#node模块记录
###模块简介:
-
一个js文件为一个最小模块
-
遵循commonjs规范,通过require(“模块名”) 引用,module.export(“模块名”)暴露
-
node引入模块需要经过三步:
- 路径分析
- 文件定位
- 编译执行 (默认编译 js文件,如果没寻找到js文件那么将会寻找.node文件,接下来.json文件)
-
require文件路径
./name or …/name 相对路径
/name 绝对路径
name 直接获取(获取启动时编译进缓存中的模块) -
每个模块存在module对象以及exports对象
######那么为什么我们没有编写这两个变量却可以使用呢?
因为在每个js文件编译时node会自动将代码封装(function(exports, require, module, __filename, __dirname){ ... //你的代码 ... //使用闭包将模块分割开(沙箱操作) })();
-
缓存机制
node会自动将加载过的模块放至缓存中,此处放进缓存的不是模块文件,而是模块编译过后产生的对象,此时引入模块时将会先在缓存中寻找,省去文件定位和模块编译这一步,避免资源浪费.
获取缓存资源的优先级为 核心模块缓存,文件模块缓存
###模块类别:
-
文件模块(外部自定义的模块)
-
核心模块(node自带的模块)
-
内建模块(node自带的模块-纯c语言编写)
调用关系为:
文件模块 -> 核心模块 -> 内建模块
######(不建议使用者直接调用内建模块, 大神忽略)
###核心模块
- javascript核心模块编译
>由于核心模块可能含有c/c++代码, 所以在编译javasript时会将所有的javascript代码编译为c/c++代码,将所有.js文件转为字符串存到c++里的数组里,生成node_natives.h头文件。
>
>在node启动时会将javascript代码直接载入内存中,经过标识符分析定位javascript代码
具体操作:
源文件通过process.binding(“native”)取出, 编译成功的模块缓存在NativeModule._cache对象上,文件模块则缓存到Module._cache对象上
-
c/c++模块编译
node_extensions.h文件将这些散列的内建模块统一放进了node_module_list的数组中, 用get_builtin_module()方法获取模块
-
核心模块的引入流程
require(“os”) -> NativeModule.require(“os”) -> process.binding(“os”) -> get_builtin_module(“node_os”) -> NODE_MODULE(node_os, reg_fun);