最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時間:2016年10月27日 10:49:27   作者:注意_前方高能  
大家都知道Node 采用的模塊化結構是按照 CommonJS 規(guī)范,模塊與文件是一一對應關系,即加載一個模塊,實際上就是加載對應的一個模塊文件。這篇文章顯示簡單的介紹了nodejs中require的加載機制,而后簡單的模擬require函數(shù),有需要的朋友們下面來一起看看吧。

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

1、require的加載文件順序

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

          require('./module');

     // 此時文件按 JS 文件執(zhí)行

          require('./module.js');

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

          require('./module.json');

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

          require('./module.node');

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

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

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

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

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

     通過 / 開頭:則以系統(tǒng)根目錄開始尋找模塊;

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

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

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

     或者從當前目錄向上搜索 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 屬性(不會再次執(zhí)行該模塊)

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

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

二、模擬require函數(shù)

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

require的簡單實現(xiàn)機制為:

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

     讀取這個文件里面的代碼

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

     執(zhí)行該代碼

     拿到module.exports 返回

 nodejs_require.js
 // [require函數(shù)模擬]

 "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、執(zhí)行代碼,所要執(zhí)行的代碼,需要營造一個獨立的空間

 // 定義一個數(shù)據(jù)容器,用容器去裝模塊導出的成員
 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)`;

 // 執(zhí)行代碼
 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();

總結

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

相關文章

  • nodejs學習筆記之路由

    nodejs學習筆記之路由

    因為只是用于本地服務器用于自己測試用,所以不需要太完善的路由功能,所以也就不去使用express框架,而是自己實現(xiàn)一個簡易路由,可以針對自己的需求來定制路由功能。
    2017-03-03
  • node crawler如何添加promise支持

    node crawler如何添加promise支持

    這篇文章主要介紹了node crawler如何添加promise支持,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-02-02
  • Node.js爬取豆瓣數(shù)據(jù)實例分析

    Node.js爬取豆瓣數(shù)據(jù)實例分析

    這篇文章通過實例給大家詳細分析了Node.js爬取豆瓣數(shù)據(jù)的過程以及具體方法步驟,有興趣的朋友可以參考學習下。
    2018-03-03
  • Node.JS發(fā)送http請求批量檢查文件中的網(wǎng)頁地址、服務是否有效可用

    Node.JS發(fā)送http請求批量檢查文件中的網(wǎng)頁地址、服務是否有效可用

    這篇文章主要介紹了Node.JS發(fā)送http請求批量檢查文件中的網(wǎng)頁地址、服務是否有效可用,本文通過實例代碼文字說明給大家講解的非常詳細,需要的朋友參考下
    2019-11-11
  • Node.js使用Koa搭建 基礎項目

    Node.js使用Koa搭建 基礎項目

    時下前端工程師有很多人比較關注NodeJs以及express 框架或者Koa 框架之類的新技術。難得我最近閑時較多,利用一下舊歷新年尚未正式到來的這片閑暇,也來涉足其中,一窺其中奧妙。
    2018-01-01
  • node.js中的buffer.Buffer.isEncoding方法使用說明

    node.js中的buffer.Buffer.isEncoding方法使用說明

    這篇文章主要介紹了node.js中的buffer.Buffer.isEncoding方法使用說明,本文介紹了buffer.Buffer.isEncoding的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • 使用socket.io制做簡易WEB聊天室

    使用socket.io制做簡易WEB聊天室

    這篇文章主要為大家詳細介紹了使用socket.io制做簡易WEB聊天室,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • node版本沖突問題的解決方案

    node版本沖突問題的解決方案

    因為項目用的依賴和要運行環(huán)境的node.js版本起了沖突,下面這篇文章主要給大家介紹了關于node版本沖突問題的解決方案,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • 使用Node.js的async和await進行異步編程

    使用Node.js的async和await進行異步編程

    使用異步編程可以提高Node.js應用程序的性能,而async和await是Node.js中實現(xiàn)異步編程的一種簡單且易于使用的方式,可以幫助開發(fā)者避免回調(diào)地獄和處理異步操作時的錯誤
    2023-05-05
  • node基于async/await對mysql進行封裝

    node基于async/await對mysql進行封裝

    這篇文章主要介紹了node基于async/await對mysql進行封裝,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,,需要的朋友可以參考下
    2019-06-06

最新評論

浮梁县| 湖南省| 禄丰县| 桃园县| 锦屏县| 洛阳市| 青浦区| 雷山县| 兰溪市| 舟曲县| 虎林市| 图木舒克市| 千阳县| 宣恩县| 乐山市| 澄江县| 新闻| 寿阳县| 绥宁县| 湘阴县| 防城港市| 阿克陶县| 宣恩县| 汉川市| 宁安市| 邯郸市| 乌恰县| 蒙山县| 吉安县| 启东市| 乐至县| 铜鼓县| 平阴县| 望奎县| 太湖县| 新丰县| 南木林县| 旅游| 台江县| 英德市| 锦屏县|