1. Javascript 先天缺乏模块的功能。在其他高级语言中,Java有类文件,Python有import机制,Ruby有require,PHP有include和require,而Javascript 则需要依靠<script>标签引入代码,当脚本多的时候,会显得杂乱无章。
2. 针对以上问题,CommonJS应运而生。CommonJS为Javascript制定了一个美好愿景:能够在任何地方运行!(Not just for browser), CommonJS希望弥补Javascript没有标准的缺陷(没有模块系统,标准库较少,没有标准接口,缺乏包管理系统),可以编写大型应用,如服务器端Javascript,命令行工具,桌面图形界面应用程序,混合应用等。
3. CommonJS规范涵盖:
模块、二进制Buffer, 字符集编码,I/O流,进程环境,文件系统,套接字,web服务器网管接口,包管理等。
4. Node.JS遵循CommonJS规范,推进了CommonJS的发展.
5. CommonJS主要是为了JS在后端的表现制定的,不适合前端。为什么这么说呢?
前后端Javascript分别被搁置在HTTP的两端,二者扮演的角色不同:
浏览器端Javascript | 服务器端Javascript | |
代码的执行 | 需要经历从同一服务器端分发到多个客户端执行 | 相同代码需要多次执行 |
瓶颈 | 在于带宽 | 在于CPU和内存资源 |
代码加载方式 | 需要通过网络加载代码 | 从磁盘加载代码(二者速度不在一个数量级上) |
6. 于是AMD出现了,Asynchronous Module Definition. 异步模块定义。
它就主要为前端JS的表现制定规范。
AMD规范只有一个API,其模块定义如下:
define(id?,dependencies?,factory); //id,dependencies可选,factory内容就是实际代码的内容。
a. Id:模块标识,可以省略,这里的模块标识指的是自己,即整个文件。所以当id省略的时候,就相当于定义了一个匿名模块,这时候模块文件名就是 模块标识。e.g.模块文件放在a.js中,那么a就是模块名。
b. dependencies: 依赖的模块。AMD规范要在声明模块的时候指定所有的依赖,并且还要当做形参传到factory里面。例如:
define(['dep1', 'dep2'], function ( dep1, dep2 ){ … });
一个不包含依赖关系的例子:
define(function(){
var exports = {};
exports.method = function(){ ...};
return exports;
...
});
c. 从define函数中不难想到define函数具有异步性。它在执行时首先会异步去调用第二个参数中列出的依赖模块,当所有模块被载入完成后,如果第三个参数是一个回调函数则执行。
d. 在Node.js中,没有看到define将模块包起来,是因为Node实现了隐式包装(即在对模块进行 编译时,node会对模块进行头尾包装,以隔离各个模块文件,防止变量污染)。
e. requireJS就是实现了AMD规范。
7. CMD规范由国内的玉伯提出,与AMD规范的区别在于定义模块和依赖引入的部分。风格更接近于Node.可以看看Sea.js。