Babel не переносит импортированные node_modules в ES5 - включает синтаксис ES2015 - PullRequest
0 голосов
/ 05 ноября 2018

Мой конфиг babel + webpack работает нормально, но полученный пакет не работает в IE11, поскольку он содержит const объявлений. Я думал, что с предустановкой es2015 было достаточно, чтобы это исправить? Запуск $(npm bin)/babel test/some-es2015.js производит строгий код ES5.1, поэтому Babel, похоже, работает, но фактический код, который работает в IE11, находится в модулях, импортированных из node_modules.

При подборе значения 'const ' в моем результирующем пакете я получаю некоторые строки, подобные этой (оценка происходит из-за сопоставления источника eval, кстати):

eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nconst validator = __webpack_require__(/*! validator */ \"./node_modules/tcomb-additional-types/node_modules/validator/index.js\");\nconst t = __webpack_require__(/*! tcomb */ \"./node_modules/tcomb/index.js\");\nconst IP = t.refinement(t.String, validator.isIP);\nexports.IP = IP;\nexports.default = IP;\n//# sourceMappingURL=ip.js.map\n\n//# sourceURL=webpack:///./node_modules/tcomb-additional-types/lib/string/ip.js?");

Важная часть, на которую следует обратить внимание, это такие вещи, как const validator =. Это не синтаксис ES5.1. Мой собственный код, кажется, был перенесен на ES5 просто отлично. Я могу видеть этот файл в /node_modules/tcomb-additional-types/lib/string/ip.js, где они используют const, так что это не добавление Babel const s, а источник, содержащий их. Большинство других пакетов - ES5.

До сих пор я обнаружил, что большинство const с material-ui и tcomb-additional-types.

Babel .babelrc:

{
    "compact": false,
    "presets": [
        "es2015",
        "es2017"
    ],
    "plugins": [
        ["transform-runtime", {
            "polyfill": false,
            "regenerator": true
        }],
        "transform-class-properties",
        "transform-react-jsx",
        "transform-object-rest-spread"
    ]
}

Конфигурация веб-пакета:

const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');

/** @returns {String} an absolute path */
function toRoot(rootRelativeDir) {
  return path.resolve(__dirname, '..', rootRelativeDir);
}

module.exports = {
  entry: ['./src/app.js', './styles/flex.less'].map(toRoot),
  output: {
    filename: 'bundle.js',
    path: toRoot('.webpack/dist')
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    alias: {}
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              /* General options are read using .babelrc - only webpack loader specific here */
              cacheDirectory: toRoot('.webpack/babel_cache')
            }
          }
        ]
      }
    ]
  },
  plugins: [new CopyWebpackPlugin([toRoot('public')])]
};

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Моя основная проблема заключалась в том, что некоторые пакеты Node не были написаны с использованием синтаксиса ES5, и преобразования Бабеля по какой-то причине не преобразовывали их. Это нормальная проблема

Найти почему это произошло довольно легко (ответ @ Vincent помог); У меня в конфиге было exclude: /node_modules/. Конечно, удаление этого могло бы «исправить» проблему, но это привело бы к новым проблемам, поскольку exclude существует по причине, поскольку вы не хотите, чтобы Babel обрабатывал каждый файл в нем.

Итак, что вы хотите, это: выборочная фильтрация, позволяющая некоторые модули .

Попытка создать регулярное выражение, которое разрешит список пакетов в node_modules, но ограничит остальное, это громоздко и подвержено ошибкам. К счастью, документы Webpack описывают, что правила условий, одним из которых является exclude, могут быть

  • Строка: для соответствия ввод должен начинаться с предоставленной строки. И. е. абсолютный путь к каталогу или абсолютный путь к файлу.
  • RegExp: проверяется на входе.
  • Функция: она вызывается с помощью ввода и должна возвращать истинное значение, чтобы соответствовать.
  • Массив Условий: должно соответствовать хотя бы одно из Условий.
  • Объект: все свойства должны совпадать. Каждое свойство имеет определенное поведение.

Создать такую ​​функцию просто! Поэтому вместо exclude: /node_modules я изменил его на exclude: excludeCondition, где excludeCondition - следующая функция:

function excludeCondition(path){

  const nonEs5SyntaxPackages = [
    'material-ui',
    'tcomb-additional-types'
  ]

  // DO transpile these packages
  if (nonEs5SyntaxPackages.some( pkg => path.match(pkg))) {
    return false;
  }

  // Ignore all other modules that are in node_modules
  if (path.match(toRoot("node_modules"))) { return true; }

  else return false;
}

Это устранило мою проблему, так как существует лишь небольшое количество пакетов, использующих синтаксис ES2015, поэтому их добавление в белый список является управляемым.

0 голосов
/ 05 ноября 2018

Та же проблема случилась и со мной. Некоторые модули узлов не обеспечивают поддержку браузера и целевые версии узлов, которые используют более новый синтаксис ES.

Я наткнулся на этот удобный пакет, который передает код узловых модулей:

https://www.npmjs.com/package/babel-engine-plugin

Это решило мою проблему с поддержкой IE11, надеюсь, это поможет

...