commonJs规范原理(简版)

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值