Keep moving just play & have fun

AMD&CMD

2018-03-20
May

阅读:

Web
   

AMD&CMD规范


JS模块化编程


随着前端开发的不断发展,互联网业务的复杂度越来越高,JS模块化开发已经变得越来越重要。

我们在前端开发过程中,使用统一的编写方式进行模块化,可以对巨大系统和复杂业务的代码进行很好的组织和管理,方便多人的合作。

JS中的模块化规范包括(CommonJS, AMD, CMD)。

(1)CommonJS

CommonJS是一个有志于构建Javascript生态圈的组织。整个社区致力于提高javascript程序的可移植性和可交换性,无论是在服务端还是浏览器端。

a group with a goal of building up the javascript ecosystem for web browsers, desktop and command line apps and in the browser.

CommonJS是一个更偏向于服务器端的规范。Node.js采用了这个规范。根据CommonJS规范,一个单独的文件就是一个模块。

CommonJS规范的主要内容:模块必须通过module.exports导出对应的变量或接口,通过require()导入其他模块的输出到当前模块。

// moduleA.js
module.exports = function(value) {  
    return value++;  
}
// moduleB.js
var moduleA = require('./moduleA');  
var result = moduleA(2);  

优点

* 便于服务器端重用  

* NPM中已经提供近20W个模块包   

* 简单并容易使用

缺点

* 使用同步的方式加载资源,阻塞加载,不适合在浏览器环境中使用。

* 不能非阻塞的并行加载多个模块

(2)AMD规范

AMD(Asynchronous Module Definition 异步模块定义)。它采用异步方式加载模块,模块的加载不影响后面语句的运行。所有依赖这个模块的语句,都定义在一个回调函数中,等到依赖模块全部加载完成后,再执行这个回调函数。

简单地说:异步模块定义就是 依赖前置, 所有的require都被提前了。RequireJS就是AMD规范的实现

define()函数

example:

    define('alpha',['require', 'exports', 'beta'], function (require, exports, beta) {
        exports.verb = function() {
            return beta.verb();
        }
    })

AMD也采用require()语句加载模块,但是不同于CommonJS,它要求两个参数:

    require([dependencies],callback);

第一个参数[dependencies],是一个数组,代表依赖的模块; 第二个参数callback,则是依赖模块加载成功后,执行的回调函数。

example:

    require(['math'], function(math) {
        math.add(1, 2);
    })

优点

* 适合在浏览器环境异步加载

* 并行加载多个模块

缺点

* 开发体验和阅读不友好

(3)CMD规范

CMD(Common Module Definition 通用模块定义)。它更贴近CommonJS Modules、1.1和Node Modules规范,一个模块就是一个文件。

简单来说就是:

1. **通过exports暴露接口**

2. **通过require引入依赖**

它推崇依赖就近,即想什么时候加载就什么时候require,实现了 懒加载延迟执行SeaJS是CMD规范的实现。

example:

    define(function(require, exports, module) {
        var $ = require('jquery');
        var Spinning = require('./spinning');
        exports.doSth = ...;
        module.exports = ...;
    })

上例中同时使用了exports和module.exports,传入factory构造方法的参数exports是module.exports对象的一个引用。

exports和module.exports的关系

1. module.exports初始值为一个空对象{}, 所以exports的初始值也是一个{}; 

2. exports是module.exports的一个引用,他们指向同一块内存;  

3. require() 返回的是module.exports而不是exports; 

Comments

Content