参考文章: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);
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。