node:如何根据env

时间:2017-06-27 00:58:35

标签: node.js dependencies

在节点中,模块导入(aka require())在每个需要导入的文件(aka模块)中进行硬编码。这可能是数十或在我们的情况下数百个重复导入。我们是什么"要求"以动态方式主要是服务,例如" playerService"查找,更新,获取方法等,但也可以是域对象或持久性库

关键是我们有3个版本" playerService" js文件。在本地(在内存中)进行开发的一切,一个用本地数据库(测试)完成所有事情,一个用外部系统通过API(实时)完成所有事情。在这种情况下,开关在环境(开发,测试或实时)上。

值得注意的是,我们在任何地方都可以使用类,因为我们发现返回函数等函数的函数是不可读/可维护的(我们是java开发人员真的在与js斗争)

我们也在我们的节点应用程序中专门使用Web套接字 - 没有http代码。

所以我们的服务看起来像这样:

const Player = require("./player")
class PlayerService {
  constructor(timeout) {
     this.timeout= 3000  // todo, put in a config file
     if (timeout != null) {this.timeout= timeout}
  }
  updatePlayer(player) {
     // logic to lookup player in local array and change it for dev version.
     // test version would lookup player in DB and update it.
  }
}
module.exports = PlayerService

我们熟悉Grails和spring的依赖注入,但是找不到任何可以理解的节点(见下文)。不幸的是,我们不是javascript,也不是节点专家,尽管阅读量很大。

目前我们正在考虑其中一个选项,但我们希望听到更好的建议:

选项1:

  1. 硬编码" dev"需要,例如,要求(" ./开发/ playerSerice&#34)
  2. 让jenkins构建服务器在每个要求的文件中重写源代码(" ./ test / playerSerice")。
  3. 选项2:

    1. 硬编码" dev"需要,例如,要求(" ./ playerSerice&#34)
    2. 有一个jenkins构建服务器交换文件/ test / playerService / playerService"到./playerService。
    3. 显然,这些使得开发人员很难在本地计算机上运行测试版或专业版,而不会破坏源代码。

      选项3:  1.将所需的模块路径放在一个配置文件中。  2.换掉配置文件。 E.g。

      let Config = require("./config")
      let PlayerService = require(Config.playerService)
      

      我们已经尝试使这依赖于env并且有一个全局配置,开发,测试和prod配置这些,但没有找到一个优雅的方式来做到这一点。一种方法可能是在每个模块的顶部复制此代码:

      let env = process.env.NODE_ENV || 'development'
      let config = require('./config.'+env);
      let PlayerService = require("./" + Config.playerService)
      

      然后在config.development.js:

      var config = require("./config.global")
      config.PlayerService = "devPlayerService"
      module.exports = config
      

      选项4: 也许这样的事情会起作用:

      let env = process.env.NODE_ENV || 'development'
      require("./" + env + "/playerService")
      

      以上所有解决方案都缺乏单身人士 - 服务是无国籍的。我们猜测该节点将为每个请求构建每个服务的新副本(或者在我们的例子中为Web套接字消息)。有没有办法减少这个?

      显然,一些简单,可读和正式维护的依赖注入形式会很好,有一些方法可以在注入哪组类之间切换。

      我们已阅读以下帖子:

      1. https://blog.risingstack.com/dependency-injection-in-node-js/结果代码无法读取(至少对我们而言)。这样做的例子并没有帮助,团队只是围绕用户的某种代理包装,而不是服务或任何有用的东西。有什么选择?为什么选择?
      2. https://medium.com/@Jeffijoe/dependency-injection-in-node-js-2016-edition-f2a88efdd427
      3. 但是发现他们难以理解。例如。这些例子的关键词来自空气稀薄 - 它们似乎不是javascript或节点命令,并且在它们来自的文档中没有解释。

        看了看这些项目:

        1. https://github.com/jaredhanson/electrolyte
        2. https://www.npmjs.com/package/node-dependency-injection
        3. https://www.npmjs.com/package/di
        4. 但他们似乎要么被遗弃(di),要么没有维持,或者我们只是无法解决它们(电解质)。

          是否存在许多人正在使用的标准或简单的解决方案,理想情况下记录为凡人和非"表达"依赖的例子?

          更新1

          我用来创建服务的模式似乎在使用/调用时创建了一个新实例。服务应该是单身人士。简单的解决方案是将其添加到我的服务底部:

          let playerService = new PlayerService();
          module.exports = playerService;
          

          显然,这只会创建一个对象实例,无论现在多次要求(" ./ playerService")都被调用。

1 个答案:

答案 0 :(得分:1)

为了保持每个env的配置,正确的方法可能(类似于你的建议) - 保持config / env目录并为每个env放置一个文件,即development.js,test.js等,并在每个他们把正确的价值观。例如:

module.exports = {
   playerService: 'dev/PlayerService'
}   

并要求:

let env = process.env.NODE_ENV || 'development'
, envConfig = require("./config/" + env)
, playerService = require(envConfig.playerService)

你也可以像这样在一个文件中: config.js:

module.exports = {
    development:{
        playerService: '....'
    },
    test:{
        playerService: '....'
    }
}

并要求:

let env = process.env.NODE_ENV || 'development'
, config = require("./config")
, playerService = require(config[env][playerService])

这是一个常见的用例。

或者,如果你在每个env的目录中有所有服务,即一个目录用于开发,一个用于测试等,你不需要配置,你可以这样要求:

 let env = process.env.NODE_ENV || 'development'
, playerService = require('./' + env + '/playerServcie')  

在节点js中创建服务单例应该很简单,请看下面的内容:

https://blog.risingstack.com/fundamental-node-js-design-patterns/

https://www.sitepoint.com/javascript-design-patterns-singleton/

and this

希望这有帮助。