Babel 7 插件配置指南

@babel/preset-env

@babel/preset-env 插件转译 stage-3 阶段以下的语法,可以配合 .browserslistrc 进行配置。

@babel/polyfill

@babel/preset-env 可以转译语法,但不能解决代码里的使用到的 API 如:Object.assign 、Array.incldues 等,这时需要使用 @babel/polyfill 来做兼容性处理。

@babel@7.4.0 开启已经弃用 @babel/polyfill,改用 import "core-js/stable" 替代,如果代码内部使用到了 Generator/async 还需要再引入 regenerator-runtime/runtime

垫片方式选择

  • entry:根据.browserslistrc 配置,注入当前环境 API(Firefox 58)

    1
    2
    3
    // 转译前
    import "core-js/stable"
    const obj = Promise.resolve();
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    // 转译后
    "use strict";

    require("core-js/modules/es.symbol.description.js");
    require("core-js/modules/es.symbol.match-all.js");
    require("core-js/modules/es.error.cause.js");
    require("core-js/modules/es.aggregate-error.js");
    require("core-js/modules/es.aggregate-error.cause.js");
    require("core-js/modules/es.array.at.js");
    require("core-js/modules/es.array.find-last.js");
    require("core-js/modules/es.array.find-last-index.js");
    require("core-js/modules/es.array.flat.js");
    require("core-js/modules/es.array.flat-map.js");
    require("core-js/modules/es.array.includes.js");
    require("core-js/modules/es.array.iterator.js");
    require("core-js/modules/es.array.to-reversed.js");
    require("core-js/modules/es.array.to-sorted.js");
    require("core-js/modules/es.array.to-spliced.js");
    require("core-js/modules/es.array.unscopables.flat.js");
    require("core-js/modules/es.array.unscopables.flat-map.js");
    require("core-js/modules/es.array.with.js");
    require("core-js/modules/es.global-this.js");
    require("core-js/modules/es.json.stringify.js");
    require("core-js/modules/es.number.to-exponential.js");
    require("core-js/modules/es.object.from-entries.js");
    require("core-js/modules/es.object.has-own.js");
    require("core-js/modules/es.promise.js");
    require("core-js/modules/es.promise.all-settled.js");
    require("core-js/modules/es.promise.any.js");
    require("core-js/modules/es.promise.finally.js");
    require("core-js/modules/es.reflect.to-string-tag.js");
    require("core-js/modules/es.regexp.constructor.js");
    require("core-js/modules/es.regexp.dot-all.js");
    require("core-js/modules/es.regexp.exec.js");
    require("core-js/modules/es.regexp.flags.js");
    require("core-js/modules/es.string.at-alternative.js");
    require("core-js/modules/es.string.match-all.js");
    require("core-js/modules/es.string.replace.js");
    require("core-js/modules/es.string.replace-all.js");
    require("core-js/modules/es.string.trim-end.js");
    require("core-js/modules/es.string.trim-start.js");
    require("core-js/modules/es.typed-array.at.js");
    require("core-js/modules/es.typed-array.find-last.js");
    require("core-js/modules/es.typed-array.find-last-index.js");
    require("core-js/modules/es.typed-array.sort.js");
    require("core-js/modules/es.typed-array.to-reversed.js");
    require("core-js/modules/es.typed-array.to-sorted.js");
    require("core-js/modules/es.typed-array.with.js");
    require("core-js/modules/web.dom-collections.iterator.js");
    require("core-js/modules/web.immediate.js");
    require("core-js/modules/web.queue-microtask.js");
    require("core-js/modules/web.structured-clone.js");
    require("core-js/modules/web.url-search-params.size.js");
    const obj = Promise.resolve();
  • usage: 根据.browserslistrc 配置,按需(当前代码只使用了 Promise)注入当前环境 API(Firefox 58)

    1
    2
    // 使用前
    const obj = Promise.resolve();
    1
    2
    3
    4
    // 使用后
    "use strict";
    require("core-js/modules/es.promise.js");
    const obj = Promise.resolve();
  • false 不处理垫片

core-js@2 和 core-js@3

两者没有本质的区别,core-js@3 新增了一些API,如:Array.flat 方法

@babel/runtime

babel 转译过程中会产生许多 helpers 函数,如:_createClass、_classCallCheck、_defineProperties等,如果每一个文件都包含这些辅助函数项目会产生许多冗余代码,@babel/runtime 包里面内置了许多这样的函数。

1
2
// 转译前
class Person {}
1
2
3
4
5
6
7
8
9
10
11
// 转译后
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Person = /*#__PURE__*/_createClass(function Person() {
_classCallCheck(this, Person);
});

@babel/plugin-transform-runtime

作用1:自动移除语法转换后内联的辅助函数

上面提到 @babel/runtime 里面内置了许多 helpers 函数,那具体如何使用他来提高复用性呢?@babel/plugin-transform-runtime 就是干这件事情的,很明显看到这些辅助函数在使用这个插件转译后都变成require(xxxx) 形式。这样 webpack 打包的时候会基于模块来去重。

1
2
3
4
5
6
7
8
// 使用后
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var Person = /*#__PURE__*/(0, _createClass2.default)(function Person() {
(0, _classCallCheck2.default)(this, Person);
});

作用2:防止污染全局环境

当代码里使用了 core-js 的API,自动引入 @babel/runtime-corejs3/core-js-stable/ 替代全局引入的 core-js/stable,
当代码里使用了 Generator/async 函数,自动引入 @babel/runtime/regenerator 来替代全局引入的 regenerator-runtime/runtime;