3

我正在尝试配置 babel preset-env 以针对指定的目标浏览器列表自动注入 polyfill。

文档指出,preset-env使用 形式的属性配置预设"useBuiltIns": "usage"将完全做到这一点。

(我注意到单独指定此属性会导致控制台中显示警告,但说明我应该指定要使用的 core-js 版本,所以我也添加了这个。)

因此,我babel.config.js看起来像这样:

module.exports = {
  "presets": [
    "@babel/preset-react",
    "@babel/preset-typescript",
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ],
  "plugins": ['macros'],
};

极好的!这应该是轻而易举的事!

但是,使用 webpack 重新编译后,我的应用程序现在在浏览器中死机,并显示以下控制台消息:

Uncaught TypeError: __webpack_require__(...) is not a function
at Module../node_modules/webpack/buildin/harmony-module.js (harmony-module.js:24)

我已经做了一些研究(大约只值 3 小时!),我知道这是 babel 试图转换 babel 或类似的东西的结果......我需要将一些文件添加到忽略列表中可能不会被转译或双重转译。

在我的 webpack 配置中,我放置了以下内容。(注意排除条目)。

module: {
  rules: [
    {
      test: /\.(js|jsx|ts|tsx)$/,
      exclude: [/core-js/, /regenerator-runtime/],
      use: [
        {
          loader: 'babel-loader',
          options: {
            presets: babelConfig.presets,
            cacheDirectory: babelCacheDir
          }
        },
        'eslint-loader'
      ]
    }
  ]
}

我还尝试在忽略模式上添加一些变体,但我仍然遇到致命的控制台错误。

我尝试过的另一件事是忽略node_modules文件夹,但是我有大块的代码根本没有被转译。即在 IE11 中,我收到有关 ES6 箭头函数的语法错误,这些箭头函数源自未转译的供应商脚本。

如果有人能够解释为什么__webpack_require__会以一种不受欢迎的方式被改变,我会非常感激,因为这个问题需要的确切解决方案是对研究有很大的抵抗力。

编辑:以下建议必须使babelcore-js忽略,这似乎很合理。它建议在 babel 配置文件中使用以下内容:

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

但是,这会导致出现另一个相当、看似非特定的错误:

has.js:4 Uncaught TypeError: Cannot convert undefined or null to object
    at hasOwnProperty (<anonymous>)
    at push../node_modules/core-js/internals/has.js.module.exports (has.js:4)
4

2 回答 2

2

在 下useBuiltins: "usage",Babel 需要猜测一下。ES6 与 CJS 导入样式;并且它更好地猜测与 Webpack 相同的方式。

这在Babel 文档中有非常简短的介绍。正如其他地方所解释的那样,实现这一点的最简单方法是sourceType: "unambiguous"在传递给的选项中进行设置@babel/preset-env

尽我所能回答“为什么”的问题:

  • useBuiltIns: "usage"意味着 Babel 将着手查找和填充一些可能在某些浏览器中不存在的方法调用(和其他 JS 结构)。这需要在 Babel 重写时将一些修复代码注入到您的模块中。
  • 很多这些修复包括导入部分core-js以确保 Array 等原型被填充到满意;例如,Babel 可能会插入诸如
    导入“core-js/modules/es.array.map.js”;
  • 不幸的是,在 JavaScript中导入内容的方法不止一种。Babel 必须猜测哪个最适合下游工具链。如果 Babel 位于 Webpack 的上游,这是一个非常典型的场景(您的问题就是这种情况),它可能会通过在使用or的代码中添加语句来破坏Webpack 中的一些自动检测逻辑importrequire()module.exports
  • 不幸的是,Webpack 不会直接抛出解析错误,而是会尝试处理这些受污染的代码;导致各种难以理解的编译时或运行时症状(这里是另一个例子)。

直到 Babel 和 Webpack 同意某种约定或秘密握手以解决 ES6 / CJS 阻抗不匹配问题,作为模块作者,您必须以某种方式确保 Babel 和 Webpack 对哪个源文件有相同的想法使用哪种格式;或者只是为您的“旧”(CJS)代码禁用 Babel,无论是在node_modules/其他地方还是其他地方。

于 2021-07-12T18:10:25.040 回答
0

排除/webpack/对我有用!

于 2020-05-10T21:48:48.400 回答