Javascript 有没有理由不将配置绑定到Node.js中的全局对象?

Javascript 有没有理由不将配置绑定到Node.js中的全局对象?,javascript,node.js,configuration,Javascript,Node.js,Configuration,我正在寻找在我的节点应用程序中使用全局配置设置的最佳方法。按照(我)偏好的顺序,我找到的方法有: 将配置附加到全局对象 global.config = { db: require('./config/db'), server: require('./config/server'), session: require('./config/session'), auth: require('./config/auth') }; 将配置对象传递给需要它的模块 var

我正在寻找在我的节点应用程序中使用全局配置设置的最佳方法。按照(我)偏好的顺序,我找到的方法有:

  • 将配置附加到全局对象

    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);
    
  • 每个模块中都需要配置文件。由于我通常将配置文件分割成不同的文件,所以我真的不喜欢这样做。由于我不总是使用某些文件,这通常还包括检查文件是否存在


  • 有什么理由要避免这两种方法中的任何一种吗?有什么理由认为一个选项比其他选项更受欢迎吗?

    根据我的经验,使用选项是一种常见的方式。第2点:将配置选项传递给您建议的需要它的模块

    原因

    • 它将配置与实际逻辑分离。如果将配置文件包括在 模块本身对一个特定的配置文件有一个不必要的依赖关系
    • 仍然存在对作为参数提供的特定配置值的定义依赖,而不是“神奇地”从全局名称空间中提取,这使得代码难以读取、维护和测试
    顺便说一句,这是几乎每种语言的经验法则,允许全局变量/对象和构造包含“任何你喜欢的东西,任何你喜欢的地方”。但是,
    requirejs
    至少允许
    exports
    成为一个立即接受配置的函数,这已经将您推向了正确的方向。因此,一行程序是一种要求和配置资源的优雅方式


    除此之外的所有内容都可能会在关于依赖注入(DI)概念的讨论中结束,这是一个单独的主题。

    对于小型项目,这三种方法都是可以接受的。对于大人物,我接下来可以说:

    全局变量是一个问题 如果您开始使用这种方式,您需要保护配置对象,如
    var config={…};config.freeze()。在任何情况下,全局变量都是一种不好的做法,特别是对于NodeJ,因为它破坏了模块化系统

    传递配置是最好的方法 这就是原因吗测试

    在测试中,您需要获取配置文件的一些状态。第一种和第三种方式为您提供了下一种代码样式:

    config.js app.js 摩卡+柴试验 app.js 摩卡+柴试验 子模块.js
    传递变量的主要问题是,当我将模块拆分为多个文件时,每次需要单独的文件时,我都必须不断传递config对象。有什么办法可以顺利解决这个问题吗?我为你们更新了答案的最后一部分。这有用吗?是的,绝对有用。这几乎就是我现在采用的方法。您在原始示例中使用的“freezy”函数是什么?搜索npm freezy后,什么也没发现。。。我是否应该始终冻结配置以防止其他开发人员或其他需要配置的模块修改我的原始值?请参阅
    Object.prototype.freeze
    。我建议您将
    全局配置
    对象的逻辑划分为模块操作
    ,但这是一个非常独立的引用。常量
    config
    可以节省调试时间,也可以节省开发时间。传递变量的主要问题是,当我将模块拆分为多个文件时,每次需要单独的文件时,我都必须不断传递config对象。有什么方法可以顺利解决这个问题吗?@sup3rman如果您将事物拆分为单独文件所拥有的小逻辑单元,则可能不需要每次都传递整个配置对象,但它们需要一些参数(如果有的话)。如果您拆分(例如,路由段),我认为绝对可以为每个所需资源传递所需的配置。
    module.exports= {
      a: 10
    };
    
    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!!!
    });
    
    var config = {
      a: 10
    };
    config.freezy();
    module.exports = config;
    
    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');
      });
    });
    
    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;`
    
    function MySubModule(config) {
      this._c = config.c;
    }
    module.exports = MySubModule;