require 实现原理 mini 版
const fs = require('fs');
const path = require('path');
const vm = require('vm');
function Module(id) {
this.id = id;
this.exports = {};
}
Module._cache = {};
Module._extensions = {
'.json'(module) {
let scripts = fs.readFileSync(module.id, 'utf-8');
module.exports = JSON.parse(scripts);
},
'.js'(module) {
let script = fs.readFileSync(module.id, 'utf-8');
let templateFn = `(function(exports,module,require,__filename,__dirname){${script}})`;
let fn = vm.runInThisContext(templateFn);
let exports = module.exports;
let thisValue = exports;
let filename = module.id;
let dirname = path.dirname(filename);
fn.call(thisValue,exports,module,req,filename,dirname);
}
}
Module._resolveFilename = function (id) {
let filepath = path.resolve(__dirname, id);
let isExists = fs.statSync(filepath);
if (isExists) return filepath;
let keys = Object.keys(Module._extensions);
for (let i = 0; i < keys.length; i++) {
let newPath = filepath + keys[i];
if (fs.statSync(newPath)) return newPath;
}
throw new Error("module not found!");
}
Module.prototype.load = function () {
let extname = path.extname(this.id);
Module._extensions[extname](this);
}
function req(filename) {
filename = Module._resolveFilename(filename);
let cacheModule = Module._cache[filename];
if (cacheModule) return cacheModule.exports;
const module = new Module(filename);
Module._cache[filename] = module;
module.load();
return module.exports;
}
const test = req('./test.js');
req('./test.js')
req('./test.js')
console.log(test);