差异主要有如下几点:

  • CommonJS 输出是值的拷贝,即原来模块中的值改变不会影响已经加载的该值,ES6静态分析,动态引用,输出的是值的引用,值改变,引用也改变,即原来模块中的值改变则该加载的值也改变。
  • CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。
  • CommonJS 加载的是整个模块,即将所有的接口全部加载进来,ES6 可以单独加载其中的某个接口(方法),
  • CommonJS this 指向当前模块,ES6 this 指向undefined

CommonJS 模块输出的是值的拷贝,也就是说,一旦输出一个值,模块内部的变化就影响不到这个值。
ES6 模块的运行机制与 CommonJS 不一样。
JS 引擎对脚本静态分析的时候,遇到模块加载命令import,就会生成一个只读引用。
等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
ES6 模块不会缓存运行结果,而是动态地去被加载的模块取值,并且变量总是绑定其所在的模块。

下面是一个表格,展示了ES6模块与CommonJS模块之间的差异:

特点ES6模块CommonJS模块
语法使用importexport语法使用requiremodule.exports语法
动态导入支持动态导入,可以根据条件导入不同的模块不支持动态导入,导入的模块在脚本加载时确定
导入和导出的类型可以导入和导出变量、函数、类、默认导出等多种类型只能导入和导出整个模块对象
导入方式可以使用命名导入和默认导入方式只支持命名导入方式
导出方式可以使用命名导出和默认导出方式只支持命名导出方式
模块加载时机在编译时就会生成所有模块的依赖关系,可以进行静态分析在运行时加载模块,无法进行静态分析
模块间的关系每个ES6模块都有自己的作用域,相互之间没有依赖关系模块之间共享相同的作用域,可以直接访问和修改导出的变量和函数
浏览器支持部分浏览器原生支持,可以使用Babel转译实现兼容性不支持,需要使用工具如Browserify、Webpack进行转译和打包
Node.js使用需要使用--experimental-modules标志启用ES模块支持原生支持CommonJS模块

请注意,这些是一般规则,具体的差异可能因为不同的运行环境和工具而有所不同。

个人笔记记录 2021 ~ 2025