在Node.js中将公共variables传递到单独模块的最佳方式是什么?

我使用单独的路由器文件作为主应用程序和身份validation应用程序模块。 我不能得到最好的方式来传递variables(数据库客户端)到路由器。 我不想硬编码或传递:

module.exports = function(app, db) { 

也许这是使用单例注册或使用全局数据库variables的最好方法?

什么是你的devise模式的经验? 哪种方式最好,为什么?

我发现使用dependency injection来传递东西,是最好的风格。 这确实看起来像你有:

 // App.js module.exports = function App() { }; // Database.js module.exports = function Database(configuration) { }; // Routes.js module.exports = function Routes(app, database) { }; // server.js: composition root var App = require("./App"); var Database = require("./Database"); var Routes = require("./Routes"); var dbConfig = require("./dbconfig.json"); var app = new App(); var database = new Database(dbConfig); var routes = new Routes(app, database); // Use routes. 

这有很多好处:

  • 它迫使你将系统分离成具有清晰依赖关系的组件,而不是隐藏文件中间的依赖关系,它们被称为require("databaseSingleton")或者更糟糕的是global.database
  • 它使得unit testing变得非常简单:如果我想单独testingRoutes ,我可以注入假appdatabase参数,并且只testingRoutes代码本身。
  • 它将所有的对象图布线放在一个地方,即组合根(在本例中是server.js ,应用程序入口点)。 这给你一个地方,看看如何在系统中的一切都融合在一起。

我所看到的更好的解释之一就是采访 .NET着作“ dependency injection”一书的作者Mark Seeman 。 它同样适用于JavaScript,尤其适用于Node.js: require常常用作传统的服务定位器,而不仅仅是一个模块系统。

我build议你用db实例创build一个设置文件,以及其他你需要在全局中使用的东西,比如“singleton”。

例如,我有我的redis数据库客户端settings.js:

 var redis = require('redis'); exports.redis = redis.createClient(6379, '127.0.0.1'); 

而在其他多个模块中,我将它包括在内:

 var settings = require('./settings'); setting.redis.<...> 

很多时候,我总是有一个db连接的实例。

如果您使用dependency injection框架,您可以节省自己的所有模板代码

这个答案列出了其中的一些。 我也在这里构build了一个更简单的DI框架 。

编辑:下面是一个复制forms的情况下,页面更改的答案


require是在Node.js中pipe理依赖关系方式,当然它是直观和有效的,但也有其局限性。

我的build议是查看一下Node.js中的一些dependency injection容器,以了解它们的优缺点。 他们之中有一些是:

  • 分散
  • 电解液
  • 线
  • 静脉
  • Pongular

仅举几个。

现在真正的问题是,与一个简单的require相比,你能用Node.js DI容器实现什么?

优点:

  • 更好的可testing性:模块接受它们的依赖作为input
  • 控制反转:决定如何连接你的模块而不接触你的应用程序的主代码。
  • 用于parsing模块的可定制algorithm:依赖关系具有“虚拟”标识符,通常它们不绑定到文件系统上的path。
  • 更好的可扩展性:由IoC和“虚拟”标识符启用。
  • 其他花哨的东西可能:
    • asynchronous初始化
    • 模块生命周期pipe理
    • DI容器本身的可扩展性
    • 可以轻松实现更高级别的抽象(例如AOP)

缺点:

  • 不同于Node.js的“体验”:不require使用肯定会感觉你正在偏离Node的思维方式。
  • 依赖与其实现之间的关系并不总是明确的。 依赖关系可以在运行时解决,并受各种参数的影响。 代码变得更难理解和debugging
  • 启动时间较慢
  • 成熟度(目前):目前没有一款解决scheme真的很受欢迎,所以没有太多的教程,没有生态系统,没有经过testing。
  • 一些DI容器在Browserify和Webpack等模块打包程序中效果不佳。

这是完全过时的,但你可以在脚本中使用global

  global.foo = new Foo(); 

在另一个脚本中:

  foo.bar(); 

你也可以使用已经存在的常量:

  Object.foo = new Foo(); 

和这里 :

  Object.foo.bar();