@babel/plugin-transform-modules-commonjs
历史
| 版本 | 变更 |
|---|---|
v7.14.0 | 实现了 importInterop 选项 |
这个插件包含在 @babel/preset-env 的 modules 选项下
这个插件将 ECMAScript 模块转换为 CommonJS。请注意,只有 import/export 语句(import "./mod.js")和 import 表达式(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
在
export default 42;
出
Object.defineProperty(exports, "__esModule", {
value: true,
});
exports.default = 42;
安装
🌐 Installation
- npm
- Yarn
- pnpm
- Bun
npm install --save-dev @babel/plugin-transform-modules-commonjs
yarn add --dev @babel/plugin-transform-modules-commonjs
pnpm add --save-dev @babel/plugin-transform-modules-commonjs
bun add --dev @babel/plugin-transform-modules-commonjs
用法
🌐 Usage
使用配置文件(推荐)
🌐 With a configuration file (Recommended)
// without options
{
"plugins": ["@babel/plugin-transform-modules-commonjs"]
}
// with options
{
"plugins": [
["@babel/plugin-transform-modules-commonjs", {
"allowTopLevelThis": true
}]
]
}
通过 CLI
🌐 Via CLI
babel --plugins @babel/plugin-transform-modules-commonjs script.js
通过 Node API
🌐 Via Node API
require("@babel/core").transformSync("code", {
plugins: ["@babel/plugin-transform-modules-commonjs"],
});
选项
🌐 Options
allowTopLevelThis
boolean,默认值为 false。
当这个选项是 true 时,Babel 会将顶层 this(在 ES 模块中总是 undefined)转换为 void 0。
🌐 When this option is true, Babel will transform top level this (always undefined in ES Modules) to void 0.
importInterop
"babel" | "node" | "none" 或 (specifier: string, requestingFilename: string | undefined) => "babel" | "node" | "none"。默认是 "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.
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.
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.
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 属性。
🌐 By default, when using exports with babel a non-enumerable __esModule property
is exported.
var foo = (exports.foo = 5);
Object.defineProperty(exports, "__esModule", {
value: true,
});
考虑迁移到顶层 enumerableModuleMeta 假设。
{
"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.
var foo = (exports.foo = 5);
exports.__esModule = true;
strict
boolean,默认值为 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.
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
boolean、Array<string> 或 (string) => boolean,默认值为 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- 没有任何导入模块的惰性初始化。 -
true- 不要对本地./foo导入进行懒初始化,但可以对foo依赖进行懒初始化。本地路径更有可能出现循环依赖,如果懒加载的话可能会出问题,所以默认情况下本地路径不是懒加载的,而独立模块之间的依赖很少是循环的。
-
Array<string>- 延迟初始化所有源与给定字符串之一匹配的导入。 -
(string) => boolean- 传递将被调用的回调来决定是否应该延迟加载给定的源字符串。
导入永远不会惰性的两种情况是:
🌐 The two cases where imports can never be lazy are:
-
import "foo";由于副作用导入的存在意味着没有绑定用来稍后启动初始化,所以它们自动是非惰性的。
-
export * from "foo"重新导出所有名称需要提前执行,否则没有办法知道哪些名称需要导出。
你可以在这里了解更多关于配置插件选项的内容
noInterop
boolean,默认值为 false
已弃用:请改用 importInterop 选项。
当设置为 true 时,这个选项的行为和设置 importInterop: "none" 一样。
🌐 When set to true, this option has the same behavior as setting importInterop: "none".
相关 assumptions
🌐 Relevant assumptions