# @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-js
instead 请注意,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);
};