Skip to main content

@babel/plugin-transform-runtime

一个插件,可以重用 Babel 的注入帮助代码以节省代码大小。

¥A plugin that enables the re-use of Babel's injected helper code to save on codesize.

注意

"foobar".includes("foo") 等实例方法仅适用于 core-js@3。如果需要 polyfill,可以直接导入 "core-js" 或者使用 @babel/preset-envuseBuiltIns 选项。

¥Instance methods such as "foobar".includes("foo") will only work with core-js@3. If you need to polyfill them, you can directly import "core-js" or use @babel/preset-env's useBuiltIns option.

安装

¥Installation

将其安装为开发依赖。

¥Install it as development dependency.

npm install --save-dev @babel/plugin-transform-runtime

@babel/runtime 作为生产依赖(因为它用于 "runtime")。

¥and @babel/runtime as a production dependency (since it's for the "runtime").

npm install --save @babel/runtime

转换插件通常仅在开发中使用,但运行时本身将取决于你部署的代码。有关详细信息,请参阅下面的示例。

¥The transformation plugin is typically used only in development, but the runtime itself will be depended on by your deployed code. See the examples below for more details.

危险

启用此插件后,@babel/preset-env 中的 useBuiltIns 选项不得设置。否则,此插件可能无法完全沙盒化环境。

¥When this plugin is enabled, the useBuiltIns option in @babel/preset-env must not be set. Otherwise, this plugin may not able to completely sandbox the environment.

为什么?

¥Why?

Babel 对 _extend 等常见功能使用非常小的辅助程序。默认情况下,这将添加到需要它的每个文件中。这种重复有时是不必要的,尤其是当你的应用分布在多个文件中时。

¥Babel uses very small helpers for common functions such as _extend. By default this will be added to every file that requires it. This duplication is sometimes unnecessary, especially when your application is spread out over multiple files.

这是 @babel/plugin-transform-runtime 插件的用武之地:所有的助手都将引用模块 @babel/runtime 以避免编译输出中的重复。运行时将编译到你的构建中。

¥This is where the @babel/plugin-transform-runtime plugin comes in: all of the helpers will reference the module @babel/runtime to avoid duplication across your compiled output. The runtime will be compiled into your build.

这个转换器的另一个目的是为你的代码创建一个沙盒环境。如果直接导入 core-js@babel/polyfill 以及它提供的 PromiseSetMap 等内置函数,会污染全局作用域。虽然这对于应用或命令行工具来说可能没问题,但如果你的代码是一个你打算发布以供其他人使用的库,或者你无法完全控制代码运行的环境,那么它就会成为一个问题。

¥Another purpose of this transformer is to create a sandboxed environment for your code. If you directly import core-js or @babel/polyfill and the built-ins it provides such as Promise, Set and Map, those will pollute the global scope. While this might be ok for an app or a command line tool, it becomes a problem if your code is a library which you intend to publish for others to use or if you can't exactly control the environment in which your code will run.

转换器会将这些内置插件别名为 core-js,因此你可以无缝使用它们,而无需使用 polyfill。

¥The transformer will alias these built-ins to core-js so you can use them seamlessly without having to require the polyfill.

有关其工作原理以及发生的转换类型的更多信息,请参阅 技术细节 部分。

¥See the technical details section for more information on how this works and the types of transformations that occur.

用法

¥Usage

¥With a configuration file (Recommended)

没有选项:

¥Without options:

babel.config.json
{
"plugins": ["@babel/plugin-transform-runtime"]
}

使用选项(及其默认值):

¥With options (and their defaults):

babel.config.json
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"version": "7.0.0-beta.0"
}
]
]
}

该插件默认假设所有可填充的 API 都将由用户提供。否则需要指定 corejs 选项。

¥The plugin defaults to assuming that all polyfillable APIs will be provided by the user. Otherwise the corejs option needs to be specified.

通过 CLI

¥Via CLI

Shell
babel --plugins @babel/plugin-transform-runtime script.js

通过 Node API

¥Via Node API

JavaScript
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-runtime"],
});

选项

¥Options

