1.前端模块化Commonjs的基本原理实现
const path = require('path');
const fs = require('fs')
const vm = require('vm')
function Module(id){
this.id = id
this.exports = {}
}
Module._extensions = {
'.js':function(module){
let sourceJson = fs.readFileSync(module.id)
let wrapper = ['(function(exports,module,require,_dirname,_filename){','})']
const script = wrapper[0] + sourceJson + wrapper[1]
console.log(script);
let fn = vm.runInThisContext(script);
let exports = module.exports;
let dirname = path.dirname(module.id)
fn.call(exports,exports,module,req,dirname,module.id)
},
'.json':function(module){
console.log(module);
let contentJson = fs.readFileSync(module.id)
module.exports = JSON.parse(contentJson);
}
}
Module._resolveFileName = function(id){
let filePath = path.resolve(id)
if( fs.existsSync(filePath) ){
return filePath
}
let exts = Object.keys(Module._extensions);
for (let index = 0; index < exts.length; index++) {
let p = filePath+exts[index]
if( fs.existsSync(p) ){
return filePath;
}
}
throw new Error('模块不存在~')
}
Module._cache = {
}
Module.prototype._load = function(id){
let extensions = path.extname(this.id);
Module._extensions[extensions](this)
}
function req(id){
let filePath = Module._resolveFileName(id);
if( Module._cache[filePath] ){
return Module._cache[filePath].exports;
}
let module = new Module(filePath)
Module._cache[filePath] = module;
module._load(filePath)
return module.exports;
}
let r = req('a.js')
r = req('a.js')
r = req('a.js')
console.log(r);