# @babel/plugin-transform-runtime
一个插件,可以重用 Babel 注入的帮助程序代码以节省代码大小。
注意:诸如此类的实例方法
"foobar".includes("foo")仅适用于core-js@3. 如果你需要填充它们,你可以直接导入"core-js"或使用 的@babel/preset-env选项useBuiltIns。
# 安装
安装它作为开发依赖。
- npm
npm install --save-dev @babel/plugin-transform-runtime
- yarn
yarn add --dev @babel/plugin-transform-runtime
并@babel/runtime (opens new window) 作为生产依赖项(因为它用于“运行时”)。
- npm
npm install --save @babel/runtime
- yarn
yarn add @babel/runtime
转换插件通常仅用于开发,但运行时本身将取决于您部署的代码。有关更多详细信息,请参见下面的示例。
启用此插件时,不得设置
useBuiltIns中的选项。@babel/preset-env否则,此插件可能无法完全沙盒化环境。
# 为什么? (opens new window)
Babel 使用非常小的助手来实现常见功能,例如_extend. 默认情况下,这将被添加到每个需要它的文件中。这种重复有时是不必要的,尤其是当您的应用程序分布在多个文件中时。
这就是@babel/plugin-transform-runtime插件的用武之地:所有帮助程序都将引用该模块@babel/runtime以避免编译输出中的重复。运行时将编译到您的构建中。
此转换器的另一个用途是为您的代码创建一个沙盒环境。如果您直接导入core-js (opens new window) 或@babel/polyfill (opens new window) 及其提供的内置插件,例如Promise,Set和Map,这些将污染全局范围。虽然这对于应用程序或命令行工具来说可能没问题,但如果您的代码是一个您打算发布供其他人使用的库,或者如果您无法准确控制代码运行的环境,这就会成为一个问题。
转换器会将这些内置插件别名化为core-js这样您就可以无缝地使用它们而无需 polyfill。
有关其工作原理和发生的转换类型的更多信息,请参阅技术细节部分。 (opens new window)
# 用法
# 使用配置文件(推荐) (opens new window)
没有选项:
babel.config.json
{
"plugins": ["@babel/plugin-transform-runtime"]
}
使用选项(及其默认值):
babel.config.json
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"version": "7.0.0-beta.0"
}
]
]
}
该插件默认假定所有 polyfillable API 都将由用户提供。否则corejs (opens new window) 需要指定选项。
# 通过CLI (opens new window)
babel --plugins @babel/plugin-transform-runtime script.js
# 通过节点API (opens new window)
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-runtime"],
});
# 选项
# corejs (opens new window)
false, 2,3或{ version: 2 | 3, proposals: boolean }, 默认为false.
例如['@babel/plugin-transform-runtime', { corejs: 3 }],
| 版本 | 变化 |
|---|---|
v7.4.0 | 支持{ proposals: boolean } |
指定一个数字将重写需要 polyfillable API 的帮助程序,以引用该(主要)版本的帮助程序core-jsinstead 请注意,corejs: 2仅支持全局变量(例如Promise)和静态属性(例如Array.from),同时corejs: 3还支持实例属性(例如[].includes)。
默认情况下,@babel/plugin-transform-runtime不填充提案。如果您正在使用corejs: 3,则可以通过启用该proposals: true选项来选择加入此功能。
此选项需要更改用于提供必要的运行时助手的依赖项:
| corejs | 选项 | 安装命令 |
|---|---|---|
false | npm install --save @babel/runtime | |
2 | npm install --save @babel/runtime-corejs2 | |
3 | npm install --save @babel/runtime-corejs3 |
# helpers (opens new window)
boolean, 默认为true.
切换是否将内联 Babel 助手(classCallCheck、extends等)替换为对moduleName.
有关详细信息,请参阅帮助程序别名 (opens new window) 。
# polyfill (opens new window)
v7 中删除了此选项。
# regenerator (opens new window)
boolean, 默认为true.
切换生成器函数是否转换为使用不污染全局范围的再生器运行时。
有关详细信息,请参阅再生器别名 (opens new window) 。
# useBuiltIns (opens new window)
v7 中删除了此选项。
# useESModules (opens new window)
⚠️ 此选项已被弃用:从 version 开始
7.13.0,@babel/runtime使用package.json选项"exports"自动在 CJS 和 ESM 助手之间进行选择。
boolean, 默认为false.
| 版本 | 变化 |
|---|---|
v7.13.0 | 此选项已被弃用 |
启用后,转换将使用不通过运行的助手 @babel/plugin-transform-modules-commonjs。这允许在像 webpack 这样的模块系统中进行更小的构建,因为它不需要保留 commonjs 语义。
例如,这里是禁用的classCallCheck助手useESModules:
exports.__esModule = true;
exports.default = function(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
};
并且,启用它:
export default function(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
# absoluteRuntime (opens new window)
boolean或者string, 默认为false.
transform-runtime这允许用户在整个项目中广泛运行。默认情况下,直接transform-runtime从导入@babel/runtime/foo,但只有@babel/runtime在node_modules正在编译的文件中才有效。node_modules对于位于用户项目之外的嵌套、npm 链接模块或 CLI 等情况,这可能会产生问题。为了避免担心运行时模块的位置是如何解析的,这允许用户预先解析一次运行时,然后将运行时的绝对路径插入到输出代码中。
如果文件是为以后使用而编译的,那么使用绝对路径是不可取的,但在编译文件然后立即使用的上下文中,它们可能非常有用。
# version (opens new window)
默认情况下,transform-runtime 假定已@babel/runtime@7.0.0安装。如果您安装了更高版本 @babel/runtime(或它们的 corejs 对应版本@babel/runtime-corejs3)或将其列为依赖项,则 transform-runtime 可以使用更高级的功能。
例如,如果您依赖于@babel/runtime-corejs2@7.7.4您可以使用
babel.config.json
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": 2,
"version": "^7.7.4"
}
]
]
}
这导致更小的包大小。
# 技术细节 (opens new window)
转换器插件transform-runtime做了三件事:
- 当您使用生成器/异步函数时自动要求*
@babel/runtime/regenerator(可通过选项切换regenerator)。 - 如有必要,可以使用*
core-js助手而不是假设它将由用户填充(可通过选项切换corejs) - 自动删除内联 Babel 助手并使用模块*
@babel/runtime/helpers代替(可通过helpers选项切换)。
这到底意味着什么?Promise基本上,你可以使用、Set、等内置插件Symbol,也可以无缝地使用所有需要 polyfill 的 Babel 功能,没有全局污染,使其非常适合图书馆。
确保将其包含@babel/runtime为依赖项。
# 再生器别名 (opens new window)
每当您使用生成器函数或异步函数时:
function* foo() {}
生成以下内容:
"use strict";
var _marked = [foo].map(regeneratorRuntime.mark);
function foo() {
return regeneratorRuntime.wrap(
function foo$(_context) {
while (1) {
switch ((_context.prev = _context.next)) {
case 0:
case "end":
return _context.stop();
}
}
},
_marked[0],
this
);
}
这并不理想,因为它依赖于包含的再生器运行时,这会污染全局范围。
然而,使用runtime变压器,它被编译为:
"use strict";
var _regenerator = require("@babel/runtime/regenerator");
var _regenerator2 = _interopRequireDefault(_regenerator);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
var _marked = [foo].map(_regenerator2.default.mark);
function foo() {
return _regenerator2.default.wrap(
function foo$(_context) {
while (1) {
switch ((_context.prev = _context.next)) {
case 0:
case "end":
return _context.stop();
}
}
},
_marked[0],
this
);
}
这意味着您可以在不污染当前环境的情况下使用再生器运行时。
# core-js别名 (opens new window)
有时您可能想使用新的内置插件,例如Map,Set等Promise。使用这些插件的唯一方法通常是包含一个全局污染的 polyfill。
这是有corejs选项的。
该插件转换以下内容:
var sym = Symbol();
var promise = Promise.resolve();
var check = arr.includes("yeah!");
console.log(arr`Symbol.iterator`;
进入以下内容:
import _getIterator from "@babel/runtime-corejs3/core-js/get-iterator";
import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes";
import _Promise from "@babel/runtime-corejs3/core-js-stable/promise";
import _Symbol from "@babel/runtime-corejs3/core-js-stable/symbol";
var sym = _Symbol();
var promise = _Promise.resolve();
var check = _includesInstanceProperty(arr).call(arr, "yeah!");
console.log(_getIterator(arr));
这意味着您可以无缝地使用这些本机内置函数和方法,而不必担心它们来自何处。
注意:实例方法例如"foobar".includes("foo")仅在使用corejs: 3.
# 助手别名 (opens new window)
通常 Babel 会将助手放在文件的顶部来执行常见任务,以避免在当前文件中重复代码。有时这些助手会变得有点笨重,并在文件中添加不必要的重复。转换runtime器替换了对模块的所有帮助程序调用。
这意味着以下代码:
class Person {}
通常变成:
"use strict";
function _classCallCheck(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
var Person = function Person() {
_classCallCheck(this, Person);
};
然而,变压器runtime将其变成:
"use strict";
var _classCallCheck2 = require("@babel/runtime/helpers/classCallCheck");
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
var Person = function Person() {
(0, _classCallCheck3.default)(this, Person);
};