译者: 波比小金刚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 }
复制代码