require

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,下图为结果

image.png

如何证明是从缓存中获取呢?第一次引入之后删掉缓存,再引入

/**
*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文件的步骤

  1. 先调用Module._resolveFilename查询到所引入的文件的绝对路径
  2. 是否有该模块缓存,有就返回缓存
  3. 是内置模块,返回内置模块
  4. 创造一个Module的实例module,存入缓存
  5. 然后调用module.load进行文件的加载
  6. 输出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.按照不同的后缀采用不同的加载方式

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容