require的查找规则
在Node中,我们导入一个模块或者文件会使用require函数,但是我们有没有注意一个细节,就是我们导入一个js文件时可以省略掉后缀名.js,require函数也会帮我们导入,这是为什么呢?假设require的查找规则是require(x),那么会有如下几种情况:
x是一个核心模块,例如file,path,http,那么直接返回该核心模块。X是以./,../,/开头:- 将
x当作一个文件在对应的目录下查找:- 如果x有后缀名,那么就按照后缀名去查找对应的文件。
- 如果没有后缀名,那么就按照以下顺序来查找:
x文件,x.js文件,x.json文件x.node文件。
- 若没有找到
x文件,那么将x当作一个目录,按以下顺序来查找目录下的index文件:x/index,x/index.js,x/index.json,x/index.node。 - 若以上都没有找到,那么报
not found错误。
- 将
- 直接是
x(不是路径),且x不是一个核心模块,那么它会从调用require函数所在的js文件所在的上层文件夹中的node_modules文件夹中一层一层地查找:
若找到,直接返回文件,没有找到报not found错误。
require的加载顺序以及缓存机制
require函数是同步的。
// foo.js
console.log(1)
// main.js
require('./foo')
console.log(2)
require如果被多次引入,那么它将会被缓存,最终只执行一次。- 如果有循环引用,那么他的加载顺序应该是
图结构中的深度优先算法的顺序
即:main -> aaa -> ccc -> ddd -> eee -> bbb