absoluteRuntime

booleanstring,默认为 false

¥boolean or string, defaults to false.

这允许用户在整个项目中广泛运行 transform-runtime。默认情况下,transform-runtime 直接从 @babel/runtime/foo 导入,但仅当 @babel/runtime 在正在编译的文件的 node_modules 中时才有效。这对于嵌套的 node_modules、npm 链接的模块或驻留在用户项目之外的 CLI 等情况可能会有问题。为了避免担心如何解析运行时模块的位置,这允许用户预先解析一次运行时,然后将运行时的绝对路径插入到输出代码中。

¥This allows users to run transform-runtime broadly across a whole project. By default, transform-runtime imports from @babel/runtime/foo directly, but that only works if @babel/runtime is in the node_modules of the file that is being compiled. This can be problematic for nested node_modules, npm-linked modules, or CLIs that reside outside the user's project, among other cases. To avoid worrying about how the runtime module's location is resolved, this allows users to resolve the runtime once up front, and then insert absolute paths to the runtime into the output code.

如果文件被编译以供以后使用,则使用绝对路径是不可取的,但在文件被编译然后立即使用的上下文中,它们可能会很有帮助。

¥Using absolute paths is not desirable if files are compiled for use at a later time, but in contexts where a file is compiled and then immediately consumed, they can be quite helpful.

提示

你可以阅读有关配置插件选项 此处 的更多信息

¥You can read more about configuring plugin options here

corejs

false23{ version: 2 | 3, proposals: boolean },默认为 false

¥false, 2, 3 or { version: 2 | 3, proposals: boolean }, defaults to false.

例如 ['@babel/plugin-transform-runtime', { corejs: 3 }],

¥e.g. ['@babel/plugin-transform-runtime', { corejs: 3 }],

History
版本变化
v7.4.0支持 { proposals: boolean }

指定一个数字将重写需要可填充 API 的助手来引用来自 core-js 的(主要)版本的助手 请注意,corejs: 2 仅支持全局变量(例如 Promise)和静态属性(例如 Array.from),而 corejs: 3 还支持实例属性(例如 [].includes)。

¥Specifying a number will rewrite the helpers that need polyfillable APIs to reference helpers from that (major) version of core-js instead Please note that corejs: 2 only supports global variables (e.g. Promise) and static properties (e.g. Array.from), while corejs: 3 also supports instance properties (e.g. [].includes).

默认情况下,@babel/plugin-transform-runtime 不会 polyfill 提案。如果你使用的是 corejs: 3,则可以通过启用 proposals: true 选项来选择加入。

¥By default, @babel/plugin-transform-runtime doesn't polyfill proposals. If you are using corejs: 3, you can opt into this by enabling using the proposals: true option.

此选项需要更改用于提供必要运行时辅助程序的依赖:

¥This option requires changing the dependency used to provide the necessary runtime helpers:

corejs 选项安装命令
falsenpm install --save @babel/runtime
2npm install --save @babel/runtime-corejs2
3npm install --save @babel/runtime-corejs3
提醒

Babel 8 中将删除 corejs 选项。要注入 polyfills,可以直接使用 babel-plugin-polyfill-corejs3babel-plugin-polyfill-corejs2

¥The corejs option will be removed in Babel 8. To inject polyfills, you can use babel-plugin-polyfill-corejs3 or babel-plugin-polyfill-corejs2 directly.

helpers

boolean,默认为 true

¥boolean, defaults to true.

切换内联 Babel 助手(classCallCheckextends 等)是否替换为对 @babel/runtime(或等效包)的调用。

¥Toggles whether or not inlined Babel helpers (classCallCheck, extends, etc.) are replaced with calls to @babel/runtime (or equivalent package).

有关详细信息,请参阅 助手别名

¥For more information, see Helper aliasing.

提醒

helpers 选项将在 Babel 8 中删除,因为该插件将仅用于注入助手(包括 regeneratorRuntime,它将像任何其他 Babel 助手一样处理)。

¥The helpers option will be removed in Babel 8, as this plugin will only be used to inject helpers (including regeneratorRuntime, which will be handled as any other Babel helper).

