require機(jī)制主要部分實(shí)行流程
require的文件加載和依賴管理確實(shí)非常好用,下面簡單分析其機(jī)制原理
代碼實(shí)現(xiàn)分析
'use strict'
//自己實(shí)現(xiàn)require主要的部分
function?$require(id) {
const?fs = require('fs');
const?path = require('path');
//緩存
$require.cache=$require.cache|| {}
//step1.先找到文件(加載文件的完整路徑)
const?filename = path.join(__dirname, id);
if($require.cache[filename]){
? ??return?$require.cache[filename].exports;
}
//step2.讀取文件腳本內(nèi)容
let code=fs.readFileSync(filename,'utf8');
//step3.執(zhí)行代碼,所要執(zhí)行的代碼匿级,需要營造一個(gè)私人的空間
let module= {id:filename,exports:{} };
let exports=module.exports;?// exports指向module.exports
const?dirname=path.dirname(filename);
code='(function($require, module, exports, __dirname, __filename){ '+code+' })($require, module, exports, dirname,?filename)';
eval(code);
//step4.緩存
$require.cache[filename] =module;
//step5.返回值
return?module.exports;
}
require擴(kuò)展名
require加載文件時(shí)可以省略擴(kuò)展名
比如:require('./module’);
加載優(yōu)先級(jí):
1.加載的目錄中存在module.js文件趟章,則最優(yōu)先加載js文件
2.加載的目錄中存在module.json文件椭豫,如果不存在js文件,此時(shí)優(yōu)先加載json文件解析
3.加載的目錄中存在module.node文件,如果js弧腥、json都不存在厦取,則此時(shí)優(yōu)先加載預(yù)編譯好c++模塊
4.如果上述的文件都不存在,module是文件夾管搪,則
????a)優(yōu)先加載該目錄下package.json中main指向的文件(一般是./module/default.js)
????b)不存在package配置文件虾攻,則就會(huì)直接加載index.js文件
require加載文件規(guī)則
如果參數(shù)字符串不以“./”或者“/”開頭,則表示加載的是一個(gè)默認(rèn)提供的核心模塊(位于Node的系統(tǒng)的安裝目錄)
require(‘fs’); =>加載核心模塊中的文件系統(tǒng)模塊
或者從當(dāng)前目錄向上搜索node_modules目錄中的文件
require(‘my_module’); =>各級(jí)node_modules文件夾中搜索my_module.js文件更鲁。