对@ babel/preset-env的useBuiltIns选项感到困惑(使用浏览器集成)

ARS*_*S81 26 javascript babel webpack babel-preset-env

我正在使用Babel 7和Webpack 4进行一个Web项目.我之前从未使用过Babel,也无法真正理解它的某些部分.基于我正在使用的文档,@babel/preset-env因为它似乎是推荐的方式(特别是对于初学者).还通过我的.browserslistrc文件使用浏览器列表集成.

Webpack编译好(babel-loader版本8.0.2),我没有错误,但我对useBuiltIns: "entry" 这里提到的这个选项以及polyfill系统如何在Babel中工作感到困惑.

.babelrc.js

module.exports = {
  presets: [
    ['@babel/preset-env', {
      "useBuiltIns": "entry" // do I need this?
    }]
  ],
  plugins: [
    '@babel/plugin-syntax-dynamic-import'
  ]
};
Run Code Online (Sandbox Code Playgroud)

.browserslistrc
这里复制(认为​​合理,因为我的项目使用的是Bootstrap).

>= 1%
last 1 major version
not dead
Chrome >= 45
Firefox >= 38
Edge >= 12
Explorer >= 10
iOS >= 9
Safari >= 9
Android >= 4.4
Opera >= 30
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:

1)我需要使用该useBuiltIns: "entry"选项吗?

2)我需要安装@babel/polyfill包,开始我vendors.jsrequire("@babel/polyfill");

3)如果我省略两者怎么办?

如果我做1和2,我的vendors.js成长411 KB
如果我省略它只是341 KB
在生产构建之后.

我认为@babel/preset-env默认情况下处理所有重写和填充,而不需要额外的任何import/require需要...

谢谢!

- 编辑 -

巴贝尔的球队刚刚更新的文档@babel/polyfill基于一些GitHub上的问题(包括我)抱怨不清楚/误导性的文件.现在很明显如何使用它.(......之后我的原始问题似乎很愚蠢:)

Ego*_*huk 29

1)我需要使用useBuiltIns:“ entry”选项吗?

是的,如果您要根据目标环境包括polyfills。

TL; DR

基本上有3种选择useBuiltIns

“ entry”:使用此选项时,@babel/preset-env将直接导入替换core-js为仅导入目标环境所需的特定模块。

这意味着您需要添加

import "core-js/stable";
import "regenerator-runtime/runtime";
Run Code Online (Sandbox Code Playgroud)

到您的入口点,这些行将仅由必需的polyfill替换。定位chrome 72时,它将转换@babel/preset-env

import "core-js/modules/es.array.unscopables.flat";
import "core-js/modules/es.array.unscopables.flat-map";
import "core-js/modules/es.object.from-entries";
import "core-js/modules/web.immediate";
Run Code Online (Sandbox Code Playgroud)

“用法”:在这种情况下,当目标环境中不支持某些功能的使用时,将自动添加polyfills。所以:

const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
Run Code Online (Sandbox Code Playgroud)

在类似的浏览器ie11中将被替换为

import "core-js/modules/es.array.includes";
import "core-js/modules/es.array.iterator";
import "core-js/modules/es.object.to-string";
import "core-js/modules/es.set";

const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
Run Code Online (Sandbox Code Playgroud)

如果目标浏览器是最新的chrome,则不会进行任何转换。

那是我个人选择的武器,因为不需要在源代码中包含任何内容(core-js或regenerator),因为只会根据浏览器列表中设置的目标环境自动添加所需的polyfill。


false:当没有自动添加polyfill时,这是默认值。


2)我是否需要安装@ babel / polyfill软件包并使用require(“ @ babel / polyfill”)启动我的vendor.js;?

babel v7.4和之前的环境中是core-js v3

TL; DR

不会。仅从开始babel v7.4core-js v3(用于引擎盖下的填充​​)开始@babel/preset-env,才知道该填充需要并按建议的顺序添加。

此外@babel/polyfill,不赞成使用分离core-jsregenerator-runtime包含。

因此,将useBuiltInsfalse与false以外的选项一起使用应该可以解决此问题。

不要忘了添加core-js为项目的依赖项,并@babel/preset-envcorejs属性下设置其版本。


3)如果我都省略了该怎么办?

由于@ PlayMa256已经回答,因此将没有polyfills。


有关详细信息和完整信息,请参见core-js 创作者页面

还请随时使用Babel沙箱

  • 不,您只需要向依赖项添加`core-js` (2认同)
  • 好答案。Babel 文档说:“当使用使用或输入选项时,@babel/preset-env 将添加对 core-js 模块的直接引用作为裸导入(或需要)。这意味着 core-js 将相对于文件本身并且需要可访问。” 如果没有上下文或示例,很难理解。 (2认同)

Pla*_*256 14

1)我需要使用useBuiltIns:“ entry”选项吗?

是的,根据babel文档:

“此选项将启用一个新插件,该插件将基于环境对@ babel / polyfill的个别需求替换声明import“ @ babel / polyfill”或require(“ @ babel / polyfill”)”-基本上,包括所有需要的polyfill(当您@babel/polyfill在需要时已安装)。

2)我是否需要安装@ babel / polyfill软件包并使用require(“ @ babel / polyfill”)启动我的vendor.js;?

您需要安装@babel/polyfill,babel上默认没有安装它。您必须将其包括在入口点上,或在入口点的顶部添加导入。

3)如果我都省略了该怎么办?

您将不会有polyfill。

  • 围绕这个主题的语言非常令人困惑,最初似乎是自相矛盾的……目前还不清楚这意味着在入口点顶部以及 useBuiltIns: ' 时导入“@babel/polyfill”语句是必要的。使用“entry”时,此语句会自动替换,以便您在构建时导入所需的各个填充内容 (2认同)