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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/52625979/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:59:26  来源:igfitidea点击:

Confused about useBuiltIns option of @babel/preset-env (using Browserslist Integration)

javascriptwebpackbabelbabel-preset-env

提问by ARS81

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 documentationI'm using @babel/preset-envbecause it seems the recommended way (especially for beginners). Also using Browserslist integration via my .browserslistrcfile.

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

Webpack does the compilation well (babel-loaderversion 8.0.2), I have no errors but I'm confused about this useBuiltIns: "entry"option mentioned hereand how polyfillsystem is working in Babel.

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

.babelrc.js

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

.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

So my questions are:

所以我的问题是:

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

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

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

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

3) What if I omit both?

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

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

如果我做 1 和 2,我vendors.js就会成长为411 KB
如果我同时省略这两个,它只是341 KB
在生产构建之后。

I thought @babel/preset-envhandles all the rewrites and polyfills by default without any extra import/requireneeded on my side...

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

Thanks!

谢谢!

-- EDIT --

- 编辑 -

Babel's team has just updatedthe docs of @babel/polyfillbased 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 :)

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

回答by Egor Litvinchuk

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

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

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

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

TL;DR

TL; 博士

There're basically 3 options for useBuiltIns:

基本上有 3 个选项useBuiltIns

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

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

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-envto

到您的入口点,这些行将仅被所需的 polyfills 替换。当定位到 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": in this case polyfills will be added automatically when the usage of some feature is unsupported in target environment. So:

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

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

in browsers like ie11will be replaced with

在浏览器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);

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

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

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.

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



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

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



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

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

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

是对环境之前,babel v7.4core-js v3

TL;DR

TL; 博士

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

不。从babel v7.4and开始core-js v3(用于引擎盖下的@babel/preset-envpolyfilling)只有当它知道需要哪些 polyfill 并且按照推荐的顺序添加 polyfill 时才会添加。

Moreover @babel/polyfillis considered as deprecated in favor of separate core-jsand regenerator-runtimeinclusions.

此外,@babel/polyfill被视为已弃用,以支持分离core-jsregenerator-runtime包含。

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

因此,使用useBuiltInswith 选项而不是 false 应该可以解决问题。

Don't forget to add core-jsas a dependency to your project and set its version in @babel/preset-envunder corejsproperty.

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



3) What if I omit both?

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

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

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



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

创作者的页面上可以找到更详细和完整的信息core-js

Also please feel free to play with babel sandbox

也请随意玩babel 沙盒

回答by PlayMa256

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

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

Yes, according to babel docs:

是的,根据 babel 文档:

"This option enables a new plugin that replaces the statement import "@babel/polyfill" or require("@babel/polyfill") with individual requires for @babel/polyfill based on environment" - Basically, includes all needed polyfills (when you have @babel/polyfillinstalled when needed).

“此选项启用了一个新插件,该插件将语句 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"); ?

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

You do need to install @babel/polyfill, it does not come by default on babel. You have to include that on your entrypoint or add an import at the top of your entrypoint.

您确实需要安装@babel/polyfill,默认情况下它不会出现在 babel 上。您必须将其包含在您的入口点或在您的入口点顶部添加导入。

3) What if I omit both?

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

You won't have polyfills.

你不会有 polyfill。