对 @babel/preset-env 的 useBuiltIns 选项感到困惑(使用 Browserslist 集成)
Confused about useBuiltIns option of @babel/preset-env (using Browserslist Integration)
我正在使用 Babel 7 和 Webpack 4 开发一个 Web 项目。我以前从未使用过 Babel,所以无法真正理解它的某些部分。基于 documentation 我正在使用 @babel/preset-env
因为它似乎是推荐的方式(特别是对于初学者)。还通过我的 .browserslistrc
文件使用 Browserslist 集成。
Webpack 编译得很好(babel-loader
版本 8.0.2
),我没有错误,但我对此感到困惑 useBuiltIns: "entry"
option mentioned here 以及如何 polyfill
系统正在 Babel 中运行。
.babelrc.js
module.exports = {
presets: [
['@babel/preset-env', {
"useBuiltIns": "entry" // do I need this?
}]
],
plugins: [
'@babel/plugin-syntax-dynamic-import'
]
};
.browserslistrc
复制自 here(认为合理,因为我的项目正在使用 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
所以我的问题是:
1) 我需要使用那个 useBuiltIns: "entry"
选项吗?
2) 我需要安装 @babel/polyfill
软件包并使用 require("@babel/polyfill");
启动我的 vendors.js
吗?
3) 如果我都省略了怎么办?
如果我做 1 和 2,我的 vendors.js
会长到 411 KB
如果我两者都省略,那就是 341 KB
在生产构建之后。
我认为 @babel/preset-env
默认处理所有重写和 polyfill,我这边不需要任何额外的 import/require
...
谢谢!
-- 编辑--
Babel 的团队刚刚 updated the docs of @babel/polyfill
基于一些 GitHub 问题(包括我的)抱怨 unclear/misleading 文档。现在很明显如何使用它。 (......之后我原来的问题似乎很愚蠢:)
1) Do I need to use that useBuiltIns: "entry" option?
是的,根据 babel 文档:
"This option enables a new plugin that replaces the statement import "@babel/polyfill" 或 require("@babel/polyfill") 以及基于环境的@babel/polyfill 的个人需求" - 基本上,包括所有需要的 polyfill (当你安装了@babel/polyfill
需要的时候)。
2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?
您确实需要安装 @babel/polyfill
,babel 默认不会安装它。您必须将其包含在您的入口点或在您的入口点顶部添加一个导入。
3) What if I omit both?
你不会有 polyfills。
1) Do I need to use that useBuiltIns: "entry" option?
是的,如果您想根据您的目标环境包含 polyfill。
TL;DR
useBuiltIns
基本上有3个选项:
"entry":使用此选项时,@babel/preset-env
将 core-js
的直接导入替换为仅导入特定模块所需的特定模块目标环境。
这意味着您需要添加
import "core-js/stable";
import "regenerator-runtime/runtime";
到您的入口点,这些行将仅由必需的 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";
"usage":在这种情况下,当目标环境不支持使用某些功能时,将自动添加 polyfill。所以:
const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
在 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);
如果目标浏览器是最新的 chrome,则不会应用任何转换。
这是我个人选择的武器,因为不需要在源代码中包含任何东西(core-js 或再生器),因为只会根据浏览器列表中设置的目标环境自动添加所需的 polyfill。
false: 这是没有自动添加 polyfill 时的默认值。
2) Do I need to install @babel/polyfill package and start my
vendors.js with require("@babel/polyfill"); ?
是 babel v7.4
和 core-js v3
之前的环境。
TL;DR
没有。从 babel v7.4
和 core-js v3
开始(用于底层填充)@babel/preset-env
将仅在知道需要哪些填充并且按照推荐的顺序添加填充。
此外,@babel/polyfill
被认为已弃用,取而代之的是单独包含 core-js
和 regenerator-runtime
。
因此,将 useBuiltIns
与 false 以外的选项一起使用应该可以解决问题。
不要忘记将 core-js
添加为项目的依赖项,并在 corejs
属性 下的 @babel/preset-env
中设置其版本。
3) What if I omit both?
正如@PlayMa256 已经回答的那样,不会有 polyfill。
可以在 core-js
creator's page
找到更详细和完整的信息
也请随意玩babel sandbox
我正在使用 Babel 7 和 Webpack 4 开发一个 Web 项目。我以前从未使用过 Babel,所以无法真正理解它的某些部分。基于 documentation 我正在使用 @babel/preset-env
因为它似乎是推荐的方式(特别是对于初学者)。还通过我的 .browserslistrc
文件使用 Browserslist 集成。
Webpack 编译得很好(babel-loader
版本 8.0.2
),我没有错误,但我对此感到困惑 useBuiltIns: "entry"
option mentioned here 以及如何 polyfill
系统正在 Babel 中运行。
.babelrc.js
module.exports = {
presets: [
['@babel/preset-env', {
"useBuiltIns": "entry" // do I need this?
}]
],
plugins: [
'@babel/plugin-syntax-dynamic-import'
]
};
.browserslistrc
复制自 here(认为合理,因为我的项目正在使用 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
所以我的问题是:
1) 我需要使用那个 useBuiltIns: "entry"
选项吗?
2) 我需要安装 @babel/polyfill
软件包并使用 require("@babel/polyfill");
启动我的 vendors.js
吗?
3) 如果我都省略了怎么办?
如果我做 1 和 2,我的 vendors.js
会长到 411 KB
如果我两者都省略,那就是 341 KB
在生产构建之后。
我认为 @babel/preset-env
默认处理所有重写和 polyfill,我这边不需要任何额外的 import/require
...
谢谢!
-- 编辑--
Babel 的团队刚刚 updated the docs of @babel/polyfill
基于一些 GitHub 问题(包括我的)抱怨 unclear/misleading 文档。现在很明显如何使用它。 (......之后我原来的问题似乎很愚蠢:)
1) Do I need to use that useBuiltIns: "entry" option?
是的,根据 babel 文档:
"This option enables a new plugin that replaces the statement import "@babel/polyfill" 或 require("@babel/polyfill") 以及基于环境的@babel/polyfill 的个人需求" - 基本上,包括所有需要的 polyfill (当你安装了@babel/polyfill
需要的时候)。
2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?
您确实需要安装 @babel/polyfill
,babel 默认不会安装它。您必须将其包含在您的入口点或在您的入口点顶部添加一个导入。
3) What if I omit both?
你不会有 polyfills。
1) Do I need to use that useBuiltIns: "entry" option?
是的,如果您想根据您的目标环境包含 polyfill。
TL;DR
useBuiltIns
基本上有3个选项:
"entry":使用此选项时,@babel/preset-env
将 core-js
的直接导入替换为仅导入特定模块所需的特定模块目标环境。
这意味着您需要添加
import "core-js/stable";
import "regenerator-runtime/runtime";
到您的入口点,这些行将仅由必需的 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";
"usage":在这种情况下,当目标环境不支持使用某些功能时,将自动添加 polyfill。所以:
const set = new Set([1, 2, 3]);
[1, 2, 3].includes(2);
在 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);
如果目标浏览器是最新的 chrome,则不会应用任何转换。
这是我个人选择的武器,因为不需要在源代码中包含任何东西(core-js 或再生器),因为只会根据浏览器列表中设置的目标环境自动添加所需的 polyfill。
false: 这是没有自动添加 polyfill 时的默认值。
2) Do I need to install @babel/polyfill package and start my vendors.js with require("@babel/polyfill"); ?
是 babel v7.4
和 core-js v3
之前的环境。
TL;DR
没有。从 babel v7.4
和 core-js v3
开始(用于底层填充)@babel/preset-env
将仅在知道需要哪些填充并且按照推荐的顺序添加填充。
此外,@babel/polyfill
被认为已弃用,取而代之的是单独包含 core-js
和 regenerator-runtime
。
因此,将 useBuiltIns
与 false 以外的选项一起使用应该可以解决问题。
不要忘记将 core-js
添加为项目的依赖项,并在 corejs
属性 下的 @babel/preset-env
中设置其版本。
3) What if I omit both?
正如@PlayMa256 已经回答的那样,不会有 polyfill。
可以在 core-js
creator's page
也请随意玩babel sandbox