在Node.js中不绑定配置到全局对象的任何理由
Any reason not to bind configurations to global object in Node.js?
我正在寻找在我的Node应用程序中使用全局配置设置的最佳方法。按照我的喜好,我找到的方法有:
-
将配置附加到全局对象
global.config = { db: require('./config/db'), server: require('./config/server'), session: require('./config/session'), auth: require('./config/auth') };
-
将配置对象传递给需要它的模块。
var config = { db: require('./config/db'), server: require('./config/server'), session: require('./config/session'), auth: require('./config/auth') }; var responder = require('./responder')(config);
-
每个模块都需要配置文件。因为我通常把我的配置分割成单独的文件,我真的不喜欢这样做。因为我不总是使用某些文件,所以通常也需要检查文件是否存在。
有什么理由应该避免这两种方法吗?有什么理由让一个人比其他人更受欢迎吗?
根据我的经验,使用选项No是一种常见的做法和良好的风格。2:将配置选项传递给需要它的模块。
:
- 它将配置与实际逻辑解耦。如果将配置文件包含在对于模块本身,有一个不必要的依赖于一个特定的配置文件。
- 仍然有一个定义的依赖于作为参数提供的特定配置值-而不是"神奇地"从全局命名空间中提取,这使得代码难以阅读,维护和测试。
requirejs
已经把你推向了一个正确的方向至少允许exports
是一个可以立即接受构型的函数。因此,一行代码是要求和配置资源的一种优雅方式。
除此之外的一切都可能以依赖注入(DI)概念的讨论告终——这是一个单独的主题。
对于小型项目,这三种方法都是可以接受的。对于大的,我可以说下一个:
全局变量是个问题
如果你开始使用这种方式,你需要保护像var config = {...}; config.freeze();
这样的配置对象。在任何情况下,全局变量都是一个不好的做法,特别是对于NodeJS,因为它破坏了模块化系统。
传递配置是最好的方法
那是原因吗?测试
在测试中,你需要获取配置文件的一些状态。第一种和第三种方法提供了下一个代码样式:
config.js
module.exports= {
a: 10
};
app.js
var config = require('config');
module.exports.func = function(){
if (config.a > 10) return 'A';
return 'B';
}
摩卡+茶测试
var expect = require('chai').except,
config = require('config'),
app = require('app');
describe('Func', function(){
it('return "A" if a > 10', function(){
config.a = 12; //DHOOO!!! (c) Homer Simpson
expect(app.func()).to.equal('A');
});
it('return "B" if a <= 10', function(){
config.a = 9;
expect(app.func()).to.equal('B');
});
config.a = 12; //return default state of config. DHOOO!!!
});
你怎么能看到你需要有可编辑的配置,这是一个不好的做法(大项目,每个开发人员可以在任何地方改变配置状态…DHOOO ! !)
第二种方式是这样的:
config.js
var config = {
a: 10
};
config.freezy();
module.exports = config;
app.js
module.exports.func = function(config){
if (config.a > 10) return 'A';
return 'B';
}
摩卡+茶测试
var expect = require('chai').except,
app = require('app');
describe('Func', function(){
it('return "A" if a > 10', function(){
expect(app.func({a:12})).to.equal('A');
});
it('return "B" if a <= 10', function(){
expect(app.func({a:9})).to.equal('B');
});
});
更新在这个例子中,func
是非常综合的,对于实际项目,您可以看到这样的东西:
module.js
var SubModule = require('submodule');
function MyModule(config, someVar) {
//Don't use full config, only options you needed.
//Pull out config options
this._a = config.a;
this._b = config.b;
this.doSomethink(someVar);
this.subModule = new SubModule(config);
}
MyModule.prototype.doSomething = function(){
if (this._a > 10) return 'A';
return 'B';
}
module.exports = MyModule;`
submodule.js
function MySubModule(config) {
this._c = config.c;
}
module.exports = MySubModule;
相关文章:
- 全局变量和全局对象的属性之间有什么区别吗
- 全局对象是属于哪个类的对象
- javascript无法重新定义函数内部的全局对象
- cordova:例外:财产'requestFileSystem'的[对象全局]不是函数
- Javascript,从静态函数中打印全局对象
- 为了避免创建全局变量,可以将所有变量分配给一个对象吗
- 向调用全局javascript函数的对象添加处理程序
- jQuery:如何使用文字对象方法中的方法来获取全局变量
- 警告 - 全局 THIS 对象的危险使用
- 在全局声音管理器对象上完成
- 将对象传递给指令不允许全局变量
- 在 Javascript 中创建全局变量时是否需要指定对象类型
- 将对象插入到全局数组
- Javascript外部对象全局
- 对象 [对象全局] 没有方法“附加事件”
- 如何使javascript对象全局可用
- 在 AngularJS 中使对象全局化
- 未捕获的类型错误: 对象 [对象全局] 没有方法
- Cheerio:SyntaxError:属性选择器格式不正确:对象全局
- 在复杂的AngularJS应用中使对象全局可访问和可操作的最好方法