← [ BACK_TO_NOTES ]

CommonJS / AMD / UMD

CommonJS、AMD、UMD 三种历史模块系统的关系与适用场景。

#synthesis #dev #growing #javascript #nodejs #browser

[!info] related notes

CommonJS / AMD / UMD

一句话定义

  • CommonJS (CJS):Node.js 的同步模块系统,用 require() 导入、module.exports 导出。
  • AMD:浏览器端的异步模块系统,用 define() 定义模块。
  • UMD:同时兼容 CJS 和 AMD 的通用包装模式,用于库发布。

CommonJS 与 AMD 的边界

CommonJS 在 Node 中通过同步 require() 返回 module.exports,并按解析后的文件名缓存。语法、对象共享、exports 重绑定与循环依赖细节统一在该概念页维护。

AMD 为异步加载依赖提供声明接口,常用于由 RequireJS 等加载器管理的旧浏览器工程。两者的 require 不是同一个接口:Node 通常接收模块标识符并返回导出值;RequireJS 可接收依赖数组并在回调里交付依赖。

AMD 详解

// 定义模块
define('math', ['dep1', 'dep2'], function(dep1, dep2) {
  return {
    add: function(a, b) { return a + b; }
  };
});

// 匿名模块(更常见)
define(['jquery'], function($) {
  return function(selector) {
    return $(selector);
  };
});

// RequireJS 加载
require(['math'], function(math) {
  console.log(math.add(1, 2));
});

特点:

  • 异步加载,为浏览器设计(网络请求不能阻塞)。
  • define(deps, callback) 显式声明依赖。
  • 依赖加载完成后才执行回调,避免运行时找不到模块。
  • RequireJS 是常见的 AMD 加载器;浏览器本身不提供 define。

UMD 包装模式

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD 环境(RequireJS)
    define(['jquery'], factory);
  } else if (typeof module === 'object' && module.exports) {
    // CommonJS 环境(Node.js)
    module.exports = factory(require('jquery'));
  } else {
    // 浏览器全局变量
    root.MyLib = factory(root.jQuery);
  }
}(typeof self !== 'undefined' ? self : this, function($) {
  return { init: function() { /* ... */ } };
}));

特点:

  • 不是新模块系统,是兼容包装模式。
  • 检测当前环境,选择对应的模块加载方式。
  • 今天主要在 npm 包的 UMD 构建产物中看到(如 dist/lib.umd.js)。

今天怎么选

场景推荐
新项目ESM(import / export)
Node.js 遗留代码CJS,逐步迁移 ESM
库发布(需要普通 script 全局变量)提供 UMD 或 IIFE 构建;ESM + CJS 双产物本身不提供全局入口
读老代码 / 打包产物理解 CJS / AMD / UMD 即可

ESM 迁移注意事项

  • Node.js 中启用 ESM:"type": "module" in package.json 或使用 .mjs 扩展名。
  • 原生 Node ESM 没有内置 require 变量;需要时从 node:module 导入 createRequire 并用 createRequire(import.meta.url) 创建。
  • ESM 的静态 import 声明只能在模块顶层;条件加载可以用 import() 表达式,CJS 的 require() 也可以在条件分支中调用。
  • 混用 CJS 和 ESM 时注意循环依赖行为的差异。

学习检查

  • AMD 的加载器与 UMD 的环境检测分别负责什么?
  • 为什么 ESM + CJS 双产物不能直接替代普通 script 的全局入口?
创建于 2025/1/1 更新于 2026/10/6
Digital Biome
Access

键盘导航

j / k / ↑ / ↓
选择对象
Enter / o
打开选择
/ 或 Ctrl+K
全站搜索
i / f / 1–4
筛选当前列表
g → h / l / p / t / a
首页 / 笔记 / 项目 / 工具 / About
r → 1–9
打开所选对象的关联
u
返回上一页
Esc
关闭浮层 / 取消命令;输入框内清空文本