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

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
三十而立洋3 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
大勇前进3 天前
原生 PHP 还是 Laravel?小项目到底要不要上框架
后端
yuzhi_liu3 天前
我用 LangGraph4j 实现 Multi-Agent Supervisor
后端
alsmile3 天前
Node-RED 之外,国产规则引擎的新方案:基于标准语法,Go 先行实现
后端·开源·go
大白803 天前
PHP 内存溢出排查思路:看懂报错日志,精准定位问题
后端
卡布鲁3 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js