本文轉自Node.js module.exports與exports
做者: chemdemojavascript
折騰Node.js有些日子了,下面將陸陸續續記錄下使用Node.js的一些細節。java
熟悉Node.js的童鞋都知道,Node.js做爲服務器端的javascript運行環境,它使用npm做爲通用的包管理工具,npm遵循CommonJS規範定義了一套用於Node.js模塊的約定,關於npm實現Node.js模塊的更多細節請細讀深刻Node.js的模塊機制,這裏簡單講下書寫Node.js代碼時module.exports與exorts的區別。git
在瀏覽器端js裏面,爲了解決各模塊變量衝突等問題,每每藉助於js的閉包把全部模塊相關的代碼都包裝在一個匿名函數裏。而Node.js編寫模塊至關的自由,開發者只須要關注require,exports,module等幾個變量就足夠,而爲了保持模塊的可讀性,很推薦把不一樣功能的代碼塊都寫成獨立模塊,減小各模塊耦合。開發者能夠在「全局」環境下任意使用var申明變量(不用寫到閉包裏了),經過exports暴露接口給調用者。github
咱們常常看到相似export.xxx = yyy
或者module.exports = xx
這樣的代碼,可實際在經過require
函數引入模塊時會出現報錯的狀況,這是什麼緣由致使的呢?npm
Node.js在模塊編譯的過程當中會對模塊進行包裝,最終會返回相似下面的代碼:瀏覽器
(function (exports, require, module, __filename, __dirname) { // module code... });
其中,module就是這個模塊自己,require是對Node.js實現查找模塊的模塊Module._load實例的引用,__filename和__dirname是Node.js在查找該模塊後找到的模塊名稱和模塊絕對路徑,這就是官方API裏頭這兩個全局變量的來歷。服務器
關於module.exports與exorts的區別,瞭解了下面幾點以後應該就徹底明白:閉包
模塊內部大概是這樣:函數
exports = module.exports = {};
假若有模塊a.js代碼以下:工具
exports.str = 'a'; exports.fn = function() {};
對a模塊的調用:
var a = require('./a'); console.log(a.str); console.log(a.fn());
這樣用是對的,若是改造a以下:
exports.str = 'a'; exports = function fn() {};
在調用a模塊時天然沒用fn屬性了。
再改造下a模塊:
exports.str = 'a'; module.exports = function fn() {};
這時a模塊其實就是fn函數的引用,也就是說能夠require('./a')()這樣使用,而同時再也不有str屬性了。
下面直接導出一個類:
module.exports = function A() {};
調用:
var A = require('./a'); var a = new A();
總結下,有兩點: