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