实现兼容AMD/CMD/Node多种模块规范

在JavaScript社区,CommonJS规范的提出,是模块化方面最重要的一笔。

CommonJS的模块实现

CommonJS的模块引用使用require,如下:

1
var http = require('http');

Node的模块实现

在Node中引入模块,需要经过下面3个步骤:

  • 路径分析;
  • 文件定位;
  • 编译执行。

主要用require()方法来查找模块。

AMD规范

AMD全称Asynchronous Module Definition,即“异步模块定义”。其模块引用方式如下:

1
define(id?,dependencies?,factory);

其中,id及依赖是可选的。其与CommonJS方式相似的地方在于factory的内容就是实际代码的内容,下面是一个简单的例子:

1
2
3
4
5
6
7
define(function(){
var exports = {};
exports.sayHello = function(){
alert('hello');
};
return exports;
});

CMD规范

CMD由国内大神玉伯提出,与AMD类似,区别主要在于定义模块和依赖引入的地方。AMD需要在声明模块时指定所有的依赖,通过形参传递依赖到模块内容中:

1
2
3
define(['dep1','dep2'],function(dep1,dep2){
return function(){};
});

与AMD相比,CMD更接近Node对CommonJS规范的定义:

1
define(factory);

在依赖部分,CMD支持动态引入,如下:

1
2
3
define(function(require,exports,module){
// Todo
});

require、exports、module通过形参传递给模块,在需要依赖模块时,随时调用require引入即可。

兼容多种模块规范

为了让同一个模块可以运行在前后端,在开发过程中需要考虑兼容前后端问题,以下代码演示如何将hello()方法定义到不同的运行环境中,它能够兼容AMD、CMD、Node以及常见的浏览器环境中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
;
(function (name, definition) {
// 检测上下文环境是否为AMD或CMD
var hadDefine = typeof define === 'function',
// 检测上下文环境是否为Node
hasExports = typeof module !== 'undefined' && module.exports;
if (hadDefine) {
// AMD/CMD
define(definition);
}
else if (hasExports) {
// Node
module.exports = definition();
}
else {
// 将模块的执行结果挂在全局变量(window)中
this[name] = definition();
}
})('hello', function () {
var hello = function () {};
return hello;
});

以上信息主要摘自书籍《深入浅出Nodejs》,有兴趣的朋友可以自己尝试前台、后台模块引入的异同,或者尝试这几种模块引入方式的异同。



money☜☜☜ wechat 『『『 reward 点击扫码打赏 ~~~ ^_^ 』』』alipay ☞☞☞ money