moduleName

History
版本变化
v7.24.0添加了 moduleName 选项

string,默认为 @babel/runtime

¥string, defaults to @babel/runtime.

此选项控制 @babel/plugin-transform-runtime 在注入导入时将使用哪个辅助程序包。它使用以下优先级:

¥This option controls which package of helpers @babel/plugin-transform-runtime will use when injecting imports. It uses the following priority:

  • moduleName 选项(如果指定)

    ¥moduleName option, if specified

  • 任何 babel-plugin-polyfill-* 插件建议的助手模块

    ¥Helpers module suggested by any babel-plugin-polyfill-* plugin

    • babel-plugin-polyfill-corejs3 建议 @babel/runtime-corejs3

      ¥babel-plugin-polyfill-corejs3 suggests @babel/runtime-corejs3

    • babel-plugin-polyfill-corejs2 建议 @babel/runtime-corejs2

      ¥babel-plugin-polyfill-corejs2 suggests @babel/runtime-corejs2

  • 回退到 @babel/runtime

    ¥Fallback to @babel/runtime

请注意,指定 corejs 选项将在内部启用相应的 babel-plugin-polyfill-corejs* 插件,因此它会影响最终的模块名称。

¥Note that specifying the corejs option will internally enable the corresponding babel-plugin-polyfill-corejs* plugin, thus it has an effect on the final module name.

regenerator

boolean,默认为 true

¥boolean, defaults to true.

在旧的 Babel 版本中,此选项用于切换生成器函数是否转换为使用不会污染全局范围的再生器运行时。

¥In older Babel version, this option used to toggles whether or not generator functions were transformed to use a regenerator runtime that does not pollute the global scope.

有关详细信息,请参阅 再生器别名

¥For more information, see Regenerator aliasing.

提醒

Babel 8 中将删除 regenerator 选项,因为不再需要它了。

¥The regenerator option will be removed in Babel 8, as it will not be necessary anymore.

useESModules

boolean,默认为 false

¥boolean, defaults to false.

History
版本变化
v7.13.0此选项已被弃用

启用后,转换将使用不会通过 @babel/plugin-transform-modules-commonjs 运行的辅助程序。这允许在 webpack 等模块系统中进行更小的构建,因为它不需要保留 commonjs 语义。

¥When enabled, the transform will use helpers that do not get run through @babel/plugin-transform-modules-commonjs. This allows for smaller builds in module systems like webpack, since it doesn't need to preserve commonjs semantics.

例如,这里是禁用 useESModulesclassCallCheck 助手:

¥For example, here is the classCallCheck helper with useESModules disabled:

JavaScript
exports.__esModule = true;

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

并且,启用它:

¥And, with it enabled:

