CommonJS 和 ES Module 都是 JavaScript 的模块化方案,但它们出现的时代和设计思路不同。CommonJS 主要是 Node.js 早期使用的模块规范,采用 require 导入、module.exports 导出,特点是运行时加载;而 ES Module 是 JavaScript 官方标准模块方案,采用 import 和 export,特点是编译时分析,因此更利于静态优化和 Tree Shaking。简单来说,CommonJS 更偏 Node 传统模块体系,ES Module 更现代、标准化,也更适合前端工程化和未来生态。
核心
- CommonJS 和 ES Module 都是模块化方案
- CommonJS:
require/module.exports - ES Module:
import/export - CommonJS 是运行时加载
- ES Module 是编译时静态分析
- ES Module 更利于 Tree Shaking
- Node 早期常用 CommonJS,现代前端更常用 ES Module
一、什么是 CommonJS
CommonJS 是一种早期的 JavaScript 模块规范,在 Node.js 里非常常见。
它的写法一般是:
导出
js
module.exports = {
add
}
导入
js
const math = require('./math')
它的特点是:
- 主要用于 Node.js 早期生态
- 模块在运行时加载
- 更适合服务端环境
二、什么是 ES Module
ES Module,也叫 ESM,是 JavaScript 官方标准的模块化方案。
它的写法是:
导出
js
export const add = () => {}
或者:
js
export default add
导入
js
import { add } from './math.js'
它的特点是:
- 是语言层面的官方标准
- 可以做静态分析
- 现代前端和新版本 Node 都支持
三、两者最核心的区别
1. 语法不同
CommonJS:
js
require()
module.exports
exports
ES Module:
js
import
export
export default
这是最直观的区别。
2. 加载时机不同
CommonJS
是运行时加载
也就是说,代码执行到 require 的时候,才会去加载模块。
ES Module
是编译时加载 / 静态分析
也就是说,在代码真正运行前,编译阶段就能确定模块依赖关系。
所以可以直接记:
- CommonJS:运行时
- ESM:编译时
四、为什么 ES Module 更利于优化
因为 ES Module 是静态的。
比如:
js
import { add } from './math'
打包工具在构建阶段就能知道:
- 你导入了哪个模块
- 用了哪个导出
- 哪些代码没用到
所以可以更方便做:
- Tree Shaking
- 静态依赖分析
- 更精准的打包优化
而 CommonJS 的 require 可以动态写:
js
require(path)
这让编译阶段更难准确分析依赖。
所以可以说:
ES Module 更适合工程化优化,因为它的依赖关系是静态可分析的。
五、值拷贝和引用绑定的区别
这也是一个比较常见的点。
CommonJS
导出更偏向于值的拷贝
如果导出的是基本类型,外部拿到的是当前值。
ES Module
导出的是值的引用绑定
也就是说,ES Module 更像是和原变量建立了一种实时关联。
所以在某些更新场景里,ESM 的行为会更接近"动态绑定"。
六、this 指向不同
在 CommonJS 模块里,顶层的 this 通常指向当前模块对象。
而在 ES Module 里,模块默认就是严格模式,顶层 this 是 undefined。
七、循环依赖处理也有差异
CommonJS 和 ES Module 都可能遇到循环依赖,但处理机制不同。
CommonJS
因为是运行时加载,所以循环依赖时拿到的可能是"已经执行到一半的导出结果"。
ES Module
因为是静态结构,处理方式会更规范一些,但也仍然要小心循环依赖。
八、Node 中两者的关系
Node 早期主要使用 CommonJS。
现在新版本 Node 同时支持:
- CommonJS
- ES Module
但两者在 Node 里混用时要注意:
- 文件后缀
package.json中的type- 导入导出方式差异
比如:
type: "module"表示按 ESM 解析- 默认很多老项目还是 CommonJS
九、实际开发中怎么选
你可以这样答:
- 老 Node 项目、很多历史包,CommonJS 仍然常见
- 现代前端项目和新项目,一般更推荐 ES Module
- 因为 ESM 是官方标准,语法统一,也更利于打包优化
所以整体趋势是:
CommonJS 更偏历史和 Node 传统,ES Module 更偏现代标准和未来方向。
CommonJS 和 ES Module 都是 JavaScript 模块化方案,前者使用
require和module.exports,属于运行时加载;后者使用import和export,属于编译时静态分析,因此 ES Module 更标准化,也更利于 Tree Shaking 和现代工程化。