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

Pon*_*cks 12 internet-explorer polyfills babeljs babel-polyfill

由于我还需要支持IE11,因此我也需要进行移植node_modules

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

presets: [
  ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],
],
Run Code Online (Sandbox Code Playgroud)

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

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

TypeError:无法分配为只读对象“#<Object>”的属性“ exports”

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

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

log*_*yth 15

Babel默认情况下假设其处理的文件是ES模块(使用importexport)。如果您在node_modules其中的东西(可能是CommonJS模块)上运行Babel ,则需要告诉Babel将其全部node_modules作为脚本进行处理,或者告诉Babel根据importand 的存在来猜测类型export。猜测最容易,因此您可以添加

sourceType: "unambiguous"
Run Code Online (Sandbox Code Playgroud)

也告诉巴贝尔不运行usage的转换core-js本身

  ignore: [
    /\/core-js/,
  ],
Run Code Online (Sandbox Code Playgroud)

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

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

{
  ignore: [
    /\/core-js/,
  ],
  sourceType: "unambiguous",
  presets: [
    ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],
  ],
}
Run Code Online (Sandbox Code Playgroud)

如果您想对此更加具体,也可以

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

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

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

  • 尝试过这个,出现了这个错误:https://i.imgur.com/slZtKT5.png 这是一个进步,因为它是一个不同的错误! (2认同)