Skip to content

@babel/preset-env、@babel/plugin-transform-runtime、@babel/runtime、core-js #3

@wangyingjun

Description

@wangyingjun

首先介绍@babel/preset-env

它的作用是把最新的javascript的语法转换成当前环境可使用的js语法,看下面这个例子:
源代码

const r = new Promise();

console.log('abc'.includes)

配置babel

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

输出如下:

"use strict";

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

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

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

var r = new Promise();
console.log('abc'.includes);

输出结果中,插入了对 core-js 的引用,所以在项目中需要安装 core-js,引入过程中,其实是插入了全局变量,同时会污染环境,如果不想要插入全局变量,则需要@babel/plugin-transform-runtime

@babel/plugin-transform-runtime@babel/runtime

再使用 @babel/plugin-transform-runtime 时 需要安装 npm i --save @babel/runtime ,看下面这个例子:

源代码

class Animal {}

不使用 @babel/plugin-transform-runtime 时,输出结果如下:

"use strict";

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

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

发现生成代码中,插入了 _classCallCheck这个辅助函数(可以称为babel运行时环境提供的辅助函数),多个地方使用就会在每一处插入相同的辅助函数,所以需要@babel/plugin-transform-runtime,输出结果如下:

"use strict";

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

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

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

结果中通过引用@babel/runtime/xxxxxx中的函数,来避免重复生成,这就时为什么需要安装@babel/runtime的原因

看如下例子:
源码:

const r = new Promise();

console.log('abc'.includes)

class Animal {}

babel配置如下:

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

输出结果如下:

"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.string.includes.js");

var r = new Promise();
console.log('abc'.includes);

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

全局变量并没有解决,需要更改babel配置如下

{
    "presets": [
        ["@babel/preset-env", {
            "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 r = new _promise["default"]();
console.log((0, _includes["default"])('abc'));

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

可以看出 引用了@babel/runtime-corejs3这个库,所以解决全局变量需要安装@babel/runtime-corejs3这个库,可以移除core-js

@babel/runtime-corejs2@babel/runtime-corejs3

@babel/runtime-corejs2并不包含对象的属性方法 比如 String.prototype.includes,所有并不能解决全局导入污染作用域的问题,而@babel/runtime-corejs3包含了属性方法,所以可以避免污染全局作用域

总结

在业务中,并清除3方包是否兼容当前环境,推荐全局引入,污染作用域,如下babel配置

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

然而在开发包的时候,为避免包污染其他环境,应通过 @babel/@babel/plugin-transform-runtime@babel/runtime-corejs3,推荐如下配置:

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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions