深读node模块加载流程底层逻辑(Module)

分析模块加载的流程

  • 1.加载模块 Module._load 加载模块之后 最终返回的就是module.exports
  • 2.Module._resolveFilename 解析文件名, 产生一个可读取的文件名 .js? .json?
  • 3.Module._cache 如果文件被缓存过 直接拿上一次的返回结果
  • 4.如果模块没有加载过,会根据路径创建一个模块 new Module() {id:文件名,exports:导出结果}
  • 5.缓存模块为了后续使用
  • 6.module.load 加载模块(读文件)
  • 7.获取扩展名来调用不同的加载方式
  • 8.根据扩展名查找 对应的加载方式 Module._extension
  • 9.js的模块主要是读取
  • 10.读取文件后包裹函数 , 并且传入五个参数 [ ‘exports’,‘require’,‘module’,‘__filename’, ‘__dirname’ ]
  • 11.执行函数 用户会给module.exports 赋予值
    1. 因为最终返回的是module.exports 所以可以拿到最终的返回结果
const fs = require('fs');
const path = require('path');
const vm = require('vm');

// 模块加载器
function Module(id) {
  this.id = id;
  this.exports = {}; // 模块的导出结果
}

// 模块缓存
Module._cache = {};

// 扩展名对应的加载方式
Module._extensions = {
  ".js"(module) {
    const content = fs.readFileSync(module.id, "utf8");
    const wrapperFn = vm.compileFunction(content, [
      "exports",
      "require",
      "module",
      "__filename",
      "__dirname",
    ]);
    const exports = module.exports;
    const thisValue = exports;
    const dirname = path.dirname(module.id);
    Reflect.apply(wrapperFn, thisValue, [
      exports,
      myRequire,
      module,
      module.id,
      dirname,
    ]);
  },
  ".json"(module) {
    const content = fs.readFileSync(module.id, "utf8");
    module.exports = JSON.parse(content);
  },
};

// 解析文件名
Module._resolveFilename = function (id) {
  const fileUrl = path.resolve(__dirname, id);
  if (fs.existsSync(fileUrl)) return fileUrl;
  const exts = Reflect.ownKeys(Module._extensions);
  for (let i = 0; i < exts.length; i++) {
    const fileUrl = path.resolve(__dirname, id + exts[i]);
    if (fs.existsSync(fileUrl)) return fileUrl;
  }
  throw new Error("Module not found");
};

// 加载模块
Module.prototype.load = function (filename) {
  const ext = path.extname(filename);
  Module._extensions[ext](this);
};

// 自定义require函数
function myRequire(id) {
  // 解析文件名
  const filepath = Module._resolveFilename(id);

  // 检查模块是否已缓存
  const cacheModule = Module._cache[filepath];
  if (cacheModule) {
    return cacheModule.exports;
  }

  // 创建新模块并缓存
  const module = new Module(filepath);
  Module._cache[filepath] = module;

  // 加载模块
  module.load(filepath);

  // 返回结果
  return module.exports;
}

// 使用自定义的require函数加载模块
const content = myRequire("./module.json");
console.log(content);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值