对比讲解:CommonJS、ES Module(ESM)、AMD、UMD、IIFE 等模块系统的区别和应用场景。
✅ 1. CommonJS(Node.js 的模块规范)
📌 特点:
- 同步加载(适合服务端 Node)
require()引入模块module.exports/exports导出模块- 加载的是对象的拷贝(缓存)
// foo.js
const name = 'dazhaung';
module.exports = { name };
// bar.js
const foo = require('./foo');
console.log(foo.name);
📦 应用:
- Node.js 默认使用的模块系统
- webpack 默认支持(但建议使用 ESM)
✅ 2. ES Module(ESM,ES6 模块)
📌 特点:
- 静态分析:编译时确定依赖关系
- 异步加载
- 支持 Tree Shaking(更易于打包优化)
- 使用
import/export语法
// foo.js
export const name = 'ChatGPT';
// bar.js
import { name } from './foo.js';
console.log(name);
📦 应用:
- 浏览器原生支持
<script type="module"> - 现代前端工具默认(如 Vite、ESBuild、Webpack 5)
- Node.js 也支持(需设置
"type": "module")
✅ 3. AMD(Asynchronous Module Definition)
📌 特点:
- 异步加载
- 用于浏览器环境
- 典型库:RequireJS
define(['module1', 'module2'], function (m1, m2) {
// 使用 m1、m2
});
📦 应用:
- 曾经解决浏览器模块化的方案,现在已基本被淘汰
✅ 4. UMD(Universal Module Definition)
📌 特点:
- 兼容 CommonJS、AMD、浏览器全局变量
- 用于发布库
(function (root, factory) {
if (typeof module === 'object' && module.exports) {
module.exports = factory();
} else if (typeof define === 'function' && define.amd) {
define(factory);
} else {
root.myLib = factory();
}
})(this, function () {
return { name: 'chatgpt' };
});
📦 应用:
- 库的发布格式,例如 lodash、axios 早期版本
✅ 5. IIFE(立即执行函数表达式)
📌 特点:
- 最早期模块方案,无模块系统
- 使用闭包封装作用域
(function () {
const name = 'chatgpt';
console.log(name);
})();
📦 应用:
- ES6 之前,JS 模块化的主要方式
🧩 总结对比表:
| 特性 | CommonJS | ES Module | AMD | UMD | IIFE |
|---|---|---|---|---|---|
| 语法 | require/export | import/export | define | 多种兼容 | 无模块语法 |
| 加载方式 | 同步 | 异步(静态) | 异步 | 兼容所有 | 立即执行 |
| 使用场景 | Node.js | 现代浏览器/Node | 浏览器 | 通用库发布 | 早期浏览器 |
| Tree Shaking | ❌ | ✅ | ❌ | ❌ | ❌ |
| 支持平台 | Node.js | 浏览器+Node | 浏览器 | 全平台 | 浏览器 |
🧠 项目实战建议:
-
现代项目:使用 ES Module
import/export语法- 更利于 Tree Shaking、类型支持、异步加载
-
Node 项目:逐步迁移 ESM
- Node 14+ 支持
"type": "module"可用 ESM
- Node 14+ 支持
-
库开发:打包成 UMD / ESM 兼容格式
- 发布库时用 Rollup/Vite/tsup 输出多格式