淺談Node模塊載入機制/CommonJS規範

平時總會用到require和module.exports來載入和使用模塊,但對原理並不了解,查了下資料豁然開朗。

問題1: module到底是什麼,module.exports和exports有什麼區別?

其實module和exports可以理解成一個js文件自帶的對象,module.exports和exports這兩個對象保存的地址是相等的,指向堆內存中的一部分。

我們可以實驗一下,新建文件test.js

console.log(module);nconsole.log(exports);nconsole.log(module.exports === exports);n

$node test.jsnModule {n id: .,n exports: {},n parent: null,n filename: C:messiahtest.js,n loaded: false,n children: [],n paths: [ C:messiahnode_modules, C:node_modules ] }n {}n truen

問題2:require函數到底做了什麼?

其實就是把被require的js文件中的代碼放進了一個立即執行函數里,並return module.exports

比如test.js文件如下

var a = {n name: xiaoming,n age: 16n}nnvar b = 123;n

1.js文件如下

var a = require(./test.js);n

那麼,1.js文件可以看成

var a = (function() {n var a = {n name: xiaoming,n age: 16n }nn var b = 123;n n return module.exports;n})()n

這裡也解釋了為什麼不要直接給exports賦值。因為我們知道,對象中保存的其實是指向堆內存中內存的地址。

補充:一般模塊分為核心模塊,第三方模塊,本地模塊。

核心模塊比如http, fs, url等模塊。第三方模塊比如pm2 mysql等,第三方模塊可以全局安裝(npm install pm2 -g)和本地安裝(npm install pm2)。本地模塊就是自己寫的模塊。

當我們require模塊的時候,加不加路徑也是有區別的。

如果我們不加路徑,比如require(http),Node會依次在內置模塊、全局模塊和當前模塊下查找模塊。

加路徑一般都是用來載入本地模塊,比如require(./test)

推薦閱讀:

代碼質量檢測平台架構設計
陰陽師將大量伺服器運算放在客戶端完成是否可能?
雜談 Web 前端編程範式
Webpack構建library時的踩坑經歷

TAG:前端开发 | Nodejs | CommonJS |