模块化是将代码拆分为独立、可复用、有明确输入输出的小单元;CommonJS 同步加载、支持运行时动态引入但导出值拷贝且不支持 tree-shaking;ESM 是官方标准,静态声明、导出引用、支持异步加载和编译期优化。

模块化就是把代码拆成独立、可复用、有明确输入输出的小单元,每个文件管好自己的事,不互相污染。
CommonJS 是 Node.js 早期的模块方案
它用 同步加载,靠 require() 引入,module.exports 导出。模块第一次加载后会缓存,后续再 require 直接返回缓存结果。
- 可以在 if、函数里随时
require,运行时决定要不要加载 - 导出的是值的拷贝,改了原始值,已导入的地方看不到变化
- 路径可以是变量或拼接字符串,比如
require('./' + name) - 不支持编译期优化,像 tree-shaking 这类静态分析做不了
ES 模块(ESM)是 JavaScript 官方标准
它用 静态声明,靠 import 和 export,必须写在文件顶层,不能放在条件或函数里。
-
浏览器和现代 Node.js 都原生支持,需加
.js后缀(如import './util.js') - 导出的是值的引用,原始值变了,所有导入处都能看到更新
- 依赖关系在代码运行前就确定了,能做 tree-shaking、自动代码分割等优化
- 支持异步加载:
import('./module.js')返回 Promise,适合懒加载
实际开发中怎么选
新项目统一用 ESM —— 语法更清晰、工具链支持好、是语言标准。Node.js 从 v14 开始稳定支持 ESM,只需加 "type": "module" 或用 .mjs 后缀。
立即学习“Java免费学习笔记(深入)”;
- 混用要注意:CommonJS 里
require一个 ESM 文件会报错;ESM 中也不能直接importCommonJS 的module.exports对象(但 Node.js 有兼容层,通常能转成命名空间对象) - 动态导入统一用
import(),它在两种环境都可用,返回 Promise - 打包工具如 Vite、Webpack 默认按 ESM 处理,遇到
require会尝试兼容,但建议逐步迁出
基本上就这些。











