require究竟做了什么
require的源代码位于lib/module.js
下。关于require的分析,推荐阅读require()源码解读和CommonJS规范。
require的基本作用就是读取并执行一个javascript文件,并返回其module.exports对象。在Module.prototype.require
函数中,会调用Module._load
函数,Module._load
完成了整个require的过程。整个require的过程在阮老师的博客里已经写的比较清晰了,我在其基础上补充几点(node源码为v9.3.0)。
_load
函数的三个参数
request
传入目标模块的路径。parent
传入目标模块的父模块,即require
代码出现的模块;对于main
来说,不存在父模块,因此在Module.runMain
函数里有这样一句话,针对main
的特殊处理:
Module._load(process.argv[1], null, true);
可以看到,parent
被置成null
。第三个参数是isMain
,用来区别是否是主模块。
ECMAScript Modules
if (isMain && experimentalModules)
: 这是node在8.5引入的一个新的对ECMAScript Modules的支持,通过设置--experimental-modules
参数来启动。
路径解析
调用_resolveFilename
函数来尝试解析目标模块的路径,尝试规则和优先级就不再重复了。解析成功的话会返回该模块的绝对路径。如果穷尽所有规则都无法匹配,会产生异常:
var err = new Error(`Cannot find module '${request}'`);
err.code = 'MODULE_NOT_FOUND';
throw err;
模块缓存
模块的缓存都是挂在Module._cache
对象上的。node会首先尝试从缓存里去搜索是否有已存在的模块,如果