模块加载过程机制
优先从缓存加载
路径分析和文件定位
模块标识符分析
核心模块
路径形式的文件模块
自定义模块
无论是核心模块还是文件模块都是通过 requrie 方法进行加载
1、 优先从缓存中加载(node对于已经加载过的模块会缓存起来,下次如果继续使用,直接从缓存中拿),无论是核心模块还是文件模块
2.1 、如果模块标识是核心模块,那么 node 去读取自己的核心模块
2.2 、如果模块标识是以 . 开头的模块,那么这个模块就是一个相对路径文件模块。
2.3、 既不是路径形式的文件模块,也不是核心模块,是一个包
3.1 、node 先在当前目录下找有没有一个叫做 node_modules 的目录, 如果找到,则找里面有没有对应的包名
3.2、 如果找到该包名对应的目录,找里面的 package.json 文件
3.3 、如果找到 package.json 文件,那么找里面的 main 属性,如果找到 main 属性,直接加载该属性对应的 模块文件
3.4 、如果没有找到 package.json 文件 或者 package.json 文件中没有 main 属性 或者 main 指定的入口文件模块不存在,查找失败
4、 node 自动进入上一级目录 重复上面的步骤
node 中的包模块查找机制非常类似于 JavaScript 中的 作用域链 和 原型链
5、 如果直到 当前文件模块所属的盘符根路径还找不到,最后报错。
总结: 先去缓存中找,缓存没有如果是核心模块就去读自己的核心模块,如果不是按照路径找,路径没有不是文件的话就是包,就去找这个包
文件定位
文件扩展名分析:按照 `.js` `.json` `.node` 的次序补足扩展名
目录分析和包
模块编译
`.js` 文件,通过 fs 模块同步读取文件后编译执行
`.node` 文件
`.json` 文件,通过 fs 模块同步读取文件后使用 `JSON.parse()` 解析返回结果
其它扩展名,被当作 `.js` 文件载入
兼容模块规范
在代码中加入这些判断
if (typeof exports !== ‘undefined’) {
if (typeof module !== ‘undefined’ && module.exports) {
exports = module.exports = _;