node加載模塊分爲3個步驟
1.路徑查找
2.文件定位
3.模塊編譯node
1.路徑查找
經過module.paths能夠看出,文件查找是先查找當前目錄的node_modules,而後查找父目錄的node_modules,而後逐級向上查找c++
2.文件定位
若是require傳參沒有文件擴展名,那麼node會按.js .json .node 的順序查找文件
若是沒有查找到對應文件,node會把對應目錄做爲包處理,查找目錄下pageage.json文件,用JSON.parse()處理,而後查找到main屬性,根據main屬性進行文件定位,若是main屬性沒有文件拓展名,依然按照.js .json .node 順序查詢。若是main屬性文件指定的文件名錯誤,或者壓根沒有pageage.json,node會將index做爲默認文件名,按照.js .json .node 依次進行查找,若是尚未定位到,將進入下一個模塊路徑查找,所有遞歸後,若是尚未找到,將會拋出查詢失敗異常。json
3.模塊編譯
編譯分爲三種狀況,js模塊、c/c++模塊、json模塊
Js模塊
每一個模塊都有默認變量,exports、module、require、__filename、__dirname。這些變量的來源是在編譯過程,對文件進行收尾處理緩存
function(exports、module、require、__filename、__dirname){ /*文件內容*/ }
exports和module.exports的區別
exports是module.exports的引用,若是直接對exports進行復制,只是改變了exports的指向,可是對於module.exports是沒有任何改變的。因此咱們不能直接對exports進行賦值,應該對exports的屬性賦值。
c/c++模塊
由於是c/c++編寫,因此該模塊並不須要編譯,而是直接進行加載和執行。
經過調用process.dlopen()方法執行。
json模塊
node直接經過fs模塊同步讀取json文件,而後經過JSON.parse()進行轉換,後賦值給module.exports。ui
模塊緩存
核心模塊編譯成功後緩存在NativeModule._cache下
文件模塊編譯成功後緩存在Module._cache下code