AMD是专为浏览器设计的异步JavaScript模块规范,通过define定义依赖前置、异步加载的模块,require.js为其主流实现,适合无打包环境的大型前端项目。

AMD(Asynchronous Module Definition)是一种为浏览器环境设计的 JavaScript 模块规范,核心目标是解决传统 script 标签加载模块时的依赖顺序、全局污染和同步阻塞问题。它不依赖构建工具,原生支持异步加载、依赖前置声明和模块隔离,适合大型前端项目在无打包环境下的运行。
AMD 的基本语法与模块定义
AMD 通过 define 函数定义模块,接收三个可选参数:模块名(可省略)、依赖数组、工厂函数。工厂函数在所有依赖加载完成后执行,返回模块导出值。
示例:
define(['./util', 'jquery'], function(util, $) {
return {
init: function() {
console.log('Module loaded with', $.fn.jquery);
return util.helper();
}
};
});
关键点:
立即学习“Java免费学习笔记(深入)”;
- 依赖路径支持相对路径(如 './util')和简写 ID(如 'jquery',需提前配置映射)
- 工厂函数参数顺序必须与依赖数组严格对应
- 模块仅执行一次,返回值被缓存,后续 require 获取的是同一引用
require.js:最主流的 AMD 加载器实现
RequireJS 是 AMD 规范的事实参考实现,通过动态创建 script 标签并监听 onload 事件完成异步加载。它维护内部模块注册表,按依赖图拓扑排序执行模块。
使用前需先加载 require.js,并通过 data-main 指定入口模块:
<script src="require.js" data-main="main.js"></script>
入口文件 main.js 中调用 require 启动应用:
require(['app/main'], function(Main) {
Main.start();
});
RequireJS 还支持:
- 配置路径别名:避免长路径,如 paths: { 'lodash': 'libs/lodash.min' }
- Shim 配置:为非 AMD 脚本(如 jQuery 插件)声明依赖和导出变量
- 插件加载:如 'text!template.html' 加载文本资源
浏览器端异步加载的关键机制
AMD 的“异步”不是指单个请求的异步(script 标签本身已是异步),而是指依赖关系驱动的按需、并发、无阻塞加载与执行调度。
具体流程如下:
- 解析 define/require 中的依赖数组,生成模块依赖图
- 对每个未加载模块,动态插入 <script src="..."> 标签
- 利用 script 标签的 onload 或 onreadystatechange 回调判断加载完成
- 当某模块所有依赖均已就绪且自身脚本执行完毕,才执行其工厂函数
- 模块输出被缓存,重复 require 直接返回缓存值,不重新加载或执行
这种机制天然规避了传统方式中因 script 顺序错误导致的 ReferenceError,也避免了全局变量冲突。
与 CommonJS 和 ES Module 的对比要点
AMD 不是通用模块标准,而是专为浏览器早期无原生模块能力时代设计的折中方案:
- CommonJS(Node.js):同步 require,适用于服务端文件系统;浏览器需配合打包工具(如 Browserify)转换
- ES Module(import/export):现代浏览器原生支持,静态分析依赖,但默认只支持 HTTP/2 推送或本地文件协议外的 CORS 加载,且不支持运行时路径拼接
- AMD:纯客户端、完全异步、运行时路径解析灵活,适合老项目、CDN 场景或需按需加载大量第三方库的管理后台
如今新项目普遍采用 ES Module + 构建工具,但 AMD 仍在部分遗留系统、微前端子应用隔离、或 RequireJS 生态(如 Dojo 1.x)中持续发挥作用。


















