对 @babel/preset-env 的 useBuiltIns 选项感到困惑(使用 Browserslist 集成) [英] Confused about useBuiltIns option of @babel/preset-env (using Browserslist Integration)

查看:45
本文介绍了对 @babel/preset-env 的 useBuiltIns 选项感到困惑(使用 Browserslist 集成)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 Webpack 4 的 Babel 7 进行 Web 项目.我以前从未使用过 Babel,无法真正理解其中的某些部分.基于 documentation 我正在使用 @babel/preset-env 因为它似乎是推荐的方式(特别是对于初学者).还通过我的 .browserslistrc 文件使用 Browserslist 集成.

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

.babelrc.js

module.exports = {预设:[['@babel/preset-env', {"useBuiltIns": "entry"//我需要这个吗?}]],插件: ['@babel/plugin-syntax-dynamic-import']};

.browserslistrc
复制自此处(认为合理,因为我的项目使用的是 Bootstrap).

<预><代码>>= 1%最后 1 个主要版本没死铬 >= 45火狐 >= 38边 >= 12探索者 >= 10iOS >= 9Safari >= 9安卓 >= 4.4歌剧 >= 30

所以我的问题是:

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

2) 我是否需要安装 @babel/polyfill 包并用 require("@babel/polyfill"); ?

3) 如果我两者都省略会怎样?

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

我认为 @babel/preset-env 默认处理所有的重写和 polyfill,我这边不需要任何额外的 import/require...

谢谢!

-- 编辑 --

Babel 的团队刚刚更新@babel/polyfill 的文档基于一些GitHub 问题(包括我的)抱怨文档不明确/误导性.现在很明显如何使用它.(...在那之后我原来的问题似乎很愚蠢:)

解决方案

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

是的,如果您想根据您的目标环境包含 polyfill.

TL;博士

useBuiltIns 基本上有 3 个选项:

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

这意味着你需要添加

import "core-js/stable";导入再生器运行时/运行时";

到您的入口点,这些行将仅被所需的 polyfills 替换.当定位到 chrome 72 时,它会被 @babel/preset-env 转化为

import "core-js/modules/es.array.unscopables.flat";导入core-js/modules/es.array.unscoables.flat-map";导入core-js/modules/es.object.from-entries";导入core-js/modules/web.immediate";

<小时>

"usage":在这种情况下,当目标环境不支持某些功能的使用时,将自动添加 polyfill.所以:

const set = new Set([1, 2, 3]);[1, 2, 3].包括(2);

在像 ie11 这样的浏览器中将被替换为

import "core-js/modules/es.array.includes";导入core-js/modules/es.array.iterator";导入core-js/modules/es.object.to-string";导入core-js/modules/es.set";const set = new Set([1, 2, 3]);[1, 2, 3].包括(2);

如果目标浏览器是最新的 chrome,则不会应用任何转换.

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

<小时>

false:这是没有自动添加 polyfill 时的默认值.

<小时><块引用>

2) 我需要安装@babel/polyfill 包并启动我的vendor.js with require("@babel/polyfill");?

是的,适用于 babel v7.4core-js v3 之前的环境.

TL;博士

没有.从 babel v7.4core-js v3(用于引擎盖下的 polyfilling)开始 @babel/preset-env 将添加仅当它知道需要哪些 polyfill 并按照推荐的顺序使用 polyfill.

此外,@babel/polyfill 被视为已弃用,以支持单独的 core-jsregenerator-runtime 包含.

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

不要忘记将 core-js 作为依赖项添加到您的项目中,并在 corejs 下的 @babel/preset-env 中设置其版本代码>属性.

<小时><块引用>

3) 如果我两者都省略会怎样?

正如@PlayMa256 已经回答的那样,不会有 polyfill.

<小时>

更详细和完整的信息可在 core-js 创作者页面

也请随意使用 babel 沙箱

I'm working on a web project using Babel 7 with Webpack 4. I've never used Babel before and can't really understand some parts of it. Based on the documentation I'm using @babel/preset-env because it seems the recommended way (especially for beginners). Also using Browserslist integration via my .browserslistrc file.

Webpack does the compilation well (babel-loader version 8.0.2), I have no errors but I'm confused about this useBuiltIns: "entry" option mentioned here and how polyfill system is working in Babel.

.babelrc.js

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

.browserslistrc
Copied from here (thought reasonable because my project is using 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

So my questions are:

1) Do I need to use that useBuiltIns: "entry" option?

2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?

3) What if I omit both?

If I do 1 and 2, my vendors.js grows up to 411 KB
If I ommit both it's just 341 KB
after a production build.

I thought @babel/preset-env handles all the rewrites and polyfills by default without any extra import/require needed on my side...

Thanks!

-- EDIT --

Babel's team has just updated the docs of @babel/polyfill based on some GitHub issues (including mine) complaining about unclear/misleading documentation. Now it's obvious how to use it. (...and after that my original question seems stupid :)

解决方案

1) Do I need to use that useBuiltIns: "entry" option?

Yes, if you want to include polyfills based on your target environment.

TL;DR

There're basically 3 options for useBuiltIns:

"entry": when using this option, @babel/preset-env replaces direct imports of core-js to imports of only the specific modules required for a target environment.

That means you need to add

import "core-js/stable";
import "regenerator-runtime/runtime";

to your entry point and these lines will be replaced by only required polyfills. When targeting chrome 72, it will be transformed by @babel/preset-env to

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";


"usage": in this case polyfills will be added automatically when the usage of some feature is unsupported in target environment. So:

const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);

in browsers like ie11 will be replaced with

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);

In case target browser is latest chrome, no transformations will apply.

That's personally my chosen weapon as there's no need to include anything (core-js or regenerator) in source code as only required polyfills will be added automatically based on target environment set in browserlist.


false: that's the default value when no polyfills are added automatically.


2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?

Yes for environment prior to babel v7.4 and core-js v3.

TL;DR

No. Starting from babel v7.4 and core-js v3 (which is used for polyfilling under the hood) @babel/preset-env will add the polyfills only when it know which of them required and in the recommended order.

Moreover @babel/polyfill is considered as deprecated in favor of separate core-js and regenerator-runtime inclusions.

So using of useBuiltIns with options other than false should solve the issue.

Don't forget to add core-js as a dependency to your project and set its version in @babel/preset-env under corejs property.


3) What if I omit both?

As @PlayMa256 already answered, there will be no polyfills.


More detailed and whole info con be found at core-js creator's page

Also please feel free to play with babel sandbox

这篇关于对 @babel/preset-env 的 useBuiltIns 选项感到困惑(使用 Browserslist 集成)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