https://my.oschina.net/felumanman/blog/263330
http://wenku.baidu.com/link?url=PJE5sOrZOEhjdmwhjW_L8sZyzwME9D5m4nVwCjK2Kb0h8si9H7-xXmnDobqj2EdekmGlQ3Za0KZjhnRp6kGYuYfiFcZtW_MMJkjBA8rePi6gnmQ18-F2IifoJDzHHT7C
1、CommonJS
CommonJs 是服务器端模块的规范,Node.js采用了这个规范。随着node.JS的出现,服务器端的模块化显得尤为重要,因为服务器段不需要考虑请求,所以对于依赖模块采用了同步加载。通过定义全局函数require来传入模块标识来引入其他模块,执行结果就是别的模块暴露出来的API,而暴露的API作为exports对象的属性。(即加载模块使用require方法,该方法读取一个文件并执行,最后返回文件内部的exports对象。)根据CommonJS规范,一个单独的文件就是一个模块。CommonJS 加载模块是同步的,所以只有加载完成才能执行后面的操作。像Node.js主要用于服务器的编程,加载的模块文件一般都已经存在本地硬盘,所以加载起来比较快,不用考虑异步加载的方式,所以CommonJS规范比较适用。但如果是浏览器环境,要从服务器加载模块,这是就必须采用异步模式。所以就有了 AMD CMD 解决方案。
//math.js exports.add = function(){ var sum = 0,i=0,args=arguments,l=args.length; while(i<l){ sum += args[i++];} return sum; }
//increment.js var add = require('math').add; exports.increment = function(val){ return add(val,1);};
//program.js var inc = require('increment').increment; var a= 1; inc(a);//2
2、AMD(Asynchromous Module Definition)
AMD((Asynchromous Module Definition,异步模块定义), 是 RequireJS 在推广过程中对模块定义的规范化产出。它的模块支持对象、 函数 、构造器、 字符串 、JSON等各种类型的模块。适用AMD的规范一般用define方法定义模块,并且AMD规范允许输出模块兼容CommonJS规范,这时define方法中可以含有require(),然后淘宝的前端大牛对AMD完善了一下就是CMD
//a.js define(function(){ console.log('a.js执行'); return{ hello:function(){ console.log('hello, a.js'); } } });
//b.js define(function(){ console.log('b.js执行'); return{ hello: function(){ console.log('hello, b.js'); } } });
//main.js
require(['a','b'], function(a,b){
console.log('main.js执行');
a.hello();
$('#b').click(function(){ b.hello(); });
})
3、CMD(Common Module Definition)
CMD是SeaJS 在推广过程中对模块定义的规范化产出
CMD 和 AMD的异同点:
1.对于依赖的模块AMD是提前执行,CMD是延迟执行。不过RequireJS从2.0开始,也改成可以延迟执行(根据写法不同,处理方式不通过)。
2.CMD推崇依赖就近,AMD推崇依赖前置。
虽然 AMD也支持CMD写法,但依赖前置是官方文档的默认模块定义写法。
3.AMD的api默认是一个当多个用,CMD严格的区分推崇职责单一。例如:AMD里require分全局的和局部的。CMD里面没有全局的 require,提供 seajs.use()来实现模块系统的加载启动。CMD里每个API都简单纯粹。
RequireJS 和 Sea.js的异同点:
相同点:RequireJS 和 Sea.js 都是模块加载器,倡导模块化开发理念,核心价值是让 JavaScript 的模块化开发变得简单自然。
不同点:
- 定位有差异。RequireJS 想成为浏览器端的模块加载器,同时也想成为 Rhino / Node 等环境的模块加载器。Sea.js 则专注于 Web 浏览器端,同时通过 Node 扩展的方式可以很方便跑在 Node 环境中。
- 遵循的规范不同。RequireJS 遵循 AMD(异步模块定义)规范,Sea.js 遵循 CMD (通用模块定义)规范。规范的不同,导致了两者 API 不同。Sea.js 更贴近 CommonJS Modules/1.1 和 Node Modules 规范。
- 推广理念有差异。RequireJS 在尝试让第三方类库修改自身来支持 RequireJS,目前只有少数社区采纳。Sea.js 不强推,采用自主封装的方式来“海纳百川”,目前已有较成熟的封装策略。
- 对开发调试的支持有差异。Sea.js 非常关注代码的开发调试,有 nocache、debug 等用于调试的插件。RequireJS 无这方面的明显支持。
- 插件机制不同。RequireJS 采取的是在源码中预留接口的形式,插件类型比较单一。Sea.js 采取的是通用事件机制,插件类型更丰富。
4、UMD(Universal Module Definition)
umd是AMD和CommonJS的糅合
AMD 浏览器第一的原则发展 异步加载模块。
CommonJS 模块以服务器第一原则发展,选择同步加载,它的模块无需包装(unwrapped modules)。
这迫使人们又想出另一个更通用的模式UMD (Universal Module Definition)。希望解决跨平台的解决方案。
UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式。
在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。