在节点中,模块导入(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:
选项2:
显然,这些使得开发人员很难在本地计算机上运行测试版或专业版,而不会破坏源代码。
选项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套接字消息)。有没有办法减少这个?
显然,一些简单,可读和正式维护的依赖注入形式会很好,有一些方法可以在注入哪组类之间切换。
我们已阅读以下帖子:
看了看这些项目:
但他们似乎要么被遗弃(di),要么没有维持,或者我们只是无法解决它们(电解质)。
是否存在许多人正在使用的标准或简单的解决方案,理想情况下记录为凡人和非"表达"依赖的例子?
我用来创建服务的模式似乎在使用/调用时创建了一个新实例。服务应该是单身人士。简单的解决方案是将其添加到我的服务底部:
let playerService = new PlayerService();
module.exports = playerService;
显然,这只会创建一个对象实例,无论现在多次要求(" ./ playerService")都被调用。
答案 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/
希望这有帮助。