【问题标题】:how to pass a shared variable to downstream modules?如何将共享变量传递给下游模块?
【发布时间】:2014-10-29 00:08:57
【问题描述】:

我有一个节点顶层myapp 变量,其中包含一些关键的应用程序状态——记录器、数据库处理程序和一些其他数据。目录层次结构中的下游模块需要访问这些数据。如何在节点中设置键/值系统来做到这一点?

Express: How to pass app-instance to routes from a different file? 中得到高度评价和接受的答案建议在较低级别的模块中使用

//in routes/index.js
var app = require("../app");

但这注入了目录结构和文件名的硬编码知识,应该是 更大 no-no jimho。是否有其他方法,例如 JavaScript 中的原生方法?我也不喜欢在没有var 的情况下声明变量的想法。

使值可用于在较低范围内创建的对象的节点方式是什么? (我对 node 非常陌生,all-things-node 对我来说还不是很明显)

非常感谢。

【问题讨论】:

标签: node.js


【解决方案1】:

由于使用 node global (docs here) 似乎是 OP 使用的解决方案,所以我想将其添加为官方答案以收集我的宝贵积分。

我强烈建议您为变量命名,例如

global.myApp.logger = { info here }
global.myApp.db = {
   url: 'mongodb://localhost:27017/test',
   connectOptions : {}
}

如果您在 app.js 中并且只想允许访问它

global.myApp = this;

一如既往,谨慎使用全局变量...

【讨论】:

    【解决方案2】:

    这实际上与节点无关,而是与一般软件架构决策有关。

    当您有一个客户端和一个服务器模块/包/类(以您喜欢的方式调用它们)时,一种方法是在服务器模块上定义例程,该例程将客户端保留在“全局”范围内的任何状态数据作为参数,完成其任务并向客户报告结果。

    通过这种方式,它可以完美解耦,您可以严格控制数据的去向。

    希望这会有所帮助:)

    【讨论】:

    • 你是对的。但我试图避免使用像 func(handle, ...) 这样的签名,因为这样就必须将把手拖到任何地方。
    【解决方案3】:

    这样做的一种方法是在匿名函数中 - 即,不要返回 objectmodule.exports,而是返回一个返回适当值的 function

    假设我们想将var1 传递给我们的两个模块./module1.js./module2.js。这是模块代码的外观:

    module.exports = function(var1) {
        return {
            doSomething: function() { return var1; }
        };
    }
    

    那么,我们可以这样称呼它:

    var downstream = require('./module1')('This is var1');
    

    给你你想要的。

    【讨论】:

    • 那行得通,所以我继续我的工作,谢谢。但是如果我重新组织我的代码,现在它是 ./x/module1.js 和 ./module2.js 那么我需要更改任何代码吗?我发现我必须这样做,但有解决方法吗?
    • @Dinesh 除非你想动态地加载一个模块(即你不知道它在哪里),你只需要改变require()里面的字符串。如果你想动态地找到它,那就完全不同了。不要忘记将答案标记为已接受:)
    • .@Brendan 我愿意。我迭代一个特定的目录,找到与特定模式匹配的文件,实例化模块,询问它可以处理的 HTTP 请求类型,并配置两个网络服务器之一。我正在考虑让模块加载并根据各自的功能注册自己。
    • @Dinesh 可以看看node-glob,这可能是你最好的选择。否则,我建议不要让应用程序找到模块。
    • @Brendan 是的,user949300 推荐了它,这正是我所需要的。谢谢。
    【解决方案4】:

    我刚刚创建了一个空模块并将其安装在 node_modules 下作为 appglobals.js

    // index.js
    module.exports = {};
    // package.json too is barebones
    { "name": "appGlobals" }
    

    然后在不担心将来重构的情况下大放异彩:

    var g = require("appglobals");
    g.foo = "bar";
    

    我希望它以 setter/getter 的形式内置,但它的灵活性值得赞赏。

    (现在我只需要弄清楚如何将它打包用于生产)

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-10
    • 1970-01-01
    • 2018-09-07
    相关资源
    最近更新 更多