AMD和CMD规范
AMD(Asynchronous Module Definition),CMD(Common Module Definition)都是JS模块化的规范。之所以有这2个规范是因为RequireJS和Sea.js这2个模块加载器,它们倡导模块化开发理念,核心价值是让 JavaScript 的模块化开发变得简单自然,所以才有了这2个规范的定义。//并行加载所有require模块,并且解析放入回调方法参数中 require(['jquery','common'],function($,COMMON){ // ...此处调用COMMON模块 // ...此处调用jquery模块 });
附件AMD_Sample是一个使用require.js的例子。
Sea.js
官网 http://seajs.org/docs/它提倡的模块化思想是按需执行模块,也可称为延迟执行。正如CMD所推崇的as lazy as possible. 如下示例代码:
//对于方法中所有定义的require模块,都会并行加载 define(function (require, exports, module) { //当代码执行此处时才解析common模块 var COMMON = require('common'); // ...此处调用COMMON模块 //代码执行此处时才解析jquery模块 var $ = require('jquery'); // ...此处调用jquery模块 });
附件CMD_Sample是一个使用sea.js的例子。
总结:
SeaJS只会在真正需要使用(依赖)模块时才执行该模块。SeaJS是异步加载模块的没错, 但执行模块的顺序也是严格按照模块在代码中出现(require)的顺序。而RequireJS会先尽早地执行(依赖)模块, 相当于所有的require都被提前了, 而且模块执行的顺序也不一定100%就是先jquery再common,除非common中定义时依赖了jquery。
这里需要注意的一点:执行模块可能会被很多人产生误解,以为是加载。 它的执行表示真正运行define中的代码, 而非加载(load文件)模块.模块的加载都是并行的, 没有区别, 区别在于执行模块的时机, 或者说是解析。
两者比较:
requireJS实现JS模块文件的异步加载,避免网页被堵塞,管理模块之间的依赖性,便于代码的编写和维护。当然 RequireJS 从 2.0 开始,也支持了CMD写法。你在回调方法体里直接用require('common')不会有任何问题。但是这不是作者所推崇的做法,也不是官方文档里默认的模块定义写法。Sea.js动态解析,前端性能优化,但是require代码嵌入回调方法中不好的一点是,如果以后模块路径有修改,对应require代码也需要修改,则在一定程度上降低了代码的耦合度。
关于AMD和CMD对第三方插件的支持
AMD:目前AMD规范格式已经被很多主流的js框架所接受,比如jquery已经在1.7版本开始支持AMD规范,我们在引入jquery模块之前就不需要对jquery代码进行修改或包装。当然如果有不支持AMD规范的第三方js,requireJS还提供了shim的配置选项,具体就不详细介绍,可以查看官方API。附件中AMD_shim就是采用shim对一个低版本的jquery和第三方插件ztree的支持。CMD:对于CMD规范格式的支持,则需要对第三方插件做一些必要的包装和修改。就拿jquery来说,可以用如下形式改写插件代码:
define(function(){ //...此处添加jquery源码 return $.noConflict(); });
从附件CMD_Sample里就可以看到jquery是被改过的。