nodejs之模塊加載機制

 

nodejs模塊加載原理

node加載模塊步驟:node

  1) 路徑分析 (如判斷是否是核心模塊、是絕對路徑仍是相對路徑等)c++

  2) 文件定位 (文件擴展名分析, 目錄和包處理等細節)json

  3) 編譯執行 數組

 

原生模塊加載順序緩存

  1) 緩存app

  2) 本地原生模塊函數

 

文件模塊加載順序

  1) 緩存ui

  2) 若是是絕對路徑, 則直接按路徑讀取並編譯spa

  3) 若是是「/」則直接從/node_modules目錄查找code

  4) 若是是相對路徑, 則生成以下查詢規則,

[
    '/home/myapp/mydir/node_module',
    '/home/myapp/node_module'   
    '/home/node_module',
    '/node_module'
]

 

  5) 從上述數組中取出第一個目錄做爲查找對象, 若是存在結束查找

  6) 而後依次嘗試添加.js、.json、.node後綴繼續查找, 若是存在則結束

  7) 嘗試將require參數做爲一個包查找, 讀取目錄下的package.json文件, 取得main參數指定的文件

  8) 根據指定的文件未找到, 若是沒有,執行第6步

  9) 若是main參數不存在或者第8步未找到, 則查找該目錄下index文件, 若是沒有, 執行第6步

  10) 若是依然沒有找到, 則開始取出數組第二條路徑, 而後執行5-7步。 直到數組中最後一個值

  11) 若是還沒找到, 拋出異常

 

至此, 文件終於找到了。。。而後呢?找到後該作什麼呢?

也許有的人早就發現一個問題, require函數是哪裏來的呢?模塊中明明沒有定義啊, 爲何就能使用了呢? 

有的同窗立刻回答說, 它是個全局的。。。全局的?那這個所謂全局的又在哪定義的呢? 額。。。不知道。。。

 

require到底哪裏來的呢?

上面咱們已經通過重重困難終於找到了咱們的文件, 下一步就是咱們的編譯

node針對不一樣後綴的文件分類編譯

1) .js文件的編譯

  .js文件的編譯源碼比較複雜, 其最終編譯後會包裝成以下結構

(function (exports, require, module, __filename, __dirname) {
    var math = require('math');
    exports.area = function(radius) {
       return Math.PI * radius * radius;
    }
})

  如今知道爲何有require, exports, module這些函數或對象了吧。。。

 

2) .json文件的編譯

  .json的文件最爲簡單, 其實就是調用JSON.parse。下爲node源碼

Module._extensions['.json'] = function(module, filename) {
  var content = fs.readFileSync(filename, 'utf8');
  try {
    module.exports = JSON.parse(internalModule.stripBOM(content));
  } catch (err) {
    err.message = filename + ': ' + err.message;
    throw err;
  }
};

 

3) .node文件的編譯

  .node是c/c++模塊, 在此不深究, 附上源碼

Module._extensions['.node'] = function(module, filename) {
  return process.dlopen(module, path._makeLong(filename));
};
相關文章
相關標籤/搜索