nodejs引入模块用require:
var express = require('express')
exports对象用于导出当前模块的方法和变量,一个文件就是一个模块,将方法挂载在exports对象上做为属性定义导出的方式,例如: node
//test.js
exports.test1 = function(){
return 'ok';
}
在另外一个文件中,咱们经过require()方法引入模块后,就能调用它的方法和属性了: c++
//test2.js
var test = require('test');
exports.tt = function(){
return test.test1();
}
node中引入模块须要经历三个步骤: express
- 路径分析。
- 文件定位
- 编译执行
路径分析:
require()方法接受一个标识符做为参数,模块标识符分为: json
- 核心模块,如http,fs,path等,加载优先级仅次于缓存
- . 或者..开始的相对路径文件模块
- /开始的绝对路径文件模块,上述两种文件模块require()方法会将路径转为真实路径,并以真实路径做为索引,将编译执行后的结果缓存。因为指定了明确的路径,因此查找能够节约大量时间,加载速度慢于核心模块。
- 非路径形式的文件模块,特殊的文件模块,能够是一个文件或者包的形式,最慢最费时。根据node的模块路径生成规则,在加载过程当中会:
1(找当前文件目录下的node_modules目录),
2(父目录下的node_modules目录),
3(父目录的父目录的node_modules),
4(沿路径逐级向上逐级递归直到跟目录的node_modules)
文件定位: 缓存
- require()在分析标识符的过程当中,标识符不包含文件扩展名的状况下,node会按.js,.node,.json的次序补足扩展名,依次尝试(调用fs模块同步阻塞式判断文件是否存在),因此若是是.node .json文件最好加上扩展名。
- 若是没有查找到文件却获得一个目录会将目录看成一个包来处理。
模块编译: ui
- js文件经过fs模块同步读取文件后编译执行
- node文件,经过,c/c++编写的扩展文件(编写c/c++模块以后编译生成的,因此这里只有加载和执行),经过dlopen()方法加载最后编译生成的文件
- json文件,经过fs模块同步读取,用JSON.parse()解析返回结果
- 其他扩展名都被看成.js文件载入
node中模块分为核心模块和本身编写的模块(文件模块),核心模块是在node源代码编译过程当中编译进了二进制执行文件,进程启动的时候部分核心模块就直接加载到了内存,省略了2 (文件定位)和3(编译执行),而且在1(路径分析)的时候优先判断,加载速度是最快的,文件模块在运行的时候动态加载,须要123步骤,加载速度比核心模块慢。node对引入过的模块都会进行缓存,缓存的是编译和执行后的对象。require()方法优先缓存加载,核心模块的缓存检查优先于文件模块的检查。 spa