1、CommonJS
CommonJS 是javascript模块化编程的一种规范,主要是在服务器端模块化的规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,在该模块内部定义的变量,无法被其他模块读取,除非定义为global对象的属性。
在CommonJS中有一个全局性方法require( ),用于加载模块。CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD,CMD 解决方案。
2、AMD
CommonJS是主要为了JS在后端的表现制定的,他是不适合前端的。 先分析一下浏览器端的js和服务器端js都主要做了哪些事:
---------------------------------------服务器端JS | 浏览器端JS-------------------------------------------
相同的代码需要多次执行 | 代码需要从一个服务器端分发到多个客户端执行
CPU和内存资源是瓶颈 | 带宽是瓶颈
加载时从磁盘中加载 | 加载时需要通过网络加载 -
于是AMD(异步模块定义)出现了,它就主要为前端JS的表现制定规范。
加载模块是异步方式,模块的加载不影响它后面语句的执行。所有依赖这个模块的语句,都定义到一个回调函数中,等到加载完成之后,这个回调函数才会运行。
AMD规范使用define方法定义模块,通过数组引入依赖 ,回调函数通过形参传入依赖:
define(["/libs/jquery"], function(jquery){
function log(){
alert("hello world!");
}
return {
log: log
}
});
当然AMD也允许输出模块兼容CommonJS规范:
define(function(require, exports, module){
var module = require("module");
module.doSometing( );
exports.do = function(){
module.doSometing( );
}
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出
3、CMD
大名远扬的玉伯写了seajs,就是遵循他提出的CMD规范,与AMD相近,不过用起来感觉更加方便。
CMD和AMD的区别有以下几点:
① 对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
② CMD推崇依赖就近,AMD推崇依赖前置。
//AMD
define(['./a','./b'], function (a, b) {
//依赖一开始就写好
a.test();
b.test();
});
//CMD
define(function (requie, exports, module) {
//依赖可以就近书写
var a = require('./a');
a.test();
...
//软依赖
if (status) {
var b = requie('./b');
b.test();
}
});
虽然 AMD也支持CMD写法,但依赖前置是官方文档的默认模块定义写法。
AMD的api默认是一个当多个用,CMD严格的区分推崇职责单一。例如:AMD里require分全局的和局部的。CMD里面没有全局的 require,提供 seajs.use()来实现模块系统的加载启动。CMD里每个API都简单纯粹。