您的位置:首页 > Web前端 > JavaScript

浅析JS模块规范(CommonJS/AMD/CMD)

2017-03-02 10:43 381 查看
随着JS模块化编程的发展,处理模块之间的依赖关系成为了维护的关键,AMD,CMD,CommonJS是目前最常用的三种模块化书写规范。
一、CommonJS
CommonJS规范是诞生比较早的,NodeJS就采用了CommonJS。
Node、CommonJS、浏览器和W3C之间关系:
  |---------------浏览器----- ------------------|        |--------------------------CommonJS----------------------------------|

  |  BOM  |       | DOM |        | ECMAScript |         | FS |           | TCP |         | Stream |        | Buffer |          |........|

  |-------W3C-----------|       |---------------------------------------Node--------------------------------------------------|
CommonJS定义的模块分为:{模块引用(require)} {模块定义(exports)} {模块标识(module)}
require()用来引入外部模块;exports对象用于导出当前模块的方法或变量,唯一的导出口;module对象就代表模块本身。
//sum.js
exports.sum = function(){...做加操作..};

//calculate.js
var math = require('sum');
exports.add = function(n){
return math.sum(val,n);
};
这种写法适合服务端,因为服务器读取模块都是在本地磁盘,加载速度很快。但是如果在客户端,加载模块的时候有可能出现“假死”状况。比如上面的例子中sum的调用必须等待sum.js请求成功,加载完毕。那么,能不能异步加载模块呢?
二、AMD
AMD,即 (Asynchronous Module Definition),这种规范是异步的加载模块,requireJs应用了这一规范。先定义所有依赖,然后在加载完成后的回调函数中执行:
require([module], callback);
AMD就只有一个接口:define(id?,dependencies?,factory);
它要在声明模块的时候制定所有的依赖(dep),并且还要当做形参传到factory中,像这样:
define(['dep1','dep2'],function(dep1,dep2){...});
若无依赖,就定义简单的模块,如:
define(function(){
var exports = {};
exports.method = function(){...};
return exports;
});
AMD虽然实现了异步加载,但是开始就把所有依赖写出来是不符合书写的逻辑顺序的,能不能像commonJS那样用的时候再require,而且还支持异步加载后再执行呢?
三、CMD
CMD (Common Module Definition), 是seajs推崇的规范,CMD则是依赖就近,用的时候再require。它写起来是这样的:
define(function(require, exports, module) {
var clock = require('clock');
clock.start();
});
AMD和CMD最大的区别是对依赖模块的执行时机处理不同,而不是加载的时机或者方式不同,二者皆为异步加载模块。
AMD依赖前置,js可以方便知道依赖模块是谁,立即加载;而CMD就近依赖,需要使用把模块变为字符串解析一遍才知道依赖了那些模块,这也是很多人诟病CMD的一点,牺牲性能来带来开发的便利性,实际上解析模块用的时间短到可以忽略。

SeaJS与RequireJS异同:https://github.com/seajs/seajs/issues/277

参考:http://www.jianshu.com/p/09ffac7a3b2c

http://www.cnblogs.com/skylar/p/4065455.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: