如何在 vendors bundle 上使用 babel 的 useBuiltIns: 'usage' 选项?

How do I use babel's `useBuiltIns: 'usage'` option on the vendors bundle?

因为我还需要支持 IE11,所以我也需要转译 node_modules

这是我在 node_modules:

上使用的 babel 配置
presets: [
  ['@babel/preset-env', { modules: false, useBuiltIns: 'usage' }],
],

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

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

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

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

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

sourceType: "unambiguous"

并且还告诉 Babel 不要 运行 usagecore-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,这意味着该文件现在将在同一个文件中使用两个模块系统,这是一个大问题并会导致错误正在看。