1、要先将 filename的文件转化为绝对路径
2、读取这个文件,需要增加一个匿名函数(exports ,require,module,__filename,__dirname) 函数内部需要返回module.exports
3、让函数执行
4、new Module 创建模块,根据文件名绝对路径创建(exports id)
5、module.load 加载模块 Module._extensions 代表的是一个对象 对象上放着很多处理方法
6、最终返回的是一个module.exports
let path = require('path');
let fs = require('fs');
let vm = require('vm');
let wrapper = [
'(function(exports, require, module, __filename, __dirname){',
'\n})'
]
function Module(id) {
this.id = id;
this.exports = {};
}
Module._cache = {};
Module._extensions = {
'.js'(module) {
let script = fs.readFileSync(module.id,'utf8');
let fnStr = wrapper[0] + script + wrapper[1];
let fn = vm.runInThisContext(fnStr);
let exports = module.exports;
fn.call(exports,exports, req, module,module.id,path.dirname(module.id));
},
'.json'(module) {
let script = fs.readFileSync(module.id, 'utf8');
module.exports = JSON.parse(script);
}
}
function tryModuleLoad(module) {
let extname = path.extname(module.id);
Module._extensions[extname](module);
}
function resolveFileName(filename) {
let r = path.resolve(__dirname,filename);
let isExists = fs.existsSync(r);
if (isExists) {
return r;
}else{
let keys = Object.keys(Module._extensions);
for(let i = 0 ; i<keys.length;i++){
let ext = keys[i];
let tryFilename = r + ext;
if (fs.existsSync(tryFilename)){
return tryFilename;
}
}
throw new Error('module not found');
}
}
function req(filename) {
let id = resolveFileName(filename);
let cacheModule = Module._cache[id];
if(cacheModule){
return cacheModule.exports;
}
let module = new Module(id);
Module._cache[id] = module;
tryModuleLoad(module);
return module.exports;
}