异步模块定义(Asynchronous Module Definition,简称 AMD)API 描述了一种定义模块的机制,模块及其依赖模块可以通过这种机制进行加载。该机制特别适用于浏览器。

本规范曾被称为 Modules Transport/C,但本规范主要不是用来传输已有的 CommonJS 模块,而是用来定义模块。

规范正文

define 函数

本规范只定义了一个函数 define,该函数是一个自由变量,或者说是一个全局变量。函数签名如下:

define(id?, dependencies?, factory);

第一个参数 id 指定了即将定义的模块的 id。该参数是可选的,如果未指定该参数,则模块的 id 默认为模块加载器请求该脚本时使用的模块 id。如果指定该参数,参数值必须是一个绝对 id(不允许使用相对 id)。

第二个参数 dependencies 是一个数组,包含即将定义的模块所有依赖模块名称。依赖模块必须在执行工厂函数之前完成解析,解析结果作为参数传递给工厂函数,工厂函数的参数顺序与 dependencies 参数所包含依赖模块顺序保持一致。依赖模块 id 可以为相对 id,所谓相对是指相对于即将定义的模块而言。如果 dependencies 中出现 require, exports 或 module 字样,则对应的参数应被解析为 CommonJS 模块规范中所定义的自由变量 require, exports 或 module。dependencies 参数是可选的,该参数缺省值为 ["require", "exports", "module"]。如果工厂函数的参数列表长度小于 3,那么加载器可以选择使用工厂函数参数列表长度所对应的 dependencies 参数来调用工厂函数。

第三个参数 factory 是一个函数,它用来初始化一个模块或对象。如果 factory 是一个函数,那它应该只被执行一次。如果 factory 是一个对象,那么它应该作为模块的输出物进行赋值。

如果 id 和 dependencies 全部缺省,则模块加载器应扫描工厂函数体中包含的 require 语句来确定依赖模块。为此,工厂函数的第一个参数应命名为 "require"。某些情况下加载器可以选择不去扫描依赖模块,例如代码大小限制,或者函数对象缺少 toString 方法。只要 id 或 dependencies 有一个被指定实参,则加载器就不应再扫描工厂函数来确定依赖模块。

define.amd 属性

为了能够清楚表明当前全局函数 define 是否符合 AMD API,任何一个全局函数 define 都应拥有一个 amd 属性,该属性值为一个对象。这样可以避免现有的 Javascript 代码中存在的全局函数 define 不符合 AMD API 的冲突。

define.amd 对象应拥有的属性不在本规范中给出说明。实现了 AMD API 的作者可以利用 amd 属性来通知别人,他的实现中除了基本的 AMD API,还额外提供了什么支持。

define.amd 属性表明当前 AMD 实现符合本规范所定义的 API。如果还有另一个版本的 API,那么将在 define 函数上添加另一个属性,例如 define.amd2 来表示该实现符合另一个版本的 API。

以下示例想要说明某个实现支持加载多个版本的模块:

define.amd = {
multiversion: true
};

最简单的定义:

define.amd = {};

一次传输多个模块

一个脚本中可以多次调用 define 函数,define 函数的调用顺序不影响大局。先定义的模块可以指定后定义的模块作为依赖模块。模块加载器负责延迟加载未解析的依赖模块直到整个脚本都加载完毕,以此来阻止非必要的请求。

示例

使用 require 和 exports

定义一个 id 为 "alpha" 的模块,它有一个依赖模块 beta。

define("alpha", ["require", "exports", "beta"], function (require, exports, beta) {
exports.verb = function () {
return beta.verb();
}
});

定义一个匿名模块,模块的 id 来自于源文件名。

define(['alpha'], function (alpha) {
return {
verb: function () {
return alpha.verb() + 2;
}
};
});

定义一个自由模块(没有依赖其他模块)。

define({
add: function (x, y) {
return x + y;
}
});

全局变量

本规范保留了全局变量 define,*包的元数据异步定义 API and 作为保留关键字以备未来其他 CommonJS API 使用。模块加载器不应该在此函数上添加额外的方法或属性。

本规范保留了全局变量 require 提供给模块加载器使用。模块加载可以自由使用该全局变量,它们可以使用该变量,并向该变量添加属性或函数,甚至可以选择不使用 require。

备注

define 函数的调用推荐使用 define(...) 的形式,以便静态分析工具可以顺利工作。

本规范曾使用 require.def() 作为入口方法。模块加载器可以将 define() 设置为 require.def() 的别名以向后兼容。


PS:本规范从 CommonJS 官方英文版本转译而来,斜体部分表示译文存在商榷。

Ref:

CommonJS Asynchronous Module Definition

