国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

簡單模擬node.js中require的加載機制

2019-11-20 08:38:58
字體:
來源:轉載
供稿:網友

一、先了解一下,nodejs中require的加載機制

1、require的加載文件順序

require 加載文件時可以省略擴展名:

          require('./module');

     // 此時文件按 JS 文件執行

          require('./module.js');

     // 此時文件按 JSON 文件解析

          require('./module.json');

     // 此時文件預編譯好的 C++ 模塊執行

          require('./module.node');

     // 載入目錄module目錄中的 package.json 中main指向的文件

          require('./module/default.js');

     // 載入目錄module 中的index.js文件

     通過 ./ 或 ../ 開頭:則按照相對路徑從當前文件所在文件夾開始尋找模塊;

         require('../file.js'); => 上級目錄下找 file.js 文件

     通過 / 開頭:則以系統根目錄開始尋找模塊;

          require('/Users/iceStone/Documents/file.js'); => 以絕對路徑的方式找,沒有任何異議

     如果參數字符串不以“./“ 或 ”/“ 開頭,則表示加載的是一個默認提供的核心模塊(位于 Node 的系統安裝目錄中):

          require('fs'); => 加載核心模塊中的文件系統模塊

     或者從當前目錄向上搜索 node_modules 目錄中的文件:

          require('my_module'); => 各級 node_modules 文件夾中搜索 my_module.js 文件;

     如果 require 傳入的是一個目錄的路徑,會自動查看該目錄的 package.json 文件,然后加載 main 字段指定的入口文件

     如果package.json文件沒有main字段,或者根本就沒有package.json文件,則默認找目錄下的 index.js 文件作為模塊:

          require('./calcuator'); => 當前目錄下找 calculator 目錄中的 index.js 文件

2、require緩存

     第一次加載某個模塊時,Node 會緩存該模塊。以后再加載該模塊,就直接從緩存取出該模塊的 module.exports 屬性(不會再次執行該模塊)

     如果需要多次執行模塊中的代碼,一般可以讓模塊暴露行為(函數),模塊的緩存可以通過 require.cache 拿到,同樣也可以刪除

3、所有代碼都運行在模塊作用域,不會污染全局作用域。

二、模擬require函數

require的加載內部比較復雜,下面讓我們進行簡單的模擬加載

require的簡單實現機制為:

     將傳入的模塊id通過加載規則找到對應的模塊文件

     讀取這個文件里面的代碼

     通過拼接方式為該段代碼構建私有空間

     執行該代碼

     拿到module.exports 返回

 nodejs_require.js // [require函數模擬] "use strict" function $require(id) { //1、先查看模塊是否存在,如果不存在則拋出 Can't found file //2、如果存在,就讀取代碼 const fs = require('fs'); const path = require('path'); // 文件名 let filename = id; //查看是否是絕對路徑 if (!path.isAbsolute(filename)) {  filename = path.join(__dirname, id); } // 文件目錄 let dirname = path.dirname(filename); //模擬require的緩存機制 $require.cache = $require.cache || {}; if($require.cache[filename]){  return $require.cache[filename].exports; } // 讀取模塊代碼 let code=""; try {  code = fs.readFileSync(filename,'utf-8'); // 阻塞讀取文件,不會放入事件隊列  } catch (error) {  console.log(" [*]can't found file! ");  throw error; } // console.log(code); // 3、執行代碼,所要執行的代碼,需要營造一個獨立的空間 // 定義一個數據容器,用容器去裝模塊導出的成員 let _module = { // 每個js模塊都會有一個全局的module變量  id:'.',  exports:{},  parent:module,  filename:filename }; let _exports = _module.exports; // 營造一個獨立空間 code = `(function($require,module,_exports,__dirname,__filename){  $[code] })($require,_module,_exports,dirname,filename)`; // 執行代碼 eval(code); // 緩存 $require.cache[filename] = _module; // 返回結果 return _module.exports; } setInterval(()=>{  const rr = $require("./test.js");  console.log(rr); },1000);

上面的模塊測試使用的兩個模塊

 //test.js const date = $require('./date.js'); console.log(module); module.exports = date; //date.js module.exports = new Date();

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临江市| 夏津县| 长葛市| 泗洪县| 巨鹿县| 城固县| 潍坊市| 江孜县| 平山县| 正阳县| 汉寿县| 昌黎县| 古交市| 临泉县| 漳州市| 望江县| 黄山市| 安陆市| 谢通门县| 兴宁市| 苗栗市| 双桥区| 舒兰市| 项城市| 宁海县| 石首市| 本溪市| 彰武县| 乌什县| 周口市| 滨海县| 棋牌| 昔阳县| 潢川县| 柳河县| 永丰县| 江永县| 道孚县| 广安市| 通江县| 南靖县|