【问题标题】:How to correctly modularize a node.js project?如何正确模块化 node.js 项目?
【发布时间】:2014-04-24 06:25:57
【问题描述】:
我正在按照类构造函数模式创建一个 node.js 项目:
function my_class(x,y){
this.x = x;
this.y = y;
}
项目的起点是main.js 文件。项目的任何类都必须能够访问在main.js 上定义的全局对象(例如“world”和“socket”)。我找到了 4 个选项:
我在main.js 中定义了我的类。他们可以访问main.js 的全局变量,因为它正在关闭,但main.js 会变得臃肿。
我将类移动到另一个文件,例如my_class.js 和require()。这不起作用,因为 my_class 的实例将丢失闭包上下文并且不再能够访问 main.js 的全局变量。
我将类移动到另一个文件并手动将依赖项注入它的构造函数(例如:my_class(world,socket))。问题是,代码变得更加复杂和奇怪的语义,例如“my_instance.world”在源上弹出,这是无稽之谈,因为“世界”不是my_class的属性。
我将类移动到另一个文件并要求它使用my_class = eval(fs.readFileSync(()) 而不是require。这很好用,因为 my_class 获得了 main.js 的闭包上下文,并且是我正在使用的解决方案,但看起来很老套。
模块化这样的node.js项目的正确方法是什么?
【问题讨论】:
标签:
javascript
node.js
require
modularity
【解决方案1】:
如果我理解正确,可能的解决方案:
main.js:
(function(){
var global = "test"; // this you wanna have as a closure
var my_class = require('./my_class')(global);
my_class.go();
})();
my_class.js:
module.exports = function(global){
return {
go: function(){
console.log(global);
}
};
};
所以它类似于你的 3. 选项
【解决方案2】:
你的问题看起来很棘手,因为你有一个循环依赖:main.js 依赖于my_class 的功能,my_class 依赖于main.js 的数据。
通过将main.js 的数据放入global 对象中,可以解决循环依赖:
-
main.js 取决于 my_class.js 的功能
-
main.js 依赖于 global 对象中的数据
-
my_class.js 依赖于 global 对象中的数据
现在,为了避免将数据放入global 对象,实现第三个模块让我们说data.js。然后你需要这样的来源:
-
main.js 需要 data.js
-
main.js 需要 my_class.js
-
my_class.js 需要 data.js
由于 node.js 中的模块是单例,main.js 和 my_class.js 都将获得相同的 data.js 实例。
【解决方案3】:
如果您想让 main.js 中的变量在任何地方都可用,那么您可以将属性分配给 global 对象。看到 node.js 全局变量了吗?例如。只要您不过度使用它就可以正常工作。使用 Neo 的解决方案,您可以获得更多的灵活性,例如测试,因为您可以将任意对象“注入”到模块中。并非每个模块本身都必须使用相同的“全局”。