您好,欢迎访问一九零五行业门户网

JavaScript模块规范之AMD规范和CMD规范_javascript技巧

模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问题进行系统性的分解以之处理。模块化是一种处理复杂系统分解为代码结构更合理,可维护性更高的可管理的模块的方式。可以想象一个巨大的系统代码,被整合优化分割成逻辑性很强的模块时,对于软件是一种何等意义的存在。对于软件行业来说:解耦软件系统的复杂性,使得不管多么大的系统,也可以将管理,开发,维护变得“有理可循”。
还有一些对于模块化一些专业的定义为:模块化是软件系统的属性,这个系统被分解为一组高内聚,低耦合的模块。那么在理想状态下我们只需要完成自己部分的核心业务逻辑代码,其他方面的依赖可以通过直接加载被人已经写好模块进行使用即可。
一、amd
amd就只有一个接口:define(id?,dependencies?,factory);
它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:
复制代码 代码如下:
define(['dep1','dep2'],function(dep1,dep2){...});
要是没什么依赖,就定义简单的模块,下面这样就可以啦
define(function(){ var exports = {}; exports.method = function(){...}; return exports;});
这里有define,把东西包装起来,那node实现中怎么没看到有define关键字呢,它也要把东西包装起来,其实,只是node隐式包装了而已..
requirejs就是实现了amd规范的
二、cmd
玉伯写了seajs,就是遵循他提出的cmd规范,比amd稍微强大点,用起来感觉也方便些
三、amd与cmd的区别
cmd相当于按需加载,定义一个模块的时候不需要立即制定依赖模块,在需要的时候require就可以了,比较方便;而amd则相反,定义模块的时候需要制定依赖模块,并以形参的方式引入factory中
//amd方式定义模块
define(['dep1','dep2'],function(dep1,dep2){ //内部只能使用制定的模块 return function(){};});
//cmd
define(function(require,exports,module){ //此处如果需要某xx模块,可以引入 var xx=require('xx');});
而seajs也有use功能也是需要先引入所有依赖的模块,如
//seajs.use方式seajs.use(['dep1','dep2'],function(dep1,dep2){ //这里实现事务});
四、插件支持
但全球有两种比较流行的 javascript 模块化体系,一个是 node 实现的 commonjs,另外一个是 amd。很多类库都同时支持 amd 和 commonjs,但是不支持 cmd。或许国内有很多 cmd 模块,但并没有在世界上流行起来。
现在比较火的 react 及周边类库,就是直接使用 commonjs 的模块体系,使用 npm 管理模块,使用 browserify 打包输出模块。
不久的将来 es6 中新的模块化标准,可能就都得遵循新的标准了,什么amd、cmd可能到时也不会怎么用了。
但是目前来说,前端开发没有用模块化编程就真的out的了,而目前的模块化编程,本人还是建议用seajs,虽然很多插件需要追加或修改一小块代码才能支持。但改过一次就能反复使用,也不会影响其它标准的支持。总体还算是比较方便实用的。
单独解释amd 与 cmd 区别到底在哪里?
看了以上 amd,requirejs 与 cmd, seajs的简单介绍会有点感觉模糊,总感觉较为相似。因为像 requirejs 其并不是只是纯粹的amd固有思想,其也是有cmd规范的思想,只不过是推荐 amd规范方式而已, seajs也是一样。
下面是玉伯对于 amd 与 cmd 区别的解释:
amd 是 requirejs 在推广过程中对模块定义的规范化产出。
cmd 是 seajs 在推广过程中对模块定义的规范化产出。
类似的还有 commonjs modules/2.0 规范,是 bravojs 在推广过程中对模块定义的规范化产出还有不少??
这些规范的目的都是为了 javascript 的模块化开发,特别是在浏览器端的。
目前这些规范的实现都能达成浏览器端模块化开发的目的。
区别:
1. 对于依赖的模块,amd 是提前执行,cmd 是延迟执行。不过 requirejs 从 2.0 开始,也改成可以延迟执行(根据写法不同,处理方式不同)。cmd 推崇 as lazy as possible.
2. cmd 推崇依赖就近,amd 推崇依赖前置。看代码:
// cmd
define(function(require, exports, module) { var a = require('./a') a.dosomething() // 此处略去 100 行 var b = require('./b') // 依赖可以就近书写 b.dosomething() // ...})
// amd 默认推荐的是
define(['./a', './b'], function(a, b) { // 依赖必须一开始就写好 a.dosomething() // 此处略去 100 行 b.dosomething() // ...})
虽然 amd 也支持 cmd 的写法,同时还支持将 require 作为依赖项传递,但 requirejs 的作者默认是最喜欢上面的写法,也是官方文档里默认的模块定义写法。
3. amd 的 api 默认是一个当多个用,cmd 的 api 严格区分,推崇职责单一。比如 amd 里,require 分全局 require 和局部 require,都叫 require。cmd 里,没有全局 require,而是根据模块系统的完备性,提供 seajs.use 来实现模块系统的加载启动。
cmd 里,每个 api 都简单纯粹。
4. 还有一些细节差异,具体看这个规范的定义就好,就不多说了。
其它类似信息

推荐信息