简单说明一下两者在外观上的区别:ESM是ES6之后的JS模块规范。CJS(CommonJS)是社区制定的模块规范,主要用于node.js应用。ESM模块规范使用import导入,export默认导出。CJS模块规范使用require进行导入和导出,使用module.exports进行导出。在npminit初始化的Node.js项目中,package.json中type字段的设置决定了使用哪个模块规范来加载.js文件。(类型未写入->CJS加载。“类型”:“模块”->ESM加载)。此外,.mjs文件始终作为ES6模块加载,而.cjs文件始终作为CJS模块加载。重点说一下这两种模块系统在使用上的区别:无论是使用CJS还是ESM中的哪一种模块系统作为模块化开发的规范,(大多数情况下)最终都需要通过编译工具进行处理,编译成一个js文件,最终应用于生产环境。先说说两个模块规范的区别://↓ESM(场景一)//a.jsconsta=1;constb="2";export{a,b};exportdefaultfunction(){console.log("defaultfunctiondone");}//b.jsimport{a,b}from"./a.js";importdefaultFuncfrom"./a.js";console.log(a);//正常输出1console.log(b);//正常输出"2"defaultFunc();//正常执行->"defaultfunctiondone"//↓CJS(场景2)//aa.jsconsta=1;constb="2";exports.a=a;exports.b=b;module.exports=3;//bb.jsconstbb=require("./aa.js");console.log(bb);//输出结果3对比场景一和场景二:在ESM中,exportdefault被认为是顶层导出。出口被视为二次出口。两种导出方式不冲突,可以同时使用。在CJS中,module.exports被视为顶级导出。exports.x被视为顶级导出。视为二次导出,顶层导出会覆盖二次导出(不管顶层导出的位置如何)并增加场景3//↓CJS(场景3)//cc.jsconsta=1;constb="2";出口。a=a;exports.b=b;//dd.jsmodule.exports=3;//ee.jsmodule.exports=function(){console.log("defaultfunctiondone");}//ff.jsconstcc=require('./cc.js');constdd=require('./dd.js');constee=require('./ee.js');console.log(cc);//正常输出{a:1,b:'2'}console.log("dd->",dd);//正常输出3ee();//正常执行->"defaultfunctiondone"上面的场景1、2、3基本涵盖了ESM、CJS这两个模块规范在使用中出现的情况如果单独使用是没有问题的(即使用项目中从头到尾使用ESM,或者从头到尾使用CJS),编译工具会帮助我们处理各种情况。但是一旦将两个模块混在一起,就可能会出现问题。两个模块混合使用肯定需要某种编译工具,使用编译后的产品。这里我们以ts-node为例。//a.ts(ESM)exportdefaultfunction(){console.log("defaultfunctiondone")}//b.ts(CJS)constb=require("./a.ts");//b();//直接执行顶层导出函数会报错b.default()//必须使用default属性->正常执行“defaultfunctiondone”,我们尝试在单个项目中使用模块规范。如果真的遇到上面的情况,就需要ESM和CJS混用了。最好查阅项目中使用的编译工具(如webpack、rollup、ts-node等)的文档。查看编译工具如何处理兼容性问题。比如ts-node中的语法糖。export=xxx;importx=require('路径/文件');结尾。同步更新到你的语雀https://www.yuque.com/diracke...
