CommonJS和ES Module

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 和现代工程化。

相关推荐
陈随易11 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
云-缩影12 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
Dream-Y.ocean13 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
考虑考虑14 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
Highcharts.js14 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
无奈何杨14 小时前
风控决策系统决策流,策略模式,权重、顺序、投票、最坏
后端
Patrick_Wilson15 小时前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言
苏三说技术15 小时前
DeepSeek Harness入驻B站,评论区被干成了大型插件集市!
后端
橙序员小站16 小时前
我一句话让 AI 把公众号工作台搭完了:部署实测记录
后端
Patrick_Wilson16 小时前
从文本输出理解 Go 方法与接口
后端·go·编程语言