Nodejs
项目模块路径解析是通过require.resolve
方法来实现的require.resolve
就是通过Module._resolveFileName
方法实现的require.resolve
实现原理:Module._resolveFileName
方法核心流程有 3 点:- 判断是否内置模块
- 通过
Module._resolveLookupPaths
方法生成node_modules
可能存在的路径 - 通过
Module._findPath
查询模块的真实路径
Module._findPath
核心流程有 4 点:- 查询缓存(将
request
和paths
通过\x00
合并成cacheKey
) - 遍历
paths
,将path
与request
组件文件路径basePath
- 如果
basePath
存在则调用fs.realPathSync
获取文件真实路径 - 将文件真实路径缓存到
Module._pathCache
(key
就是前面生成的cacheKey
)
- 查询缓存(将
fs.realPathSync
核心流程有 3 点:- 查询缓存(缓存的
key
为p
,即Module._findPath
中生成的文件路径) - 从左往右遍历路径字符串,查询到
/
时,拆分路径,判断该路径是否为软链接,如果是软链接则查询真实链接,并生成新路径p
,然后继续往后遍历,这里有一个细节想要特别注意:- 遍历过程中生成的子路径
base
会缓存在knownHard
和cache
中,避免重复查询
- 遍历过程中生成的子路径
- 遍历完成得到模块对应的真实路径,此时会将原始路径
original
作为key
,真实路径作为value
,保存到缓存中
- 查询缓存(缓存的
require.resolve.paths
等价于Module._resolveLookupPaths
,该方法用于获取所有node_modules
可能存在路径require.resolve.paths
实现原理:- 如果路径
/
(根目录),直接返回['/node_modules']
- 否则,将路径字符串从后往前遍历,查询到
/
时,拆分路径,在后面加上node_modules
,并传入一个paths
数组,直至查询不到/
后返回的paths
数组
- 如果路径