本章将深入探讨 AMD 规范的核心思想、API 设计和实际应用。主要内容包括:
define() 和 require() 两个核心函数的语法和用法。AMD 规范的核心在于通过全局函数 define 来定义模块,以及通过 require 来加载模块。
define 函数define 函数用于定义一个模块,其基本语法为:
define(id?, dependencies?, factory);id (可选): 字符串类型,表示模块的名称。通常在打包优化时由工具自动生成,不建议手动指定。dependencies (可选): 字符串数组,列出了当前模块所依赖的其他模块。factory: 工厂函数或对象。模块的主体内容。如果为函数,其参数与 dependencies 数组中的模块一一对应,函数的返回值即为该模块的导出值。require 函数require 函数用于在顶层加载模块并执行回调。它通常作为应用的入口点。
require(dependencies, callback)dependencies: 需要加载的模块数组。callback: 依赖加载完成后执行的回调函数,其参数是加载的模块实例。math.js)此模块不依赖任何其他模块,直接通过 factory 函数返回一个对象作为导出接口。
// file: js/modules/math.js
define(function () {
console.log("math.js is loaded")
const add = (a, b) => a + b
const subtract = (a, b) => a - b
// 返回的对象就是模块的导出值
return {
add: add,
subtract: subtract
}
})math.js 的计算器模块 (calculator.js)此模块声明了对 './math' 的依赖,factory 函数的参数 math 即为 math.js 模块的导出对象。
// file: js/modules/calculator.js
define(["./math"], function (math) {
console.log("calculator.js is loaded")
const doubleAdd = (a, b) => math.add(a, b) * 2
return {
doubleAdd: doubleAdd
}
})main.js) 中使用模块使用 require 作为入口,加载 calculator.js,并在回调函数中使用它。
// file: js/main.js
require(["./modules/calculator"], function (calculator) {
console.log("main.js execution started")
const result = calculator.doubleAdd(5, 10)
console.log("Result is:", result) // 输出: Result is: 30
})适用场景: AMD 特别适合于那些需要在浏览器端异步按需加载大量 JavaScript 模块的复杂 Web 应用。在 ES Modules 普及之前,它是构建大型单页应用(SPA)的主流选择之一。
最佳实践:
baseUrl 和 paths 配置来管理模块的路径,避免硬编码相对路径。| 特性 | AMD (Asynchronous Module Definition) | CommonJS | ES Modules (ESM) |
|---|---|---|---|
| 语法 | define() / require() | require() / module.exports | import / export |
| 加载方式 | 异步加载 | 同步加载 | 异步加载 |
| 依赖时机 | 依赖前置 (在执行 factory 前加载所有依赖) | 运行时加载 (执行到 require 时才加载) | 静态解析 (在编译时确定依赖关系) |
| 值绑定 | 值的拷贝或引用 (取决于 factory 返回) | 值的拷贝 (原始类型) / 引用 (对象) | 动态只读引用 (Live Binding) |
| 适用环境 | 浏览器 (通过加载器) | Node.js (原生) | 现代浏览器 (原生)、新版 Node.js |