Skip to main content

@babel/plugin-transform-modules-commonjs

History
版本变化
v7.14.0实现了 importInterop 选项
信息

此插件包含在 @babel/preset-env 中的 modules 选项下

¥This plugin is included in @babel/preset-env under the modules option

该插件将 ECMAScript 模块转换为 CommonJS。请注意,只有导入/导出语句 (import "./mod.js") 和导入表达式 (import('./mod.js')) 的语法被转换,因为 Babel 不知道 ECMAScript 模块和 CommonJS 实现之间的不同解析算法。

¥This plugin transforms ECMAScript modules to CommonJS. Note that only the syntax of import/export statements (import "./mod.js") and import expressions (import('./mod.js')) is transformed, as Babel is unaware of different resolution algorithms between implementations of ECMAScript modules and CommonJS.

示例

¥Example

输入

¥In

JavaScript
export default 42;

输出

¥Out

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

exports.default = 42;

安装

¥Installation

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

用法

¥Usage

¥With a configuration file (Recommended)

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

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

通过 CLI

¥Via CLI

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

通过 Node API

¥Via Node API

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

选项

¥Options

importInterop

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

¥"babel" | "node" | "none", or (specifier: string, requestingFilename: string | undefined) => "babel" | "node" | "none". Defaults to "babel".

CommonJS 模块和 ECMAScript 模块不完全兼容。然而,编译器、打包器和 JavaScript 运行时开发了不同的策略以使它们尽可能地协同工作。

¥CommonJS modules and ECMAScript modules are not fully compatible. However, compilers, bundlers and JavaScript runtimes developed different strategies to make them work together as well as possible.

此选项指定 Babel 应使用的互操作策略。当它是一个函数时,Babel 调用它传递导入说明符和导入器路径。例如,当编译一个包含 import { a } from 'b'/full/path/to/foo.js 文件时,Babel 会用参数 ('b', '/full/path/to/foo.js') 调用它。

¥This option specify which interop strategy Babel should use. When it's a function, Babel calls it passing the import specifier and the importer path. For example, when compiling a /full/path/to/foo.js file containing import { a } from 'b', Babel will call it with parameters ('b', '/full/path/to/foo.js').

"babel"

当使用带有 babel 的导出时,会导出一个不可枚举的 __esModule 属性。然后,此属性用于确定导入是默认导出还是包含默认导出。

¥When using exports with babel a non-enumerable __esModule property is exported. This property is then used to determine if the import is the default export or if it contains the default export.

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 编译,它们的行为就好像它们都没有被编译一样。

¥When this import interop is used, if both the imported and the importer module are compiled with Babel they behave as if none of them was compiled.

这是默认行为。

¥This is the default behavior.

"node"

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

¥When importing CommonJS files (either directly written in CommonJS, or generated with a compiler) Node.js always binds the default export to the value of 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 中工作的任何导入在使用 Babel 使用 importInterop: "node" 编译时也可以工作。

¥This is not exactly the same as what Node.js does since Babel allows accessing any property of module.exports as a named export, while Node.js only allows importing statically analyzable properties of module.exports. However, any import working in Node.js will also work when compiled with Babel using importInterop: "node".

"none"

如果你知道导入的文件已使用将 default 导出存储在 exports.default 上的编译器进行了转换(例如 Babel),你可以放心地省略 _interopRequireDefault 辅助程序。

¥If you know that the imported file has been transformed with a compiler that stores the default export on exports.default (such as Babel), you can safely omit the _interopRequireDefault helper.

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

¥boolean, defaults to false.

默认情况下,当使用带有 babel 的导出时,会导出一个不可枚举的 __esModule 属性。

¥By default, when using exports with babel a non-enumerable __esModule property is exported.

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

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

考虑迁移到顶层 enumerableModuleMeta 假设。

¥Consider migrating to the top level enumerableModuleMeta assumption.

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

在不支持这一点的环境中,你可以启用 enumerableModuleMeta 假设,而不是使用 Object.defineProperty,而是使用分配。

¥In environments that don't support this you can enable the enumerableModuleMeta assumption, instead of using Object.defineProperty an assignment will be used instead.

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

strict

boolean,默认为 false

¥boolean, defaults to false

默认情况下,当使用带有 babel 的导出时,会导出一个不可枚举的 __esModule 属性。在某些情况下,此属性用于确定导入是默认导出还是包含默认导出。

¥By default, when using exports with babel a non-enumerable __esModule property is exported. In some cases this property is used to determine if the import is the default export or if it contains the default export.

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

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

为了防止 __esModule 属性被导出,可以将 strict 选项设置为 true

¥In order to prevent the __esModule property from being exported, you can set the strict option to true.

lazy

booleanArray<string>(string) => boolean,默认为 false

¥boolean, Array<string>, or (string) => boolean, defaults to false

将 Babel 编译的 import 语句更改为在首次使用导入的绑定时延迟评估。

¥Changes Babel's compiled import statements to be lazily evaluated when their imported bindings are used for the first time.

这可以改善模块的初始加载时间,因为有时完全不需要预先评估依赖。在实现库模块时尤其如此。

¥This can improve initial load time of your module because evaluating dependencies up front is sometimes entirely un-necessary. This is especially the case when implementing a library module.

lazy 的值有几个可能的影响:

¥The value of lazy has a few possible effects:

  • false - 没有任何导入模块的惰性初始化。

    ¥false - No lazy initialization of any imported module.

  • true - 不要延迟初始化本地 ./foo 导入,而是延迟初始化 foo 依赖。

    ¥true - Do not lazy-initialize local ./foo imports, but lazy-init foo dependencies.

    本地路径更可能具有循环依赖,如果延迟加载可能会中断,因此默认情况下它们不是惰性的,而独立模块之间的依赖很少是循环的。

    ¥Local paths are much more likely to have circular dependencies, which may break if loaded lazily, so they are not lazy by default, whereas dependencies between independent modules are rarely cyclical.

  • Array<string> - 延迟初始化所有源与给定字符串之一匹配的导入。

    ¥Array<string> - Lazy-initialize all imports with source matching one of the given strings.

  • (string) => boolean - 传递将被调用的回调来决定是否应该延迟加载给定的源字符串。

    ¥(string) => boolean - Pass a callback that will be called to decide if a given source string should be lazy-loaded.

导入永远不会惰性的两种情况是:

¥The two cases where imports can never be lazy are:

  • import "foo";

    副作用导入自动是非惰性的,因为它们的存在意味着没有绑定到以后启动初始化。

    ¥Side-effect imports are automatically non-lazy since their very existence means that there is no binding to later kick off initialization.

  • export * from "foo"

    重新导出所有名称需要预先执行,否则无法知道需要导出哪些名称。

    ¥Re-exporting all names requires up-front execution because otherwise there is no way to know what names need to be exported.

提示

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

¥You can read more about configuring plugin options here

noInterop

boolean,默认为 false

¥boolean, defaults to false

提醒

已弃用:请改用 importInterop 选项。

¥Deprecated: Use the importInterop option instead.

当设置为 true 时,此选项与设置 importInterop: "none" 具有相同的行为。

¥When set to true, this option has the same behavior as setting importInterop: "none".

相关 assumptions

¥Relevant assumptions