JavaScript
export default function(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
提醒

useESModules 选项已被弃用,并将在 Babel 8 中删除:从版本 7.13.0 开始,@babel/runtimepackage.json 使用 "exports" 选项自动在 CJS 和 ESM 助手之间进行选择。

¥The useESModules option has been deprecated and will be removed in Babel 8: starting from version 7.13.0, @babel/runtime's package.json uses "exports" option to automatically choose between CJS and ESM helpers.

version

默认情况下,transform-runtime 假定安装了 @babel/runtime@7.0.0。如果你安装了更高版本的 @babel/runtime(或它们的 corejs 对应版本,例如 @babel/runtime-corejs3)或作为依赖列出,则 transform-runtime 可以使用更高级的功能。

¥By default transform-runtime assumes that @babel/runtime@7.0.0 is installed. If you have later versions of @babel/runtime (or their corejs counterparts e.g. @babel/runtime-corejs3) installed or listed as a dependency, transform-runtime can use more advanced features.

例如,如果你依赖 @babel/runtime@^7.24.0,你可以使用

¥For example if you depend on @babel/runtime@^7.24.0 you can transpile your code with

babel.config.json
{
"plugins": [
["@babel/plugin-transform-runtime", {
"version": "^7.24.0"
}]
]
}

这导致更小的包大小。

¥which results in a smaller bundle size.

技术细节

¥Technical details

transform-runtime 转换器插件做了三件事:

¥The transform-runtime transformer plugin does three things:

  • 使用生成器/异步功能时自动需要 @babel/runtime/regenerator(可使用 regenerator 选项切换)。

    ¥Automatically requires @babel/runtime/regenerator when you use generators/async functions (toggleable with the regenerator option).

  • 如有必要,可以将 core-js 用于辅助程序,而不是假设它将由用户填充(可使用 corejs 选项切换)

    ¥Can use core-js for helpers if necessary instead of assuming it will be polyfilled by the user (toggleable with the corejs option)

  • 自动删除内联 Babel 助手并使用模块 @babel/runtime/helpers 代替(可使用 helpers 选项切换)。

    ¥Automatically removes the inline Babel helpers and uses the module @babel/runtime/helpers instead (toggleable with the helpers option).

这到底意味着什么?基本上,你可以使用 PromiseSetSymbol 等内置插件,也可以无缝使用所有需要 polyfill 的 Babel 特性,没有全局污染,非常适合库。

¥What does this actually mean though? Basically, you can use built-ins such as Promise, Set, Symbol, etc., as well use all the Babel features that require a polyfill seamlessly, without global pollution, making it extremely suitable for libraries.

确保将 @babel/runtime 作为依赖包含在内。

¥Make sure you include @babel/runtime as a dependency.

再生器别名

¥Regenerator aliasing

每当你使用生成器函数或异步函数时:

¥Whenever you use a generator function or async function:

JavaScript
function* foo() {}

生成以下内容:

¥the following is generated:

JavaScript
"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
);
}

这并不理想,因为它依赖于包含的再生器运行时,这会污染全局作用域。

¥This isn't ideal since it relies on the regenerator runtime being included, which pollutes the global scope.

然而,使用 runtime 转换器,它被编译为:

¥With the runtime transformer, however, it is compiled to:

JavaScript
"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
);
}

这意味着你可以在不污染当前环境的情况下使用再生器运行时。

¥This means that you can use the regenerator runtime without polluting your current environment.

core-js 别名

¥core-js aliasing

有时你可能想要使用新的内置插件,例如 MapSetPromise 等。使用它们的唯一方法通常是包含一个全局污染的 polyfill。

¥Sometimes you may want to use new built-ins such as Map, Set, Promise etc. Your only way to use these is usually to include a globally polluting polyfill.

这与 corejs 选项有关。

¥This is with the corejs option.

该插件转换以下内容:

¥The plugin transforms the following:

JavaScript
var sym = Symbol();

var promise = Promise.resolve();

var check = arr.includes("yeah!");

console.log(arr[Symbol.iterator]());

进入以下:

¥into the following:

JavaScript
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));

这意味着你可以无缝地使用这些原生内置函数和方法,而不必担心它们来自何处。

¥This means is that you can seamlessly use these native built-ins and methods without worrying about where they come from.

注意:"foobar".includes("foo") 等实例方法仅在使用 corejs: 3 时有效。

¥NOTE: Instance methods such as "foobar".includes("foo") will only work when using corejs: 3.

助手别名

¥Helper aliasing

通常 Babel 会在你的文件顶部放置助手来执行常见任务,以避免在当前文件中重复代码。有时这些助手可能会变得有点笨重,并在文件之间添加不必要的重复。runtime 转换器替换了对模块的所有帮助调用。

¥Usually Babel will place helpers at the top of your file to do common tasks to avoid duplicating the code around in the current file. Sometimes these helpers can get a little bulky and add unnecessary duplication across files. The runtime transformer replaces all the helper calls to a module.

这意味着以下代码:

¥That means that the following code:

JavaScript
class Person {}

通常会变成:

¥usually turns into:

JavaScript
"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 转换器将其变成:

¥the runtime transformer however turns this into:

JavaScript
"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);
};

删除的选项

¥Removed options

Babel 7.0.0 中删除了以下选项:

¥The following options where removed in Babel 7.0.0:

  • useBuiltIns

  • polyfill