缓存加载
模块会优先的从缓存中加载,在第一次加载之后会被缓存,之后的每次调用执行也会从缓存中加载,这意味着多次调用require()方法不会导致模块的代码被多次执行,无论是哪一种模块,都会优先的从缓存中加载,一方面避免了重复调用执行,一方面提高了模块的加载效率
1.内置模块加载机制
内置模块是Node.js为我们提供的模块,内置模块的加载优先级最高
如果我们现在在项目中下载了一个或者自己封装了叫做fs的模块(并非内置对象),这时我们将这个模块和fs内置模块一起导入到JS中,require('fs')返回的永远都是内置fs模块
2.第三方模块(包)的加载机制
Node.js会为我们进行判断,如果传递给ruquire()的模块标识符不是一个内置对象,也并不是以./等开头的自定义模块,那么Node则会从当前的父目录开始查询,查询node_modules文件夹,尝试从中加载到第三方模块;假如没有找到,则会继续再往上一层目录中查询,直到查询到文件系统目录停止
假如:我们在D:\xx\yy\zz\test.js这个JS文件中调用了require('moment')
那么这时Node.js首先会从D:\xx\yy\zz\node_modules\moment查找,没有查找到
Node.js接下来会从D:\xx\yy\node_modules\moment查找,没有查找到
Node.js继续从D:\xx\node_modules\moment查找,没有查找到
Node.js最后会从D:\node_modules\moment查找,没有查找到
如果文件系统也没有查找到,那么就报错
3.自定义模块 加载机制
我们加载自定义模块时,必须以./或者../开头,作为路径标识符,如果我们没有指定的话,Node.js会把它当作一个内置模块或者第三方模块来加载,没有加载到的话,就会报错
不过我们可以不加后缀名,Node.js会自动为我们补充:
我们可以直接require(./test.js)来进行加载
如果不写后缀名:
Node.js会自定为我们补充.js后缀,如果没有加载到指定的.js文件
Node.js会自定为我们补充.json后缀,如果没有加载到指定的.json文件
Node.js会自定为我们补充.node后缀,如果没有加载到指定的.node文件
如果都没有查询到的话,那么抛出错误
4.目录作为模块
其实除了文件名,我们还可以使用目录名来作为模块的加载指引
假如我们require('./const') ---------这是一个目录名作为模块标识符
第一步,Node会从被加载的目录下查找一个package.json配置文件中寻找main属性,将main属性指定的值作为require的加载入口 ----------假如我们没找到配置文件或者main入口
第二步,Node.js会从加载的目录中查找index.js文件来作为加载入口 -------假如没有找到index.js文件
这俩个都没有找到的话,抛出错误:
Error:Cannot find module 'xxxxxx'