跳至主内容

@babel/plugin-transform-modules-commonjs

非官方测试版翻译

本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →

History
VersionChanges
v7.14.0Implemented the importInterop option
信息

此插件已包含在 @babel/preset-envmodules 选项中

该插件将 ECMAScript 模块转换为 CommonJS。请注意,仅会转换 import/export 语句(import "./mod.js")和 import 表达式(import('./mod.js'))的语法,因为 Babel 无法感知 ECMAScript 模块与 CommonJS 在实现上的不同解析算法。

示例

输入

JavaScript
export default 42;

输出

JavaScript
Object.defineProperty(exports, "__esModule", {
value: true,
});

exports.default = 42;

安装

npm install --save-dev @babel/plugin-transform-modules-commonjs

用法

通过配置文件(推荐)

JavaScript
// without options
{
"plugins": ["@babel/plugin-transform-modules-commonjs"]
}

// with options
{
"plugins": [
["@babel/plugin-transform-modules-commonjs", {
"allowTopLevelThis": true
}]
]
}

通过命令行

Shell
babel --plugins @babel/plugin-transform-modules-commonjs script.js

通过 Node API

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

配置选项

importInterop

"babel" | "node" | "none",或 (specifier: string, requestingFilename: string | undefined) => "babel" | "node" | "none"。默认值为 "babel"

CommonJS 模块与 ECMAScript 模块并非完全兼容。但编译器、打包工具和 JavaScript 运行时已发展出不同的策略来尽可能实现两者的协同工作。

此选项用于指定 Babel 应使用的互操作策略。当值为函数时,Babel 会传入导入标识符和导入方路径调用该函数。例如,当编译包含 import { a } from 'b'/full/path/to/foo.js 文件时,Babel 会以参数 ('b', '/full/path/to/foo.js') 调用该函数。

"babel"

使用 Babel 导出时,会导出一个不可枚举的 __esModule 属性。该属性用于判断导入内容是否为默认导出,或是否包含默认导出。

JavaScript
import foo from "foo";
import { bar } from "bar";
foo;
bar;

// Is compiled to ...

"use strict";

function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}

var _foo = _interopRequireDefault(require("foo"));
var _bar = require("bar");

_foo.default;
_bar.bar;

当使用此导入互操作策略时,若被导入模块和导入方模块均使用 Babel 编译,其行为表现将如同两者都未经编译。

此为默认行为。

"node"

当导入 CommonJS 文件(直接编写的 CommonJS 文件或由编译器生成)时,Node.js 始终将 default 导出绑定到 module.exports 的值。

JavaScript
import foo from "foo";
import { bar } from "bar";
foo;
bar;

// Is compiled to ...

"use strict";

var _foo = require("foo");
var _bar = require("bar");

_foo;
_bar.bar;

这与 Node.js 的实际行为并非完全一致,因为 Babel 允许将 module.exports 的任何属性作为命名导出访问,而 Node.js 仅允许导入 module.exports 的可静态分析属性。但任何在 Node.js 中可正常工作的导入,在使用 importInterop: "node" 的 Babel 编译后同样有效。

"none"

若确认被导入文件已通过将 default 导出存储在 exports.default 的编译器(如 Babel)转换,可安全省略 _interopRequireDefault 辅助函数。

JavaScript
import foo from "foo";
import { bar } from "bar";
foo;
bar;

// Is compiled to ...

"use strict";

var _foo = require("foo");
var _bar = require("bar");

_foo.default;
_bar.bar;

loose

boolean,默认值 false

默认情况下,使用 Babel 导出时会生成一个不可枚举的 __esModule 属性。

JavaScript
var foo = (exports.foo = 5);

Object.defineProperty(exports, "__esModule", {
value: true,
});
注意

请考虑迁移至顶层 enumerableModuleMeta 假设。

babel.config.json
{
"assumptions": {
"enumerableModuleMeta": true
}
}

在不支持此特性的环境中,可启用 enumerableModuleMeta 假设,此时将使用赋值操作替代 Object.defineProperty

JavaScript
var foo = (exports.foo = 5);
exports.__esModule = true;

strict

boolean,默认值 false

默认情况下,使用 Babel 导出时会生成一个不可枚举的 __esModule 属性。某些情况下该属性用于判断导入内容是否为默认导出,或是否包含默认导出。

JavaScript
var foo = (exports.foo = 5);

Object.defineProperty(exports, "__esModule", {
value: true,
});

要阻止导出 __esModule 属性,可将 strict 选项设为 true

lazy

boolean | Array<string> | (string) => boolean,默认值 false

将 Babel 编译后的 import 语句改为在首次使用导入绑定时进行惰性求值。

这可以提升模块的初始加载时间,因为提前评估依赖有时是完全不必要的,在实现库模块时尤其如此。

lazy 的值有以下几种可能的影响:

  • false - 不对任何导入模块进行懒加载初始化

  • true - 不对本地 ./foo 导入进行懒加载初始化,但会对 foo 依赖进行懒加载初始化

    本地路径更可能出现循环依赖(如果懒加载可能导致问题),因此默认不进行懒加载,而独立模块间的依赖很少是循环的

  • Array<string> - 对源路径匹配给定字符串的导入进行懒加载初始化

  • (string) => boolean - 传入回调函数决定给定源字符串是否应进行懒加载

以下两种情况永远不能使用懒加载:

  • import "foo";

    副作用导入自动视为非懒加载,因为其存在意味着没有可供后续触发初始化的绑定

  • export * from "foo"

    重新导出所有名称需要提前执行,否则无法确定需要导出哪些名称

提示

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

noInterop

boolean,默认值 false

注意

已弃用:请改用 importInterop 选项

当设置为 true 时,此选项的行为等同于设置 importInterop: "none"

相关的 assumptions