详解commonJS规范中require()方法

在CommonJS规范中,通过exports或module.exports导出一个模块。模块中存在require()方法,通过这个方法接受模块标识,然后根据node的模块引入规则引入模块。就能在模块使用引入模块的属性和方法了。

在node中引入模块,会经历以下三个步骤:

  • 路径分析
  • 文件定位
  • 编译执行
// app.js   
console.log(typeof require);      // 输出 function
console.log(require.toString());  /* 输出
                                        function require(path) {
                                            try {
                                              exports.requireDepth += 1;
                                              return mod.require(path);
                                            } finally {
                                              exports.requireDepth -= 1;
                                            }
                                          }
                                  */

这是输出结果:

可以看出 require 函数接受一个参数 path(模块标识)。然后根据模块标识来进行路径分析和文件定位。

路径分析

  • 引入核心模块,比如: let http = require("http");
  • 以" ./ " 或 " ../ " 引入的相对路径的模块文件
  • 以" / " 引入的绝对路径模块
  • 以非路径形式引入的模块 比如通过npm下载的模块,配合package.json文件引入

文件定位

在node中引入模块时,文件扩展名是可以省略的。node会按照 .js .node .json 格式依次去匹配

// json.js
console.log(".js文件");

json.josn文件

{
    "name":"鲁班七号"
}
let js = require("./json");  // 输出  .js文件

let json = JSON.stringify(require("./json.json"));

console.log(json);   // 输出 {"name":"鲁班七号"}

关于require方法引入模块的步骤如下:

  1. 查找文件可能存在的文件扩展名: .js .node .josn
  2. 判断是否是绝对路径
  3. 判断是否是有目录的后缀/
  4. 判断缓存中是否存在,如果存在,就直接加载
  5. 如果缓存不存在,就遍历所有路径,是否存在该模块
  6. 如果不存在,判断目录中是否有 package.json 文件
  7. 是否存在目录名 + index + 后缀名 的文件
  8. 将找到的文件路径存入缓存
  9. 没有找到,报错

参考: 《深入浅出Node.js》作者:朴灵 第二章 模块机制

posted @ 2019-08-29 22:15  氵灬  阅读(1349)  评论(0编辑  收藏  举报