# babel - preset-env和polyfill

@babel/preset-env + @babel/polyfill 可以完全实现 ES 基础语法的转译 + 新 API 的转译,让低端运行环境(浏览器和node)能够识别和运行较新的语法规范(ES6/ES7/ES8/ES99)。

# @babel/preset-env

主要完成基本语法转义。或者说语法糖:箭头函数,async

在之前,需要使用 preset-es20** 系列的 babel 预设,所以有个问题就是,每增加一个新的提案,就需要加一个。。现在只用一个就可以了。

Babel 默认只转换新的 JavaScript 句法(syntax),而不转换新的 API,比如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(比如 Object.assign)都不会转码。

  1. 安装
yarn add @babel/preset-env -D
1
  1. 添加配置
{
  "presets": [
    [
       "@babel/preset-env",
       {
         "modules": false 
       }
    ]
  ],
  "plugins": []
}
1
2
3
4
5
6
7
8
9
10
11

modules:false 对ES6的模块文件不做转化,以便使用tree shaking、sideEffects等

# @babel/polyfill

主要完成新增 API 的转义。

本质上 @babel/polyfill 是 core-js 库的别名。core-js@3 之后,需要使用 core-js + regenerator-runtime 的方式来引入了。

  1. 安装
yarn add @babel/polyfill
1
  1. 添加配置
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "entry",
        "modules": false,
        "corejs": 2
      }
    ]
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12

"corejs": 2 新版本的@babel/polyfill包含了 core-js@2 和 core-js@3 版本,所以需要声明版本,否则webpack运行时会报warning,此处暂时使用core-js@2版本

  1. 配置参数
    • modules:"amd" | "umd" | "systemjs" | "commonjs" | "cjs" | "auto" | false,默认值是 auto。
      用来转换 ES6 的模块语法。如果使用 false,将不会对文件的模块语法进行转化。
      如果要使用 webpack 中的一些新特性,比如 tree shaking 和 sideEffects,就需要设置为 false,对 ES6 的模块文件不做转化,因为这些特性只对 ES6 的模块有效。
    • useBuiltIns:"usage" | "entry" | false,默认值是 false。
      • false:需要在 js 代码第一行主动 import '@babel/polyfill',会将@babel/polyfill 整个包全部导入。
        (能覆盖到所有 API 的转译,打包后体积最大)
      • entry:需要在 js 代码第一行主动 import '@babel/polyfill',会将 browserslist 环境不支持的所有垫片都导入。
        (能够覆盖到 'hello'.includes('h') 这种句法(待验证),足够安全,代码体积不是特别大)
      • usage:项目里不用主动 import,会自动将代码里已使用到的、且 browserslist 环境不支持的垫片导入。
        (检测不到 'hello'.includes('h') 这种句法,对这类原型链上的句法问题不会做转译,书写代码需注意,体积最小)
    • targets:用来配置需要支持的的环境,不仅支持浏览器,还支持 node。如果没有配置 targets 选项,就会读取项目中的 browserslist 配置项。
    • loose:默认 false,babel 输出模式,宽松模式下,输出代码更像手写的(大概少了很多类型兼容判断)。如果 preset-env 中包含的 plugin 支持 loose 的设置,那么可以通过这个字段来做统一的设置。

使用 @babel/polyfill 的方式,会在全局挂载新 API,会污染全局命名空间,不推荐在工具库中使用这种方式。

# corejs@3

替换 @babel/polyfill 方案。

原因:

babel-loader > 8.0.0 @babel/core > 7.4.0

  1. 安装依赖
yarn add babel-loader @babel/core @babel/preset-env -D
yarn add core-js regenerator-runtime
1
2
  1. .babelrc 配置
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false,
        "useBuiltIns": "entry",
        "corejs": {
          "version": 3, 
          "proposals": true
        }
      }
    ]
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  1. 引入依赖

根据 useBuiltIns 的选择来若修改。参考上面 @babel/polyfill 配置参数的介绍。

在代码头部入口(app.js),做修改:

import 'core-js/stable'
import 'regenerator-runtime/runtime'
1
2

core-js@3废弃了 @babel/polyfill ,实现了完全无污染的API转译,但是其暂时会增加打包体积。

# @babel/plugin-transform-runtime

按需加载 API 转义。

特点是:不会污染原型链。适用于在开发第三方 js 库时使用。

  1. 安装依赖
yarn add babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
yarn add @babel/runtime-corejs3
1
2
  1. .babelrc 文件配置
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": false
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": {
          "version": 3,
          "proposals": true
        },
        "useESModules": true
      }
    ]
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  1. 配置参数
  • corejsfalse | 2 | 3 | { version: 2 | 3, proposals: boolean },默认是 false;使用 corejs:3的时候,可以设置 proposals: true 来启用 polyfill 提案。

  • version 决定了 runtime 的版本;

corejs Install command 效果
false npm install --save @babel/runtime 辅助语法转换
2 npm install --save @babel/runtime-corejs2 语法转换,无污染的 API 转译,不支持实例方法
3 npm install --save @babel/runtime-corejs3 语法转换,无污染的 API 转译,支持实例方法,增删了功能
  • helpers 默认值 true,用来开启是否使用 helper 函数来重写语法转换的函数。
  • useESModules 默认值 false,是否对文件使用 ES 的模块语法,使用 ES 的模块语法可以减少文件的大小。
  1. transform-runtime 使用 core-js@3
  • 在之前的版本中,无法模拟实例上的方法,比如数组的 includes 方法就无法被 polyfill,只能完整加载才可以。在 core-js@3 的版本中,所有的实例方法都可以被 polyfill 了。
  • 不污染原型,使用沙盒(sandbox)模式引入。
  • 支持对 ECMAScript 提案的 API 进行模拟,proposals: true 来启用 polyfill 提案。

# 总结

  • @babel/preset-env 可以完成语法的转译和 polyfill 的加载。
  • @babel/polyfill 包含 core-jsregenerator-runtime 两个模块,可以完整的模拟 ES2015+ 的环境(不包含第4阶段前的提议)。Babel v7.4.0 版本开始弃用,推荐直接使用 core-js/stableregenerator-runtime/runtime
  • @babel/plugin-transform-runtime 是一个可以重复使用 Babel 注入的帮助程序,以节省代码大小的插件。 通常仅在开发时使用,和 @babel/runtime 配合使用,@babel/runtime 需要作为生产依赖。@babel/runtime-corejs2 增加了 core-js@2regenerator-runtime 的依赖,可以引入 polyfill。

# 参考

上次更新: 12/4/2020, 2:21:49 PM