@babel/preset-env相关问题

Babel 推荐使用 @babel/preset-env 套件来处理转译需求。顾名思义,preset 即“预制套件”,包含了各种可能用到的转译工具。

之前的以年份为准的 preset 已经废弃了,现在统一用这个总包。同时,babel 已经放弃开发 stage-* 包,以后的转译组件都只会放进 preset-env 包里。

@babel/preset-env默认会支持stage4的特性转换(当然是针对@babel/preset-env当前版本发布年份的stage4提案)。

 

一、重要参数

1. target

@babel/preset-env 支持一些参数,用来处理哪些 feature 要转译,哪些不要。其中比较重要的是 targets,用来指定目标环境。targets 使用 browserslist 来筛选浏环境,这样我们就不需要指定所有浏览器版本,而可以使用类似 last 2 versions 这样的描述。具体怎写,可以看文档,这里不再赘述。

如果你想知道自己配置的是否合适,可以在仓库目录下执行 npx browserslist,列出所有目标浏览器。

Babel 官方建议我们把 targets 的内容保存到 .browserslistrc文件中 或者 package.json 里增加一个browserslist节点,不然除了babel外,其他的工具,例如browserslist、post-css等无法从 babel 配置文件里读取配置。

2. useBuiltIns

接下来,我们可以配置 useBuiltIns这个属性决定是否引入 polyfill。它有三个可选值:

false,不引入,或者说,Babel 编译结果不引入。把引入的位置、引入哪些 polyfill 交给用户处理。

entry, 开发者在核心入口文件中使用 import '@babel/polyfill' 语句引入,其实并不理想,因为大部分浏览器不需要这些。

usage, 即“按需引用”。如果目标浏览器(从target中知道目标浏览器)不支持需要的 feature,那么就自动引入 polyfill,不然的话就不引用。由于目前的打包工具越发智能,随着 tree shaking 的完善,这样可以最低限度引入 polyfill。

3. corejs

core-js 目前最新版本是 3.0.1,关于 v3 和 v2 的对比,大家可以看这篇博文:https://github.com/zloirock/core-js/blob/master/docs/2019-03-19-core-js-3-babel-and-a-look-into-the-future.md。这里简单总结一下,core-js 2 封版于 1.5 年之前,所以里面只有对 1.5 年之前 feature 的 polyfill,最近 1.5 年新增的 feature 都不支持,也就存在因为新功能没有 polyfill 于是在旧浏览器里失败的风险。

所以我们应当升级到最新版,npm i core-js@3 -D 然后修改 babel 配置

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": "> 5%",
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}

此选项仅在与useBuiltIns:usage或useBuiltIns:entry一起使用时有效,并确保@babel/preset env为您的核心js版本注入正确的导入。

默认情况下,corejs只会使用stage2及更高阶段的特性:如果要使用stage-1(proposal)的polyfill,有三个不同的选项 :

当使用useBuiltIns:“entry”时,可以直接导入一个建议polyfill:import“core js/propositions/string replace all”。

使用useBuiltIns:"usage"时:“用法”有两种不同的选择:

    将shippedprovals选项设置为true。这将使polyfills和proposition转换成为可能,这些建议已经在浏览器中发布了一段时间。 

    使用corejs:{version:3,propositions:true}。这将使核心js支持的每一个提案都能实现多元化。 

备注: TC39 将提案分为以下几个阶段:

 

stage0 strawman
任何讨论、想法、改变或者还没加到提案的特性都在这个阶段。只有TC39成员可以提交。

 

stage1 proposal

 

(1)产出一个正式的提案。 (2)发现潜在的问题,例如与其他特性的关系,实现难题。 (3)提案包括详细的API描述,使用例子,以及关于相关的语义和算法。
stage2 draft

 

(1)提供一个初始的草案规范,与最终标准中包含的特性不会有太大差别。草案之后,原则上只接受增量修改。 (2)开始实验如何实现,实现形式包括polyfill, 实现引擎(提供草案执行本地支持),或者编译转换(例如babel)
stage3 candidate

 

(1)候选阶段,获得具体实现和用户的反馈。此后,只有在实现和使用过程中出现了重大问题才会修改。 (1)规范文档必须是完整的,评审人和ECMAScript的编辑要在规范上签字。 (2)至少要在一个浏览器中实现,提供polyfill或者babel插件。
stage4 finished

 

(1)已经准备就绪,该特性会出现在下个版本的ECMAScript规范之中。。 (2)需要通过有2个独立的实现并通过验收测试,以获取使用过程中的重要实践经验。

 

有关详细信息,请务必查看 current TC39 proposals 及其 process document

 

二、@babel/polyfill

@babel/polyfill 是对 core-js 的封装,引入该库时,实际上是引用了 core-js 的内容和生成器(regenerator-runtime)。 v7.4 之后,这个仓库就被废弃了,希要用户自己选择使用哪个兼容库。

换言之,以前是这么引用的:

import "@babel/polyfill";

现在需要:

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

对于绝大部分情况,使用 @babel/preset-env + useBuiltIns: 'usage' 仍然是最好的选则。

 三、babel体系化教程

这个博文讲得非常好,完整并且成体系,建议阅读

https://www.jiangruitao.com/babel/transform-runtime/

 
 
posted @ 2020-09-29 20:36  我是格鲁特  阅读(1662)  评论(0编辑  收藏  举报