对AMD,CMD,CommonJs的理解

对AMD,CMD,CommonJs的理解

AMD规范即异步模块加载机制。从规范描述页面看,AMD很短也很简单,但却完整描述了模块的定义,依赖关系,引用关系以及加载机制。 AMD规范其实只有一个主要接口 define(id,dependencies,factory),它要在声明模块的时候指定所有的依赖dependencies,并且还要当做形参传到factory中,对于依赖的模块提前执行,依赖前置

1
2
3
4
1.	   define("module", ["dep1", "dep2"], function(d1, d2) {  
2. return someExportedValue;
3. });
4. require(["module", "../file"], function(module, file) { /* ... */ });

优点:1、适合在浏览器环境异步加载2、并行加载多个模块
缺点:1、提高开发成本,代码阅读和书写比较困难2、不符合通用的模块思维方式,是一种妥协的实现
实现:requireJS,NodeJs,Dojo,JQuery
CMD规范和AMD相似,尽量保持简单,并且与CommonJSNodeJSModules规范保持了很大的兼容性。在CMD中,一个模块就是一个文件,格式为:define( factory )

1
2
3
4
6.	define("module", ["dep1", "dep2"], function(d1, d2) {  
7. return someExportedValue;
8. });
9. require(["module", "../file"], function(module, file) { /* ... */ });

优点:1、依赖就近,延迟执行2、很容易在node中运行
缺点:1、依赖SPM打包,模块的加载逻辑偏重
实现:SeaJS
CommonJS是在浏览器环境之外构建JavaScript生态系统为目标产生的项目,比如服务器和桌面环境中。CommonJS规范是为了解决JavaScript的作用域问题而定义的模块形式,可以使每个模块在它自身的命名空间中执行。该规范的主要内容是:模块必须通过 module.exports导出对外的变量或接口,通过require()来导入其他模块的输出到当前模块。

1
2
3
4
5
6
7
8
10.	// moduleA.js  
11. module.exports = function( value ){
12. return value * 2;
13. }

14. // moduleB.js
15. var multiplyBy2 = require('./moduleA');
16. var result = multiplyBy2(4);

CommonJS是同步加载模块,一个单独的文件就是一个模块。但其实也有浏览器端的实现,其原理是将所有模块都定义好并通过id进行索引,这样就可以浏览器进行解析了 服务器端的Node.js遵循CommonJS规范。核心思想是允许模块通过require 方法来同步加载所要依赖的其他模块,然后通过 exportsmodule.exports来导出需要暴露的接口。

1
2
3
4
17.	require("module");  
18. require("../file.js");
19. exports.doStuff = function() {};
20. module.exports = someValue;

优点:1、服务器端便于重用2、NPM中已经将近20w个模块包3、简单并容易使用
缺点:1、同步的模块方式不适合在浏览器环境中,同步意味着阻塞加载,浏览器资源是异步加载的2、不能非阻塞的并行加载多个模块
区别:(AMD or CMD)
1 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.
2 CMD 推崇依赖就近,AMD 推崇依赖前置
3 AMDAPI 默认是一个当多个用,CMDAPI 严格区分,推崇职责单一。
4 CMD相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;而AMD则相反,定义模块的时候需要制定依赖模块。

为什么要模块化?不用的时候和用RequireJS的时候代码该如何书写

1 方便大量的js脚本代码的管理维护以及团队配合开发
2 有效解决命名空间冲突及文件依赖加载顺序问题
3 有利于模块的版本管理,提高可维护性,有利于前端性能优化,跨环境共享模块

同步和异步模块化的应用场景,AMD异步模块化实现的原理

引入JS时会遇到需要异步加载文件,此时require.async便可满足异步加载需求

-------------本文结束感谢您的阅读-------------