CommonJS、ES Module(ESM)、AMD、UMD、IIFE 等模块系统的区别

218 阅读2分钟

对比讲解: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 模块化的主要方式

🧩 总结对比表:

特性CommonJSES ModuleAMDUMDIIFE
语法require/exportimport/exportdefine多种兼容无模块语法
加载方式同步异步(静态)异步兼容所有立即执行
使用场景Node.js现代浏览器/Node浏览器通用库发布早期浏览器
Tree Shaking
支持平台Node.js浏览器+Node浏览器全平台浏览器

🧠 项目实战建议:

  • 现代项目:使用 ES Module

    • import/export 语法
    • 更利于 Tree Shaking、类型支持、异步加载
  • Node 项目:逐步迁移 ESM

    • Node 14+ 支持 "type": "module" 可用 ESM
  • 库开发:打包成 UMD / ESM 兼容格式

    • 发布库时用 Rollup/Vite/tsup 输出多格式