2011-04-17 70 views
33

我正在使用Node.js處理一個項目,並且服務器端代碼變得足夠大,我想將它分解爲多個文件。看起來這已經完成了很長時間的客戶端,開發是通過爲每個文件插入一個script標籤完成的,並且僅用於分發就像用於將所有內容放在一起的「Make」。我意識到將所有的服務器端代碼進行連接是沒有意義的,所以我不會問如何去做。我能找到的最接近的東西是require(),但它的行爲不像script在瀏覽器中那樣require'd文件不共享通用名稱空間。如何使用Node.js管理多個JS文件服務器端

看看一些較舊的Node.js項目,如Shooter,看來這曾經不是這種情況,或者我錯過了我的代碼中非常簡單的東西。我的require'd文件不能在編譯時訪問全局調用名稱空間,也不能運行時。有沒有簡單的方法解決這個問題,還是我們不得不讓所有需要的JS文件完全獨立於調用範圍?

回答

47

因爲全局變量是邪惡的,所以不需要通用的命名空間。在節點我們通過寫exports定義模塊

// someThings.js 

(function() { 
    var someThings = ...; 

    ... 

    module.exports.getSomeThings = function() { 
     return someThings(); 
    } 

}()); 

// main.js 

var things = require("someThings"); 
... 
doSomething(things.getSomeThings()); 

你定義一個模塊,然後暴露你的模塊的公共API。

處理此問題的最佳方法是依賴注入。你的模塊公開了一個init函數,並將一個對象散列的依賴關係傳遞給你的模塊。

如果你真的堅持訪問全球範圍,那麼你可以通過global訪問。每個文件都可以寫入並讀取到global對象。你再也不想使用全局變量。

+0

感謝您的信息,標記爲正確的。我普遍認同全球化==邪惡的概念,但似乎他們確實有自己的位置。例如,如果我有一個基本屬性,我想爲給定的「類」設置一個依賴於其他值的值。例如: 'SomeClass.prototype.baseProp = SomeOtherClass.prototype.prop * 2;' 在這種情況下,我不得不通過構造函數將它設置爲對象實例化,或者,按照您的建議使用'global'對象。我認爲後者可能是最合適的。 – 2011-04-18 14:18:16

+2

@XHR然後'SomeClass'對SomeClass.js中的SomeOtherClass有依賴關係,並且你需要(SomeOtherClass)''。我的代碼中有一個全局變量。 'global._ = require(「underscore」)'因爲我使用它_every_單個文件。這是'global'唯一的用例。 – Raynos 2011-04-18 15:30:05

29

重新@Raynos answer,如果模塊文件旁邊,包括它的文件,它應該是

var things = require("./someThings"); 

如果模塊上公佈,並通過安裝,NPM,或者明確地投入./node_modules/文件夾,那麼

var things = require("someThings"); 

是正確的。

+4

如果您需要一個實際的節點模塊(通過npm安裝,安裝在PROJECT_ROOT/node_modules下),則需要第二行代碼。 如果您需要自己的文件(即ROOT_DIR/models/thing.js),則需要執行第一行代碼(儘管可以將.js擴展刪除)。 – 2012-07-05 17:46:10

+0

我並不積極,但您可以使用[require對象的擴展屬性](http://nodejs.org/api/globals.html#globals_require_extensions)來改變此行爲。 – snapfractalpop 2013-05-14 17:41:05

+0

感謝您的更正,我更新了它。 – michielbdejong 2015-04-16 06:04:59