乐趣区

关于node.js:nodejs篇CommonJS加载模块分析

参考文章:CommonJS 标准

剖析

  • require 加载模块门路
  • module.exports 导出模块~~~~
  • 每个模块都是一个沙箱环境,互不烦扰
  • 依据文件后缀判断文件解决形式 (json,js)

编写

加载模块 require

function myRequire(moduleRelPath){
    // 可能是相对路径,须要 resolve
    path.resolve(__dirname,moduleRelPath);
}

Module 类

  • 模块
function Module(moduleAbsPath){
    this.modulePath = moduleAbsPath;
    this.exports = {}}
  • 拼接执行字符串
Module.wrapper = ["(function(exports,module,require){","})"
]
  • 按文件解决
Module.extension = {".js"(module){},
    ".json"(module){},}

加载模块

Module.prototype.load = function () {
  // 获取文件后缀名
  let extname = path.extname(this.modulePath);
  // 交给对应办法解决
  Module.extension[extname](this);
};

导出

function myRequire(id) {let absPath = path.resolve(__dirname, id);
  let module = new Module(absPath);
  // 加载模块
  module.load();
  // 导出
  return module.exports;
}

解析文件

解决 json

Module._extensions[".json"] = (module)=> {let str = fs.readFileSync(module.id, "utf-8");
  str = JSON.parse(str);
  // 取出内容间接绑定到 module.exports
  module.exports = str;
}

解决 js

const vm = require("vm");
Module._extensions[".js"] = (module)=> {let str = fs.readFileSync(module.id, "utf-8");
    // 拼接办法
    let scriptStr = Module.wrapper[0] + str + Module.wrapper[1];
    // 沙箱环境
    let fn = vm.runInThisContext(scriptStr);
    // 执行并传参
    fn.call(module.exports, module.exports, module, myRequire);
}
退出移动版