babel>=7.4结合transform-runtime插件各配置验证

976 阅读3分钟

先说结论

  1. 在preset-env中配置useBuiltIns:usage,会按需引入相关的polyfill,但是不会提取公共的help函数,以及会污染全局对象和对象原型
  2. 在第一点的基础上,新增@babel/plugin-transform-runtime但是core-js指定为false,结果相对于第一点,不同的是这次提取了公共的help函数。
  3. 在第二点的基础上,runtime插件指定core-js版本3,会导致useBuiltIns:usage配置无效。并且也会按需引入相关polyfill,提取公共help函数,但是不会污染全局对象和对象原型。这种配置适合打包npm库。
  4. 实际业务需求开发中,采用第二点方案较为合适,但是这种混用的方式,在github上有相关issue(github.com/babel/babel…),并且bable团队成员不推荐这种混用的方式。但是我验证过没发现什么问题,并且vue-cli脚手架也用到了这种配置。

验证过程

源文件

const a = 1
const b = () => {}
p = new Promise()
class Test {}
const list = [1, 2]
// 无法静态分析的类型
const list2 = (function a() {
  return [2]
})()
list.includes(1)
list2.includes(2)

配置 useBuiltIns:false

{
    "presets": [
        [ "@babel/preset-env", {
            "targets": {},
            "useBuiltIns": false,
            "corejs": false
        }]
    ]
}

结果:仅仅转换了语法

"use strict";

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var a = 1;

var b = function b() {};

p = new Promise();

var Test = function Test() {
  _classCallCheck(this, Test);
};

var list = [1, 2];

var list2 = function a() {
  return [2];
}();

list.includes(1);
list2.includes(2);

配置 useBuiltIns:usage

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

结果 语法转换并且按需引入了polyfill 但是污染全局对象和对象原型 并且无法提取公共的help函数 比如_classCallCheck

"use strict";

require("core-js/modules/es.object.to-string.js");

require("core-js/modules/es.promise.js");

require("core-js/modules/es.array.includes.js");

require("core-js/modules/es.string.includes.js");

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var a = 1;

var b = function b() {};

p = new Promise();

var Test = function Test() {
  _classCallCheck(this, Test);
};

var list = [1, 2];

var list2 = function a() {
  return [2];
}();

list.includes(1);
list2.includes(2);

配置 和上面不同的是 去除了preset-env中的useBuiltIns 新增了runtime插件

{
    "presets": [
        [ "@babel/preset-env", {
            "targets": {}
           
        }]
    ],
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            "corejs": false 
        }]
    ]
}

结果 仅仅转换了语法和提取了公共的help函数 比如_classCallCheck

"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

var a = 1;

var b = function b() {};

p = new Promise();

var Test = function Test() {
  (0, _classCallCheck2["default"])(this, Test);
};

var list = [1, 2];

var list2 = function a() {
  return [2];
}();

list.includes(1);
list2.includes(2);

配置 上面的基础上加上useBuiltIns:usage

{
    "presets": [
        [ "@babel/preset-env", {
            "targets": {},
            "useBuiltIns": "usage",
            "corejs": 3
           
        }]
    ],
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            // "corejs": 3 
        }]
    ]
}

结果 和仅配置useBuiltIns:usage相比 不同的是这次提取了公共的help函数

"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

require("core-js/modules/es.object.to-string.js");

require("core-js/modules/es.promise.js");

require("core-js/modules/es.array.includes.js");

require("core-js/modules/es.string.includes.js");

var a = 1;

var b = function b() {};

p = new Promise();

var Test = function Test() {
  (0, _classCallCheck2["default"])(this, Test);
};

var list = [1, 2];

var list2 = function a() {
  return [2];
}();

list.includes(1);
list2.includes(2);

配置 transform-runtime指定core-js版本3

{
    "presets": [
        [ "@babel/preset-env", {
            "targets": {}
           
        }]
    ],
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            "corejs": 3 
        }]
    ]
}

结果 语法转换+按需引入的polyfill 但是没有污染全局对象和对象原型 并且提取了公共的help函数 比如_classCallCheck

"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));

var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));

var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));

var a = 1;

var b = function b() {};

p = new _promise["default"]();

var Test = function Test() {
  (0, _classCallCheck2["default"])(this, Test);
};

var list = [1, 2];

var list2 = function a() {
  return [2];
}();

(0, _includes["default"])(list).call(list, 1);
(0, _includes["default"])(list2).call(list2, 2);

配置 如果在上面的情况加上 useBuiltIns 和上面结果一样 说明此时useBuiltIns配置不生效

{
    "presets": [
        [ "@babel/preset-env", {
            "targets": {},
            "useBuiltIns": "usage",
             "corejs": 3
           
        }]
    ],
    "plugins": [
        ["@babel/plugin-transform-runtime", {
            "corejs": 3 
        }]
    ]
}
"use strict";

var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));

var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));

var _includes = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/includes"));

var a = 1;

var b = function b() {};

p = new _promise["default"]();

var Test = function Test() {
  (0, _classCallCheck2["default"])(this, Test);
};

var list = [1, 2];

var list2 = function a() {
  return [2];
}();

(0, _includes["default"])(list).call(list, 1);
(0, _includes["default"])(list2).call(list2, 2);