将对象附加到 Node.js 进程
Attaching object to Node.js process
我正在为我的 node.js Express 网络服务器使用名为 nconf
的环境变量和参数解析模块。
https://github.com/indexzero/nconf
我认为使 nconf 数据全局化的最佳方法是简单地将其附加到进程变量(如 process.env 中所示),这是好主意还是坏主意?它会在权衡 "process" 时减慢执行速度吗?
这是我的代码:
var nconf = require('nconf');
nconf.argv()
.env()
.file({ file: './config/config.json' });
nconf.defaults({
'http': {
'port': 3000
}
});
process.nconf = nconf;
//now I can retrieve config settings anywhere like so process.nconf.get('key');
坦率地说,我有点喜欢这个解决方案。现在我可以在任何地方检索配置数据,而不需要一个模块。但这可能有缺点……这很可能是一个非常糟糕的主意。 IDK.
不会减慢执行速度,但感觉"smelly"。很难发现,也很难测试,如果您决定需要的话。
更好的解决方案是将设置附加到模块并使用 require() 在需要的地方导入它。
最好的解决方案是将您的设置对象传递给 类 或需要它的模块。直接或作为某种 "global context".
的一部分
例如
var global = {
settings: {
port: 8080
}
}
//...
global.api = new Api(global);
//...
function Api(global) {
var port = global.settings.port;
}
更新:关于为什么原始模式不好的更多信息:
1) 可发现性
您将设置附加到 process.settings
并转到另一个项目。一年后,其他人接手,或者您需要更新内容。您还记得您将设置附加到 process.nconf
吗?还是 process.settings
?
现在假设您有 10 个不同的全球事物,以不同的名称连接在不同的地方。
它没有直接附加到全局上下文那么糟糕,但是清楚地看到您正在使用的东西来自哪里(构造函数或模块)肯定更好。
2) 测试
您决定需要测试您的模块。所以现在您需要为每个测试调整您的设置,而不是从文件或 argv 加载它们。你是怎么做到的?
如果是全局 process.nconf
或 require("settings")
模式,您需要执行以下操作:
function canOpenAPIOnTheConfiguredPort(done) {
var nconfSaveApiPort = process.nconf.api.port;
process.nconf.api.port = '1234';
var api = new Api();
test.assertEqual(api.port, '1234');
process.nconf.api.port = nconfSaveApiPort;
done();
}
随着您的应用程序的增长,这很快就会变得烦人(例如,想象一下必须模拟 10 个东西)。相比之下,这是使用依赖注入(构造函数)模式的方法。
function canOpenAPIOnTheConfiguredPort(done) {
var api = new Api({
port: '1234'
});
test.assertEqual(api.port, '1234');
done();
}
注意 nconf 是一个单例。
我习惯在程序的最开始进行配置,然后当我需要在另一个文件中进行设置时,我会这样做:
var nconf = require ('nconf');
nconf.get('x');
我正在为我的 node.js Express 网络服务器使用名为 nconf
的环境变量和参数解析模块。
https://github.com/indexzero/nconf
我认为使 nconf 数据全局化的最佳方法是简单地将其附加到进程变量(如 process.env 中所示),这是好主意还是坏主意?它会在权衡 "process" 时减慢执行速度吗?
这是我的代码:
var nconf = require('nconf');
nconf.argv()
.env()
.file({ file: './config/config.json' });
nconf.defaults({
'http': {
'port': 3000
}
});
process.nconf = nconf;
//now I can retrieve config settings anywhere like so process.nconf.get('key');
坦率地说,我有点喜欢这个解决方案。现在我可以在任何地方检索配置数据,而不需要一个模块。但这可能有缺点……这很可能是一个非常糟糕的主意。 IDK.
不会减慢执行速度,但感觉"smelly"。很难发现,也很难测试,如果您决定需要的话。
更好的解决方案是将设置附加到模块并使用 require() 在需要的地方导入它。
最好的解决方案是将您的设置对象传递给 类 或需要它的模块。直接或作为某种 "global context".
的一部分例如
var global = {
settings: {
port: 8080
}
}
//...
global.api = new Api(global);
//...
function Api(global) {
var port = global.settings.port;
}
更新:关于为什么原始模式不好的更多信息:
1) 可发现性
您将设置附加到 process.settings
并转到另一个项目。一年后,其他人接手,或者您需要更新内容。您还记得您将设置附加到 process.nconf
吗?还是 process.settings
?
现在假设您有 10 个不同的全球事物,以不同的名称连接在不同的地方。
它没有直接附加到全局上下文那么糟糕,但是清楚地看到您正在使用的东西来自哪里(构造函数或模块)肯定更好。
2) 测试
您决定需要测试您的模块。所以现在您需要为每个测试调整您的设置,而不是从文件或 argv 加载它们。你是怎么做到的?
如果是全局 process.nconf
或 require("settings")
模式,您需要执行以下操作:
function canOpenAPIOnTheConfiguredPort(done) {
var nconfSaveApiPort = process.nconf.api.port;
process.nconf.api.port = '1234';
var api = new Api();
test.assertEqual(api.port, '1234');
process.nconf.api.port = nconfSaveApiPort;
done();
}
随着您的应用程序的增长,这很快就会变得烦人(例如,想象一下必须模拟 10 个东西)。相比之下,这是使用依赖注入(构造函数)模式的方法。
function canOpenAPIOnTheConfiguredPort(done) {
var api = new Api({
port: '1234'
});
test.assertEqual(api.port, '1234');
done();
}
注意 nconf 是一个单例。
我习惯在程序的最开始进行配置,然后当我需要在另一个文件中进行设置时,我会这样做:
var nconf = require ('nconf');
nconf.get('x');