譯者: 波比小金剛node
翻譯水平有限,若有錯誤請指出。webpack
原文: medium.com/webpack/web…web
ps: 最近開始整理全部的優質文章翻譯集,固然若是你有好的文章請提 issue,我會找時間翻譯出來。json
wepack4 中的一個重大改變就是針對引入非 ESM 模塊(好比 CommonJS 模塊)時,import() 行爲的不一樣ui
事實上在使用 import() 的時候須要考慮不少場景。spa
可是,讓咱們從幾個命名提示開始:翻譯
須要考慮如下場景:code
這裏有一些容易理解的例子(和上邊的對照起來):對象
// (A) source.js
import("./target").then(result => console.log(result));
// (B) source.mjs
import("./target").then(result => console.log(result));
// (1) target.js
exports.name = "name";
exports.default = "default";
// (2) target.js
exports.__esModule = true;
exports.name = "name";
exports.default = "default";
// (3) target.js or target.mjs
export const name = "name";
export default "default";
// (4) target.json
{ name: "name", default: "default" }
複製代碼
讓咱們從簡單的開始:webpack4
探討的內容實際就是 webpack4 中 import() 引入不一樣規範的模塊的時候,其處理方式。
就是引入一個 ESM 的狀況
ESM 規範實際上覆蓋了這些狀況,他們是惟一的"規範"。
import() 將解析目標模塊的命名空間對象。爲了兼容性,會在其命名空間對象中增長一個 __esModule 標誌,以供轉換後的 imports 使用。
{ __esModule: true, name: "name", default: "default" }
複製代碼
好比引入一個 CommonJS 模塊
咱們導入一個 CommonJS 模塊,webpack3 僅僅解析 module.exports 的值。而 webpack4 將會人爲的爲其建立一個命名空間對象,使得 import() 能夠一致的解析這個命名空間對象。
CommonJs 模塊的默認導出始終是 module.exports 的值,webpack 容許經過 import 從 CommonJS 模塊獲取屬性,import { property } from 'cjs'
,因此咱們容許 import()
注意:這種狀況下,default
屬性被默認的default
隱藏。
// webpack 3
{ name: "name", default: "default" }
// webpack 4
{ name: "name", default: { name: "name", default: "default" } }
複製代碼
在 strict-ESM 中引入 CommonJS 模塊
在 strict-ESM 中,咱們不容許經過 import 獲取屬性,只容許 non-ESM 的默認導出。
{ default: { name: "name", default: "default" } }
複製代碼
引入一個設置 __esModule: true 的 CommonJS 模塊
webpack 經過將 CJS 模塊升級爲 ESM 來支持 __esModule。
{ __esModule: true, name: "name", default: "default" }
複製代碼
在 strict-ESM 中引入 transpiled-ESM
在 strict-ESM 中 __esModule 不被支持。
你能夠把它稱爲破壞,但至少它與 node.js 一致。
{ default: { __esModule: true, name: "name", default: "default" } }
複製代碼
引入 json
在導入 json 的時候,無論是否是 strict-ESM,都支持屬性選擇。json 將完整的對象做爲 default 導出。
{ name: "name", default: { name: "name", default: "default" } }
複製代碼
總結上邊的情景,只有一種狀況發生了改變。當導出對象的時候沒有問題,可是 module.exports 與非對象一塊兒使用的時候,你會遇到麻煩。
好比:
module.exports = 42
複製代碼
你須要使用default
屬性:
// webpack 3
42
// webpack 4
{ default: 42 }
複製代碼