@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 的不同解析演算法。
範例
在
export default 42;
輸出
Object.defineProperty(exports, "__esModule", {
value: true,
});
exports.default = 42;
安裝
- npm
- Yarn
- pnpm
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
用法
使用設定檔 (建議)
// without options
{
"plugins": ["@babel/plugin-transform-modules-commonjs"]
}
// with options
{
"plugins": [
["@babel/plugin-transform-modules-commonjs", {
"allowTopLevelThis": true
}]
]
}
透過 CLI
babel --plugins @babel/plugin-transform-modules-commonjs script.js
透過 Node API
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
屬性。然後使用此屬性來判斷匯入內容是否是預設匯出,或是否包含預設匯出。
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
的值。
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"
編譯時也能運作。
"none"
如果您知道已匯入的檔案已使用會將default
匯出儲存在exports.default
的編譯器(例如 Babel)進行轉換,則可以安全地省略_interopRequireDefault
輔助函式。
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
屬性。
var foo = (exports.foo = 5);
Object.defineProperty(exports, "__esModule", {
value: true,
});
考慮移轉至頂層enumerableModuleMeta
假設。
{
"assumptions": {
"enumerableModuleMeta": true
}
}
在不支援此功能的環境中,您可以啟用enumerableModuleMeta
假設,而不是使用Object.defineProperty
,而是使用指定。
var foo = (exports.foo = 5);
exports.__esModule = true;
strict
boolean
,預設為false
預設情況下,在使用 Babel 匯出時,會匯出不可列舉的__esModule
屬性。在某些情況下,此屬性用於判斷匯入是否為預設匯出,或是否包含預設匯出。
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"
相同。