参考文章: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);}