现在的位置: 首页 > 综合 > 正文

深入浅出NodeJS——模块机制

2018年09月29日 ⁄ 综合 ⁄ 共 1823字 ⁄ 字号 评论关闭
文章目录

JavaScript天生缺乏模块功能。

CommonJS规范涵盖模块、二进制、Buffer、字符集、IO流、进程环境、文件系统、套接字、单元测试等,Node借鉴其中Modules规范实现一套易用的模块系统。

Node的模块实现

Node中引入模块,经过以下步骤:

a 路径分析

b 文件定位

c  编译执行

Node模块分类:

a 核心模块:Node提供模块,部分在Node源码中,编译进了二进制文件,在Node启动时,这部分直接加载进内存,所以这部分模块引入时,可以忽略文件定位和编译执行,并且路径分析中优先判断,加载速度最快。

b 用户模块:用户编写模块,运行时动态加载。

加载原则

(1) 优先从缓存加载

Node缓存编译和执行之后的对象。无论是核心模块还是文件模块,require方法对相同模块的二次加载一律采用缓存优先的方式,核心模块缓存检查优先于文件模块的缓存检查。

(2) 路径分析和文件定位

模块标示符类型

a. 核心模块,如http、fs、path

b. .或者..开头的相对路径文件模块

c. 以/开头的绝对路径文件模块

d. 非路径形式的文件模块,如connect模块

文件扩展名分析:模块标示符不包含扩展名,Node会按照.js、.node、.json的次序补足,依次尝试

目录和包分析:分析文件扩展名后可能没有找到对应文件,但得到一个目录,Node将目录当做一个包来处理,package.json包描述文件,从中取出main属性指定的文件名进行定位。

(3) 模块编译

在Node中每个文件模块都是一个对象,其定义如下:

function Module(id,parent){
	this.id = id;
	this.export = {};
	this.parent = parent;
	if(parent && parent.children){
		parent.push(this);
	}
	this.filename = null;
	this.loaded = false;
	this.children = [];
}

对应不同扩展名载入方法不同:

a. js文件。通过fs模块同步读取文件。

b. node文件。调用C/C++编写的模块,通过dlopen方法加载最后编译生成的文件

c. json文件。通过fs模块同步读取以后,用JSON.parse()解析。

d. 其余扩展名 文件。当作.js文件。 

每个编译成功的模块将其文件路径作为索引缓存在Module._cache对象上。

每个模块文件中存在require、exports、module这3个成员,但是文件中并没有定义。此外每个模块还有_filename、_dirname这两个变量。实际上Node在编译时候,对获取的JS文件进行了头尾包装。在头部添加了(function(exports, require, module, _filename, _dirname)) {\n 在尾部添加了\n});

核心模块

核心模块分为C/C++编写和JavaScript编写,其中C/C++放在Node项目的src目录,JavaScript放在lib目录下。

编译所有C/C++文件之前,把所有JavaScript模块文件编译为C/C++代码,Node采用V8附带的js2c.py工具,将所有的JS代码(src/node.js和lib/*.js)转换为C++里的数组,生成node_natives.h头文件。在这个过程中JS代码以字符串的形式存储在node命名空间中,是不可直接执行的。在Node启动过程时,JS代码直接加载进内存,在加载过程中JS核心模块经历标示符分析后直接定位到内存中,比普通文件加载快很多。

C/C++编写的核心模块称为内建模块,通常不被用户直接调用,如buffer、crypto、fs、os等模块。内建模块在进行文件编译时编译进二进制文件,一旦Node开始执行,被直接载入内存直接可执行。核心模块可能会依赖内建模块,文件模块可能依赖核心模块。

包与NPM

包实际是一个存档文件,包括以下文件:

package.json:包描述文件

bin:用于存放可执行二进制文件

lib:用于存放javascript代码的目录

doc:用于存放文档的目录

test:用于存放测试相关的代码

npm install express 本地安装,安装在当前项目目录的node_modules

npm install express -g 全局模式

npm install underscore --registry=http://registry.url 非官方源安装

抱歉!评论已关闭.