require方法用来引入一个模块,将module.exports的内容返回
一、 require只执行一次
require方法是同步执行,执行完毕才会执行下一步,并且在一个模块中多次require只会在第一次require时执行该模块,然后将module.exports的内容进行缓存,后面require时都是读取缓存,不会再重新加载模块
/**
* filename: main.js
*/
console.log('1,2,3,4,5')
module.exports = {
name: 'main.js'
}
/**
* filename:test.js
*/
const main = require('./main.js')
main.date = '123456'
console.log(main)
const age = require('./main.js')
const.log(age)
结果:
image.png
可以看到console.log(1,2,3,4,5)只打印了1次,说明他只执行了一次test.js
在require.cache中可以查看模块缓存,key都是模块文件的绝对路径
执行test.js之后,打印出了require.cache,下图为结果
如何证明是从缓存中获取呢?第一次引入之后删掉缓存,再引入
/**
*filename: test.js
*/
const main = require('./main.js')
main.date = '123456'
console.log(main)
delete require.cache['/Users/cjl/studyspace/app1/src/main.js']
const age = require('./main.js')
console.log(age)
结果是:
image.png二、require文件的步骤
- 先调用Module._resolveFilename查询到所引入的文件的绝对路径
- 是否有该模块缓存,有就返回缓存
- 是内置模块,返回内置模块
- 创造一个Module的实例module,存入缓存
- 然后调用module.load进行文件的加载
- 输出module.exports
Module._resolveFilename
1.判断是否是内置模块,是直接返回
2.利用Module._resolveLookupPath从当前文件逐级向上寻找node_modules子目录,查出可能在的目录,如果是相对路径,返回他的绝对路径
3.Module._findPath
- 如果是绝对路径,就不再搜索
- 如果在缓存中有该待引入的文件路径,那么提取缓存
- 当成文件,在上一步中的目录中查找该文件,如bar,查询不到则添加后缀.js/.json/.node;
- 上面查不到的话,将bar当成目录,依次查询bar下面的package.json、index.js、index.json、index.node
- 最后将查到的绝对路径与待引入的模块名称存入缓存中,并返回
module.load
1.取出查询到的绝对路径的文件的后缀名,如果没有,就默认是.js
2.按照不同的后缀采用不同的加载方式
网友评论