CommonJS 的 AMD 规范的更多相关文章

  1. javascript模块化编程:CommonJS和AMD规范

    AMD规范,异步模块定义.与CommonJS规范齐名并列. 作用都是利于JavaScript的模块化编程. 模块化编程的好处就是: 1.可重用 2.独立 3.能解决加载的依赖性问题 4.能解决重复加载 ...

  2. 前端模块化IIFE,commonjs,AMD,UMD,ES6 Module规范超详细讲解

    目录 为什么前端需要模块化 什么是模块 是什么IIFE 举个栗子 模块化标准 Commonjs 特征 IIFE中的例子用commonjs实现 AMD和RequireJS 如何定义一个模块 如何在入口文 ...

  3. 浅析JS中的模块规范(CommonJS,AMD,CMD)

    如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已. 现在就看看吧,这些规范到底是啥东西,干嘛的. 一.CommonJS ...

  4. 浅析JS中的模块规范(CommonJS,AMD,CMD)////////////////////////zzzzzz

    浅析JS中的模块规范(CommonJS,AMD,CMD)   如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已.     ...

  5. Javascript模块规范(CommonJS规范&&AMD规范)

    Javascript模块化编程(AMD&CommonJS) 前端模块化开发的价值:https://github.com/seajs/seajs/issues/547 模块的写法 查看 AMD规 ...

  6. JS模块化规范CommonJS,AMD,CMD

    模块化是软件系统的属性,这个系统被分解为一组高内聚,低耦合的模块.理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过直接加载被人已经写好模块进行使用即可.一个模块化系统所必须的 ...

  7. JS中的模块规范(CommonJS,AMD,CMD)

    JS中的模块规范(CommonJS,AMD,CMD) 如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范咯,我也听过,但之前也真的是听听而已. 现在就看看吧, ...

  8. CommonJs、AMD、CMD模块化规范

    /** * CommonJS 模块化规范 * CommonJS规范加载模块是同步的,也就是说,只有加载完成,才能执行后面的操作 */ /*-------Node.js遵循Commonjs规范----- ...

  9. 学习笔记:CommonJS规范、AMD规范

    CommonJS规范 http://wiki.jikexueyuan.com/project/webpack-handbook/commonjs.html CommonJS 规范 http://www ...

随机推荐

  1. paip.提升稳定性---c3p0数据库连接池不能取到连接An attempt by a client to checkout a Connection has timed out

    paip.提升稳定性---c3p0数据库连接池不能取到连接An attempt by a client to checkout a Connection has timed out 作者Attilax ...

  2. eclipse 打开是报错"reload maven project has encountered a problem"

    不需要删除整个 .metadata 如果删除这个代价是重新导入全部项目 D:\eclipse-workspace\.metadata\.plugins\org.eclipse.e4.workbench ...

  3. Python之Django【进阶篇 】

    Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接数据库,并编写数据访问层代码 业务逻辑层去调用数据访问层执行 ...

  4. ooj1057: M的整数倍DP

    http://121.249.217.157/JudgeOnline/problem.php?id=1057 1057: M的整数倍 时间限制: 1 Sec  内存限制: 64 MB提交: 130   ...

  5. 解决ASP.NET在IE10中Session丢失问题【转】

    今天发现在IE10中登录我公司的一个网站时,点击其它菜单,页面总会自动重新退出到登录页,后检查发现,IE10送出的HTTP头,和.AUTH Cookie都没问题,但使用表单验证机制(FormsAuth ...

  6. ie8下jquery改变PNG的opacity出现黑边,ie6下png透明解决办法

    目前互联网对于网页效果要求越来越高,不可避免的用到PNG图片,PNG分为几种格 式,PNG8 PNG24 PNG32,其中最常用的,也是显示效果和大小比较适中的则是PNG24,支持半透明,透明,颜色也 ...

  7. JavaScript 调试小技巧

    'debugger;' 除了console.log,debugger就是另一个我很喜欢的快速调试的工具,将debugger加入代码之后,Chrome会自动在插入它的地方停止,很像C或者Java里面打断 ...

  8. paypal之nodejs 框架 Kraken-js 源码分析

    本文是基于 kraken-js 0.6.1 版本的 关于如何使用kraken-js 可以去看看官网的使用文档 点击这里 .kraken-js 是基于express之上的,目的在于让工程师更多的去关注代 ...

  9. python在windows平台的pip安装package时的编译问题

    在安装pcapy时,出现以下错误: building 'pcapy' extension error: Microsoft Visual C++ 9.0 is required (Unable to ...

  10. 笔记 - 本地拦截genymotion或者Android模拟器的网络请求

    我们在主机上面运行了Burp或者fiddler,那么代理已经监听在本机的8080端口了. 那么我们需要在模拟器中进行如下设置: 1.在设置中,长按当前连接的wifi网络,弹出如下: 2. 点击修改网络 ...