如何在供应商捆绑包上使用babel的`useBuiltIns:'usage'`选项?

时间:2018-09-19 13:51:05

标签: internet-explorer babeljs polyfills babel-polyfill

由于我还需要支持IE11,因此我还需要转换node_modules

这是我在node_modules上使用的babel配置:

presets: [
  ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],
],

我使用useBuiltIns选项是因为它给出了错误Symbol is not defined,需要使用polyfill。

但是,此配置在编译时中断,可能是因为它在代码中注入了一些imports,这是错误消息:

TypeError: Cannot assign to read only property 'exports' of object '#<Object>'

基本上,它不喜欢module.exports。那么如何在供应商捆绑包中使用useBuiltIns

目前,我始终要求在index.html中使用babel polyfill来解决,但这并不理想。

1 个答案:

答案 0 :(得分:7)

Babel默认情况下假定其处理的文件是ES模块(使用importexport)。如果您正在node_modules中的东西(可能是CommonJS模块)上运行Babel,则需要告诉Babel将所有node_modules作为脚本进行处理,或者告诉Babel根据importexport的存在。猜测是最简单的,因此您可以添加

sourceType: "unambiguous"

,并告诉Babel不要使用{p>本身对usage进行core-js转换

  ignore: [
    /\/core-js/,
  ],

因为否则usage转换实际上会将对core-js的引用插入到自身中,从而导致依赖性循环。

因此,在您的顶级Babel配置中,例如

{
  ignore: [
    /\/core-js/,
  ],
  sourceType: "unambiguous",
  presets: [
    ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],
  ],
}

如果您想对此做更多具体说明,也可以这样做

{
  ignore: [
    /\/core-js/,
  ],
  presets: [
    ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],
  ],
  overrides: [{
    test: "./node_modules",
    sourceType: "unambiguous",
  }],
}

仅为node_modules中的文件设置标志,但是这样做可能不会带来太多好处。

关于为什么可以解决此错误,问题是,如果Babel认为某物是ES模块,它将插入import语句。如果将import语句插入也使用module.exports之类的CommonJS的文件,则意味着该文件现在将在同一文件中同时使用两个模块系统,这是一个大问题,并会导致错误正在看到。