@babel/plugin-transform-runtime
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
该插件支持复用 Babel 注入的辅助代码,以减小代码体积。
实例方法如 "foobar".includes("foo") 仅在 core-js@3 环境下有效。如需 polyfill 这些方法,可直接导入 "core-js" 或使用 @babel/preset-env 的 useBuiltIns 选项。
安装
请将其安装为开发依赖项。
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/plugin-transform-runtime
yarn add --dev @babel/plugin-transform-runtime
pnpm add --save-dev @babel/plugin-transform-runtime
bun add --dev @babel/plugin-transform-runtime
同时安装 @babel/runtime 作为生产依赖项(因其用于"运行时")。
- npm
- Yarn
- pnpm
- Bun
npm install --save @babel/runtime
yarn add @babel/runtime
pnpm add @babel/runtime
bun add @babel/runtime
转换插件通常仅在开发时使用,但运行时库会被部署后的代码所依赖。详见下方示例。
启用此插件时,@babel/preset-env 中的 useBuiltIns 选项必须保持未设置状态,否则该插件可能无法完全隔离运行环境。
设计目的
Babel 使用小型辅助函数实现如 _extend 等常见功能。默认情况下,这些辅助函数会被添加到每个需要它们的文件中。当应用分散在多个文件时,这种重复通常是不必要的。
这正是 @babel/plugin-transform-runtime 的用途:所有辅助函数将引用 @babel/runtime 模块,从而避免编译输出中的重复代码。运行时库会被编译到最终构建产物中。
该转换器的另一目的是创建沙盒化的代码环境。若直接导入 core-js 或 @babel/polyfill 及其提供的 Promise、Set、Map 等内置对象,会污染全局作用域。这对应用或命令行工具可能无妨,但当代码作为库发布供他人使用,或运行环境不可控时,就会产生问题。
转换器会将这些内置对象别名指向 core-js,使您无需导入 polyfill 即可无缝使用。
具体工作原理及转换类型详见技术细节章节。
用法
通过配置文件(推荐)
无配置选项时:
{
"plugins": ["@babel/plugin-transform-runtime"]
}
配置选项及其默认值:
{
"plugins": [
[
"@babel/plugin-transform-runtime",
{
"absoluteRuntime": false,
"corejs": false,
"helpers": true,
"regenerator": true,
"version": "7.0.0-beta.0"
}
]
]
}
插件默认假设所有可 polyfill 的 API 均由用户提供,否则需指定 corejs 选项。
通过命令行
babel --plugins @babel/plugin-transform-runtime script.js
通过 Node API
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-runtime"],
});
配置选项
absoluteRuntime
boolean 或 string 类型,默认值 false。
此选项允许在整个项目中广泛使用 transform-runtime。默认情况下,transform-runtime 直接从 @babel/runtime/foo 导入,但这仅当 @babel/runtime 位于被编译文件的 node_modules 中时才有效。对于嵌套的 node_modules、npm 链接模块或位于用户项目外的 CLI 等场景,这会导致问题。为避免解析运行时模块位置的困扰,此选项允许用户预先解析运行时路径,并将绝对路径插入输出代码。
若文件需编译后延迟使用,则绝对路径并不可取;但在即编即用的场景中,该方案非常实用。
你可以在此处阅读更多关于配置插件选项的信息。
corejs
false, 2, 3 or { version: 2 | 3, proposals: boolean }, defaults to false.
e.g. ['@babel/plugin-transform-runtime', { corejs: 3 }],
History
| Version | Changes |
|---|---|
v7.4.0 | Supports { proposals: boolean } |
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).
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 option | Install command |
|---|---|
false | npm install --save @babel/runtime |
2 | npm install --save @babel/runtime-corejs2 |
3 | npm install --save @babel/runtime-corejs3 |
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, defaults to true.
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.
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
| Version | Changes |
|---|---|
v7.24.0 | Added moduleName option |
string 类型,默认值为 @babel/runtime。
此选项控制 @babel/plugin-transform-runtime 注入导入语句时使用的辅助函数包,优先级规则如下:
-
若指定了
moduleName选项,则优先使用其值 -
遵循
babel-plugin-polyfill-*插件建议的辅助模块babel-plugin-polyfill-corejs3建议使用@babel/runtime-corejs3babel-plugin-polyfill-corejs2建议使用@babel/runtime-corejs2
-
回退至
@babel/runtime
注意:指定 corejs 选项将在内部启用对应的 babel-plugin-polyfill-corejs* 插件,因此会影响最终的模块名称。
regenerator
boolean, defaults to true.
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.
The regenerator option will be removed in Babel 8, as it will not be necessary anymore.
useESModules
boolean, defaults to false.
History
| Version | Changes |
|---|---|
v7.13.0 | This option has been deprecated |
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.
For example, here is the classCallCheck helper with useESModules disabled:
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:
export default function(instance, Constructor) {
if (!(instance instanceof Constructor)) {
throw new TypeError("Cannot call a class as a function");
}
}
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 可以使用更高级的功能。
例如,如果您依赖 @babel/runtime@^7.24.0,可以通过以下配置转译代码:
{
"plugins": [
["@babel/plugin-transform-runtime", {
"version": "^7.24.0"
}]
]
}
这样可以减小包体积。
技术细节
transform-runtime 转换器插件实现三个核心功能:
- 当使用生成器/异步函数时自动引入
@babel/runtime/regenerator(可通过regenerator选项控制) - 必要时可使用
core-js替代用户提供的 polyfill(通过corejs选项控制) - 自动移除内联 Babel 辅助函数,改用
@babel/runtime/helpers模块(通过helpers选项控制)
这实际意味着什么?简而言之,您可以无缝使用 Promise、Set、Symbol 等内置对象以及所有需要 polyfill 的 Babel 功能,同时避免全局污染,这使其特别适合库开发。
请务必将 @babel/runtime 添加为依赖项。
生成器函数别名处理
当使用生成器函数或异步函数时:
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
);
}
这种方式依赖全局的 regenerator 运行时,会造成全局作用域污染。
而使用 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
);
}
这意味着您可以在不污染当前环境的前提下使用 regenerator 运行时。
core-js 别名处理
当需要使用 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 时有效。
辅助函数别名处理
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);
};
已移除的选项
以下选项已在 Babel 7.0.0 中移除:
以下选项已在 Babel 7.0.0 中移除:
-
useBuiltIns -
polyfill