当前位置: 首页 > news >正文

一文读懂:CommonJS 和 ES Module 的本质区别

🧑‍💻 写在开头

点赞 + 收藏 === 学会🤣🤣🤣

面试官:你能说说 CommonJS 和 ES Module 的区别吗?
我:……(脑子里只剩下 requireimport

说实话,这个问题你一定见过,而且99% 的前端都背过标准答案
但真要往深了问一句:

  1. 为什么 ESM 可以 Tree Shaking?CommonJS 不行
  2. 为什么 ESM 的 import 是“只读的”?

很多人,当场就开始“CPU 过载”。

于是我决定直接把底层逻辑捋清楚,以下就是我对 CommonJS 和 ES Module 一次系统性深挖的记录

一、什么是 CommonJS?它解决了什么问题?

1. CommonJS 的诞生背景

在早期 JavaScript 只有浏览器环境时,是没有模块系统的

  • 全局变量污染
  • 文件之间依赖混乱
  • 无法复用代码

于是 Node.js 社区提出了一套解决方案:CommonJS(CMJ)

👉 注意:CommonJS 是社区标准,不是官方语言层面的规范。

CommonJS 的核心特征

  • ✅ 社区标准
  • ✅ 使用函数实现(require
  • ✅ 仅 Node 环境支持
  • ✅ 动态依赖,同步执行

2. CommonJS 为什么叫“动态依赖”?

来看一段最典型的代码:

const moduleName = './a.js';
const a = require(moduleName);

这里的依赖路径,是不是运行时才能确定?这就是动态依赖;

CommonJS 的依赖关系,必须等代码执行时才能知道。


3. require 到底做了什么?(核心原理)

你在 Node 中写的:

const a = require('./a.js');

但如果我追问一句:require 加载的模块代码,是“直接执行”的吗? 模块里的 this、exports、module.exports 到底从哪来的?

答案其实藏在 Node.js 对模块的一层“函数包装”里:

function require(path) {const cache = {}// 1. 如果模块已经加载过,直接返回缓存if (cache[path]) {return cache[path].exports;}// 2. 创建模块对象const module = {id:pathexports: {}};// 3. 执行模块代码(用函数包一层)function _run(exports, require, module, __filename, __dirname) {// 模块源码在这里执行}_run.call(module.exports,module.exports,require,module,__filename,__dirname);// 4. 缓存并返回结果cache[modulePath] = module;return module.exports;
}

假设你有一个文件 a.js,那么文件中的内容会放到上面的_run函数中执行

我们拆开来看:

ScreenShot_2026-02-27_141311_499


在模块初始化阶段,这三个引用的是同一个对象。

所以以下判断永远成立:

console.log(arguments); // [exports, require ,module, __filename, __dirname]
console.log(this); // {}
console.log(this === exports); // true
console.log(exports === module.exports); // true

重点来了

  • require 是一个普通函数
  • module.exports 是一个普通对象
  • 模块执行是同步的
  • 导出的值是一次性的值拷贝

二、ES Module:语言层面的模块系统

如果说 CommonJS 是“工具方案”,那么 ES Module(ESM)就是 JavaScript 官方给出的答案

ES Module 的核心关键

  • ✅ 官方标准(ECMAScript)
  • ✅ 使用新语法(import / export
  • 所有环境支持(浏览器 / Node / Deno)
  • ✅ 同时支持静态依赖 & 动态依赖
  • 符号绑定

1. 什么是「静态依赖」?

import { a } from './a.js';

这行代码有两个关键点:

  1. import只能写在顶层
  2. 依赖路径在代码运行前就确定

👉 这意味着什么?

  • 构建工具在编译阶段就能分析依赖
  • 支持Tree Shaking
  • 可以做代码分割、预加载

这也是为什么 ESM 更适合前端工程化


2. ESM 也支持动态依赖,但它是异步的

import('./a.js').then(module => {console.log(module.a);
});

和 CommonJS 最大的不同点:

ScreenShot_2026-02-27_141425_020

3. 符号绑定:ESM 最容易被忽略

这是 ESM 和 CommonJS 的本质区别。

看一段代码

// a.js
export var a = 1;
export function changeA() {a = 2;
}
// index.js
import { a, changeA } from './a.js';
console.log(a); // 1
changeA();
console.log(a); // 2

这里为什么 a 会跟着变化?

真相就是 import 不是赋值,而是“引用同一个符号”

在 ESM 中: 导入的不是值,而是对导出符号的实时绑定

可以理解为:

  • a 在模块内部是一个变量
  • 所有 import 的地方,都指向同一个 a
  • 修改它,所有地方同步变化

这就是「符号绑定(Live Binding)」。


对比 CommonJS(非常关键)

// a.js
var n = 1;
function changeN() {n = 2;
}
module.exports = {n,changeN
}// b.js
const { n, changeN } = require('./a.js');
console.log(n); // 1
changeN();
console.log(n); // 1

这里的 n

  • 是一次值拷贝
  • 后续模块内部怎么改,外面都不会同步

4. 再看下 下面几个问题

(1) export 和 export default 的区别

  • export:具名导出,可多个
  • export default:默认导出,只能一个
  • 默认导出本质是 { default: xxx }

(2) 下面代码导出了什么?

exports.a = 'a';
module.exports.b = 'b';
this.c = 'c';
module.exports = {d: 'd'
};
结果:
{ d: 'd' }
(3)下面代码导出了什么?
exports.a = 1;  
exports = { b: 2 };

结果:

{ a: 1 }

原因是:

  • exports 只是 module.exports 的一个引用
  • 当你重新给exports赋值时,只是断开了引用关系module.exports 并没有变
  • 等价于 let exports = module.exports; exports = {}; 只是改了局部变量

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

http://www.jsqmd.com/news/417235/

相关文章:

  • 2026最新新美业抗衰仪器/美业黑科技仪器/智提拉美容仪/AI智能抗衰仪器/抗衰美容仪器推荐:科技赋能抗衰,这家品牌实力出圈 - 十大品牌榜
  • 2026最新植牙五补牙五大医院排名及解析,服务深度覆盖银川、宁夏、贺兰县、兴庆区、金凤区等地 - 十大品牌榜
  • 2026年防晒霜品牌推荐:权威榜单解析与科学选购指南 - 十大品牌推荐
  • 2026年杭州背调公司终极评测(权威机构双重背书)| 企业选型避坑全指南 - 十大品牌推荐
  • 成都环保装修公司实测!4家主流品牌对比,附材料避坑指南 - 品牌测评鉴赏家
  • 成都老房翻新装修公司推荐|2026实测不踩坑,博主亲测整理 - 品牌测评鉴赏家
  • 导师又让重写?8个AI论文平台测评:专科生毕业论文写作全攻略
  • 智能问数Agent上限之争:数据集vs语义层,哪种设计路线更适合你的业务?
  • 2026成都装修公司口碑红黑榜|靠谱选择指南+实力品牌推荐,避坑就看这篇 - 品牌测评鉴赏家
  • MCP、Agent Skills与A2A的定位对比
  • 2026年杭州背调公司推荐:以i背调为代表的标杆企业深度解析 - 十大品牌推荐
  • # 震惊!GPT-5、Gemini Pro还在闭门造车?开源社区已实现惊天逆袭!10款重磅模型颠覆AI格局!
  • 揭秘永辉购物卡回收流程:如何选择平台避免踩坑? - 团团收购物卡回收
  • 2026年防晒霜品牌推荐:多场景深度评测与选购指南,解决防护力与妆效痛点 - 十大品牌推荐
  • AI大模型就业市场2026:AI岗位需求暴涨!年薪百万?大模型工程师成香饽饽,你跟上了吗?
  • 2026年仿竹护栏优质厂家推荐指南定制化设计出众 - 真知灼见33
  • 2026年不锈钢球厂家实力推荐榜:医用/食品级/耐磨/抗酸碱/磁性/醒酒用等全品类深度解析与选购指南 - 品牌企业推荐师(官方)
  • 从零到精通:7步解锁人工智能大模型开发全栈技能!
  • 成都装修探秘:解锁个性化定制的宝藏公司 - 品牌测评鉴赏家
  • NMN精准抗衰哪个牌子好?2026年十大NMN抗衰品牌排行榜,解锁逆龄密码 - 速递信息
  • 2026年杭州背调公司推荐榜单:技术赋能与合规安全双重视角下的行业审视 - 十大品牌推荐
  • 2026新房全案装修哪家好?实测口碑榜+避坑指南,小白直接抄作业 - 品牌测评鉴赏家
  • FER-8;H2N-FEFEFRFK-OH
  • PyTorch机器学习与深度学习:数据清洗、经典机器学习、卷积神经网络、迁移学习、YOLO目标检测与LSTM时间序列预测等掌握AI核心算法!
  • 细聊神八五苔的抛圆硫酸钾靠谱吗,南京市场性价比高吗 - myqiye
  • 云安全服务-分类
  • 东莞卓世橡胶制品专业度如何,推荐选择吗? - mypinpai
  • 亲测好用 9个AI论文工具测评:本科生毕业论文写作必备神器
  • 卡西欧手表批发性价比怎样,靠谱的卡西欧手表批发品牌有哪些? - 工业品牌热点
  • 实测不踩坑|2026专业全案装修品牌推荐,亲测靠谱清单 - 品牌测评鉴赏家