模块机制
随着Web2.0的发展,Js从表单校验跃迁到应用开发的级别上:
工具(浏览器兼容) -> 组件(功能模块) -> 框架(功能模块组织) -> 应用(业务模块组织)
1.CommonJS规范
希望JavaScript能在任何地方运行
1.1CommonJS的模块规范
CommonJS对模块的定义分为模块引用、模块定义和模块表示3个部分
1.模块引用
var math = require('math');
在CommonJs中,存在require()方法引入一个模块API到当前上下文中
2.模块定义
通过exports对象定义当前模块的方法或者变量,在模块中还存在一个module对象,代表模块本身,而exports是module的属性。在Node中,一个文件就是一个模块,将方法挂载在exports对象上作为属性即可定义到处的方式:
//math.js
exports.add = function () {
var sum = 0, i = 0,
args = arguments,
l = args.length;
while (i < 1) {
sum += args[i++];
}
return sum;
}
在另一个文件引用方法并使用
//program.js
var math = require('math');
exports.increment = function (val) {
return math.add(val, 1);
}
3.模块标识
模块标识其实就是传递给require()方法的参数,可以没有文件后缀.js
CommonJS构建的模块导出和引入机制使用户完全不必考虑变量污染。
2.Node的模块实现
在Node中引入模块,需要经历如下3个步骤:
1.路径分析
2.文件定位
3.编译执行
在Node中,模块分为两类:一类是Node提供的模块,称为核心模块;另一类是用户编写的模块,称为文件模块。
核心模块在Node源码编译过程中,被编译成二进制文件。在Node进程启动自动加载到内存,加载速度是最快的。
文件模块是在运行时加载的。
两类模块都采用有限从缓存加载的策略,不用支出是核心模块的缓存检查先于文件模块的缓存检查。
2.1路径分析和文件定位
1.模块标识符分析
(1)核心模块,如http、fs、path等。
(2).或..开始的相对路径文件模块。
(3)以/开始的绝对路径文件模块。
(4)以非路径形式的文件模块,如自定义的connect模块。
2.模块编译
在Node中,每个文件模块就是一个对象。对于不同文件扩展名,其载入方法也有所不同:
(1).js文件。通过fs模块同步读取文件后编译执行。
(2).node文件。这是用C/C++编写的扩展文件,通过dlopen()方法加载最后编译生成的文件。
(3).json文件。通过fs模块同步读取文件后,用JSON.parse()解析返回结果。
(4)其余扩展名文件。被当做.js文件载入。
3.核心模块
核心模块分为Javascript编写的和C/C++编写的,其中C/C++编写的在src目录下,Javascript文件放在lib目录下。
4.前后端公用模块
4.1 AMD规范
AMD规范适用于前段应用场景,全称是Asynchronus Module Definition(异步模块定义)。AMD规范是CommonJS模块规范的一个延伸,它的模块定义如下:
define(id?, dependencies?, factory);
它的模块id和依赖是可选的,与Node模块相似的地方是factory的内容。
4.2 CMD规范
CMD规范与AMD规范的区别在于定义模块和依赖引入部分:
define(function(require,exports,module){
//the module code goes here
});
require、exports和module通过形参传给模块,在需要依赖模块时,调用require()引入。