【问题标题】:Confused about useBuiltIns option of @babel/preset-env (using Browserslist Integration)对 @babel/preset-env 的 useBuiltIns 选项感到困惑(使用 Browserslist 集成)
【发布时间】:2018-10-03 11:23:28
【问题描述】:

我正在开发一个使用 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 默认情况下会处理所有重写和填充,而我这边不需要任何额外的import/require...

谢谢!

-- 编辑--

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

【问题讨论】:

    标签: javascript webpack babeljs babel-preset-env


    【解决方案1】:

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

    是的,如果您想根据您的目标环境包含 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":在这种情况下,当目标环境不支持某些功能的使用时,会自动添加 polyfills。所以:

    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 或 regenerator),因为只会根据浏览器列表中设置的目标环境自动添加所需的 polyfill。


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


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

    对于babel v7.4core-js v3 之前的环境是。

    TL;DR

    没有。从 babel v7.4core-js v3 开始(用于底层填充)@babel/preset-env 将仅在知道需要哪些 polyfill 并按照推荐的顺序添加它们。

    此外,@babel/polyfill 被视为已弃用,取而代之的是单独的 core-jsregenerator-runtime 包含。

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

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


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

    @PlayMa256 已经回答了,不会有 polyfills。


    更详细和完整的信息可以在core-jscreator's page找到

    也请随时与babel sandbox一起玩

    【讨论】:

    • 当使用“用法”时我必须使用import "core-js/stable"; import "regenerator-runtime/runtime"; ?
    • 不,你只需要在依赖项中添加core-js
    • 好答案。 Babel 文档说:“当使用使用或入口选项时,@babel/preset-env 将添加对 core-js 模块的直接引用作为裸导入(或要求)。这意味着 core-js 将相对于文件本身并且需要可访问。”没有上下文或例子很难理解。
    【解决方案2】:

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

    是的,根据 babel 文档:

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

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

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

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

    你不会有 polyfills。

    【讨论】:

    • 谢谢,现在我明白了。同时,我阅读了babel-polyfill 的文档,这部分非常有用:babeljs.io/docs/en/babel-polyfill#size
    • 当前文档:babeljs.io/docs/en/…
    • 围绕这个主题的语言非常混乱,最初似乎自相矛盾......目前尚不清楚这意味着 import "@babel/polyfill" 声明在顶部是必要的您的入口点,当使用 useBuiltIns: 'entry' 时,此语句会自动替换,以便您在构建时导入单个所需的 polyfill
    • 请注意,如果您将useBuiltIns 设置为“usage”,则不必再将@babel/polyfill 添加到条目数组中。 babeljs.io/docs/en/…
    猜你喜欢
    • 2019-10-08
    • 2019-07-26
    • 2013-01-17
    • 2014-07-06
    • 2021-11-26
    • 2019-09-07
    • 1970-01-01
    • 2018-04-27
    • 2018-09-10
    相关资源
    最近更新 更多