21

由于我还需要支持 IE11,所以我还需要转译node_modules.

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

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

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

然而,这个配置在编译时中断,据说是因为它imports在代码中注入了一些,这里是错误:

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

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

现在我通过总是需要 babel polyfill 来解决index.html,但这并不理想。

4

1 回答 1

31

Babel 默认假定它处理的文件是 ES 模块(使用importexport)。如果你在node_modules其中的东西(可能是 CommonJS 模块)上运行 Babel,你需要告诉 Babel 将所有内容node_modules作为脚本处理,或者告诉 Babel 根据importand的存在来猜测类型export。猜测是最简单的,所以你可以添加

sourceType: "unambiguous"

并告诉 Babel 不要对自身运行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语句插入到一个也使用 CommonJS 之类的文件的文件中module.exports,这意味着该文件现在将在同一个文件中使用两个模块系统,这是一个大问题并导致您看到的错误。

于 2018-09-20T00:09:34.263 回答