[JS] 模块系统ESM和CJS

简要说明二者的表象区别: ESM 是ES6之后的JS模块规范。
CJS (CommonJS)是社区发展起来的主要应用于node.js应用的模块规范。
ESM模块规范使用import导入,export 、export default导出。
CJS模块规范使用require导入和exports、module.exports导出。
在一个npm init初始化的Node.js项目中,package.json里面type字段的设置决定.js文件用哪种模块规范加载。(type不写-> CJS加载。"type": "module" -> ESM加载)。此外.mjs文件总是以 ES6 模块加载,.cjs文件总是以 CJS 模块加载。
重点说一说两个模块系统在使用时的区别:
不论以CJS、ESM中的哪种模块系统作为模块化开发的规范,(大部分情况下)最终都需要经过编译工具处理,编译成js文件,才能最终应用到生产环境。
再说一说两种模块规范的不同: // ↓ ESM (情景1)

// a.js const a = 1; const b = "2"; export { a, b }; export default function() { console.log("default function done"); } // b.js import { a, b } from "./a.js"; import defaultFunc from "./a.js"; console.log(a); // 正常输出 1 console.log(b); // 正常输出 "2" defaultFunc(); // 正常执行 -> "default function done"

// ↓ CJS (情景2)
// aa.js const a = 1; const b = "2"; exports.a = a; exports.b = b; module.exports = 3; // bb.js const bb= require("./aa.js"); console.log(bb); // 输出结果 3

对比情景1和情景2:
在ESM中
export default被视为顶级导出
export 被视为次级导出
两种导出方式不冲突,可以同时使用
在CJS中
module.exports被视为顶级导出
exports.x 被视为次级导出
顶级导出会覆盖次级导出(无论顶级导出的位置先后)
补充一个情景3
// ↓ CJS (情景3)
// cc.js const a = 1; const b = "2"; exports.a = a; exports.b = b; // dd.js module.exports = 3; // ee.js module.exports = function() { console.log("default function done"); }// ff.js const cc = require('./cc.js'); const dd = require('./dd.js'); const ee= require('./ee.js'); console.log(cc); // 正常输出 { a: 1, b: '2' } console.log("dd->", dd); // 正常输出 3 ee(); // 正常执行 -> "default function done"

上面的情景1、2、3基本涵盖了两个模块规范使用中出现的情况。ESM、CJS如果单独使用(即在一个工程里从头到尾使用ESM,或从头到尾使用CJS),都没有问题,编译工具会帮我们处理好各种情况。
但是一旦出现两种模块混用,就可能出现问题。两种模块混用,必然需要某种编译工具,使用的是编译后产物。
这里以ts-node为例。
// a.ts (ESM) export default function () { console.log("default function done") }// b.ts (CJS) const b = require("./a.ts"); //b(); // 直接执行顶级导出的函数会报错 b.default() // 必须使用default属性 -> 正常执行 "default function done"

工作中,我们尽量在单个工程中使用一种模块规范。如果真的遇到了上面的情景,需要ESM和CJS混用,最好是查阅工程所用的编译工具(如webpack、rollup、ts-node等等)的文档。看编译工具如何处理兼容问题。
举个例子,ts-node中的语法糖。
export = xxx;
import x = require('path/file');
完结。
【[JS] 模块系统ESM和CJS】同步更新到自己的语雀
https://www.yuque.com/diracke...

    推荐阅读