2011-04-17 60 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

相关问题