🌐 [深入浅出nodeJS] 2. 模块机制
commonJS规范
node模块实现
Node在实现中并非完全按照规范实现,而是对模块规范进行了一定的取舍,同时也增加了少许自身需要的特性。尽管规范中exports、require和modulel听起来十分简单,但是Node在实现它们的过程中究竟经历了什么,这个过程需要知晓。在Node中引入模块,需要经历如下3个步骤。
(1)路径分析
(2)文件定位
(3)编译执行
在Node中,模块分为两类:一类是Node提供的模块,称为核心模块;另一类是用户编写的模块,称为文件模块。
核心模块部分在Node源代码的编译过程中,编译进了二进制执行文件。在Node进程启动时,部分核心模块就被直接加载进内存中,所以这部分核心模块引入时,文件定位和编译执行这两个步骤可以省略掉,并且在路径分析中优先判断,所以它的加载速度是最快的。
文件模块则是在运行时动态加载,需要完整的路径分析、文件定位、编译执行过程,速度比核心模块慢。
核心模块
核心模块分为C/C++编写的和JavaScript编写的两部分,其中C/C++文件存放在Node项目的src目录下, JavaScript文件存放在lib目录下。
TODO
C++扩展模块
模块调用栈
C/C++内建模块属于最底层的模块,它属于核心模块,主要提供API给JavaScript核心模块和第三方JavaScript文件模块调用。如果你不是非常了解要调用的C/C++内建模块,请尽量避免通过 process.binding()方法直接调用,这是不推荐的。
JavaScript核心模块主要扮演的职责有两类:一类是作为C/C++内建模块的封装层和桥接层,供文件模块调用;一类是纯粹的功能模块,它不需要跟底层打交道,但是又十分重要。
包与NPM
CommonJS包由包结构和描述文件组成
前后端共用模块
javascriptCopy
(function (name, definition) {
// 检测上下文环境是否为AMD或CMD
var hasDefine = typeof define === 'function',
// 检查上下文环境是否为Node
hasExports = typeof module !== 'undefined' && module.exports;
if (hasDefine) {
// AMD环境ईCMD环境
define(definition);
} else if (hasExports) {
// 定义为通Node模块
module.exports = definition();
} else {
// 将模块的执行结ࡕࠬ在windowՎ量中Lj在៓બ器中thisኸၠwindow对象
this[name] = definition();
}
})('hello', function () {
var hello = function () {};
return hello;
}); 