# @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,SetMap,这些将污染全局范围。虽然这对于应用程序或命令行工具来说可能没问题,但如果您的代码是一个您打算发布供其他人使用的库,或者如果您无法准确控制代码运行的环境,这就会成为一个问题。

转换器会将这些内置插件别名化为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 助手(classCallCheckextends等)替换为对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/runtimenode_modules正在编译的文件中才有效。node_modules对于位于用户项目之外的嵌套、npm 链接模块或 CLI 等情况,这可能会产生问题。为了避免担心运行时模块的位置是如何解析的,这允许用户预先解析一次运行时,然后将运行时的绝对路径插入到输出代码中。

如果文件是为以后使用而编译的,那么使用绝对路径是不可取的,但在编译文件然后立即使用的上下文中,它们可能非常有用。

您可以在此处阅读有关配置插件选项的更多信息 (opens new window)

# 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,SetPromise。使用这些插件的唯一方法通常是包含一个全局污染的 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);
};

Last Updated: 6/7/2023, 9:06:23 AM