最近一直在使用Node JS,在網上看到了一段代碼我覺得完美的诠釋了Node JS模塊加載的原理,其實深究下去,它還诠釋了許多東西:Js模塊化編程、閉包的真正強大之處等等。閒話不說,先看看這段代碼:
// - hello.js
void function() {
var mapping = {}, cache = {};
window.define = function(id, func) {
mapping[id] = func
};
window.require = function(id) {
if (!/\.js$/.test(id)) {
id += ".js"
}
if (cache[id]) {
return cache[id]
} else {
return cache[id] = mapping[id]()
}
}
}();
define("js/module/hello.js", function(exports) {
exports = {}; var name = 'Hello Module'
exports.sayHi = function() {
alert("Hi, this is "+ name +" !")
};
return exports
});
// - main.js
var hello = require('js/module/hello');
hello.sayHi();
我稍微改寫了一點代碼,為了能看得更清楚一些,這段代碼在全局對象window上綁定了兩個方法:define和require,寫過Node代碼的人肯定不會陌生,當我需要一個模塊的時候,就會使用require來加載它,可能是原生模塊例如http, express等,也可能是自己寫的Js文件模塊用相對路徑加載。Node在實現模塊加載的時候,就會使用優先本地查找node_modules目錄,然後一層層往上找,最後再按環境變量在安裝node的目錄執行全局模塊查找,PS: 自己寫的業務模塊一般都使用相對路徑require('./business')來查找。當Node找到模塊之後,第一次加載會比較緩慢,但是一旦加載就會緩存起來,類似我們這裡做的cache和map的作用,再查找就會快很多。所以Node使用require加載模塊第一次是阻塞式的,緩存之後就應該是異步非阻塞式的。
我們之所以可以通過require實現Js的模塊化編程,完全得益於閉包的存在。閉包可以使得我們在傳遞函數調用結束,返回函數對象之後,依然可以訪問其中的局部變量,就像例子中的name一樣,假如它是一個數據庫Connection對象,或者是一個業務Service對象,那麼通過exports,就可以在其他Js文件中使用它並且代碼從文件上是完全隔離的。
Node.Js入門[PDF+相關代碼] http://www.linuxidc.com/Linux/2013-06/85462.htm
Node.js入門開發指南中文版 http://www.linuxidc.com/Linux/2012-11/73363.htm
Node.js安裝與配置 http://www.linuxidc.com/Linux/2013-05/84836.htm
Ubuntu 編譯安裝Node.js http://www.linuxidc.com/Linux/2013-10/91321.htm
Node.js 的詳細介紹:請點這裡
Node.js 的下載地址:請點這裡