一.require()的基本用法
require语句内部逻辑:
当 Node 遇到 require(X) 时,按下面的顺序处理。
(1)如果 X 是内置模块(比如 require('http'))
a. 返回该模块。
b. 不再继续执行。(2)如果 X 以 "./" 或者 "/" 或者 "../" 开头
a. 根据 X 所在的父模块,确定 X 的绝对路径。
b. 将 X 当成文件,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。
- X
- X.js
- X.json
- X.node
c. 将 X 当成目录,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。
- X/package.json(main字段)
- X/index.js
- X/index.json
- X/index.node
(3)如果 X 不带路径
a. 根据 X 所在的父模块,确定 X 可能的安装目录。
b. 依次在每个目录中,将 X 当成文件名或目录名加载。(4) 抛出 "not found"
请看一个例子。
当前脚本文件 /home/ry/projects/foo.js 执行了 require('bar') ,这属于上面的第三种情况。Node 内部运行过程如下。
首先,确定 x 的绝对路径可能是下面这些位置,依次搜索每一个目录。
/home/ry/projects/node_modules/bar /home/ry/node_modules/bar /home/node_modules/bar /node_modules/bar
搜索时,Node 先将 bar 当成文件名,依次尝试加载下面这些文件,只要有一个成功就返回。
bar bar.js bar.json bar.node
如果都不成功,说明 bar 可能是目录名,于是依次尝试加载下面这些文件。
bar/package.json(main字段) bar/index.js bar/index.json bar/index.node
如果在所有目录中,都无法找到 bar 对应的文件或目录,就抛出一个错误。
二.Module构造函数
源码:
require的源码早Node的lib/module.js文件.下面是简化过的:
1 function Module(id, parent) { 2 this.id = id; 3 this.exports = {}; 4 this.parent = parent; 5 this.filename = null; 6 this.loaded = false; 7 this.children = []; 8 } 9 10 module.exports = Module; 11 12 var module = new Module(filename, parent);