我一直在开发一些Node应用程序,我一直在寻找一种存储部署相关设置的良好模式。在Django世界(我来自那里),常见的做法是有一个settings.py文件包含标准设置(时区等),然后有一个local_settings.py用于部署特定的设置,即。要与什么数据库通信、什么memcache套接字、管理员的电子邮件地址等等。

我一直在为Node寻找类似的模式。只要一个配置文件就好了,这样它就不必与app.js中的其他所有东西挤在一起,但我发现有一种方法在源代码控制之外的文件中拥有特定于服务器的配置很重要。同一款应用可以部署在不同设置的服务器上,必须处理合并冲突,这不是我的乐趣所在。

那么是否存在某种框架/工具,或者每个人都只是自己拼凑一些东西?


当前回答

现在,在使用数据库时,最简单的方法是完全不处理配置文件,因为部署环境更容易设置,只需使用单个环境变量(例如,将其称为DB_CONNECTION),并根据需要向其传递任何额外的配置数据。

配置数据举例:

const config = {
    userIds: [1, 2, 3],
    serviceLimit: 100,
    // etc., configuration data of any complexity    
};
// or you can read it from a config file

创建一个连接字符串,包含数据库驱动程序不关心的额外参数:

import {ConnectionString} from 'connection-string';

const cs = new ConnectionString('postgres://localhost@dbname', {
    user: 'user-name',
    password: 'my-password',
    params: {
        config
    }  ​
});

然后我们可以生成结果字符串存储在环境中:

cs.toString();
//=>postgres://localhost:my-password@dbname?config=%7B%22userIds%22%3A%5B1%2C2%2C3%5D%2C%22serviceLimit%22%3A100%7D

所以你把它存储在你的环境中,比如说DB_CONNECTION,在客户端进程中你可以通过process.env.DB_CONNECTION读取它:

const cs = new ConnectionString(process.env.DB_CONNECTION);

const config = JSON.parse(cs.params?.config); // parse extra configuration
//=> { userIds: [ 1, 2, 3 ], serviceLimit: 100 }

通过这种方式,您将在单个环境变量中同时拥有连接和所需的所有额外配置,而不需要打乱配置文件。

其他回答

我知道这是一个非常老的帖子。但是我想分享我的配置环境变量的模块,我认为这是一个非常灵活的解决方案。 下面是模块json-configurator

var configJson = {
  'baseUrl': 'http://test.com',
  '$prod_baseUrl': 'https://prod.com',
  'endpoints': {
    'users': '<%= baseUrl %>/users',
    'accounts': '<%= baseUrl %>/accounts'
    },
  foo: 'bar',
  foobar: 'foobar',
  $prod_foo: 'foo in prod',
  $test_foo: 'foo in test',
  deep:{
    veryDeep: {
      publicKey: 'abc',
      secret: 'secret',
      $prod_secret: 'super secret'
    }
  }
};

var config = require('json-configurator')(configJson, 'prod');

console.log(config.deep.veryDeep.secret) 
// super secret 

console.log(config.endpoints.users)
// https://prod.com/users 

然后你可以使用process.env。NODE_ENV来获取环境的所有变量。

我的解决办法相当简单:

在./config/index.js中加载环境配置

var env = process.env.NODE_ENV || 'development'
  , cfg = require('./config.'+env);

module.exports = cfg;

在./config/config.global.js中定义一些默认值

var config = module.exports = {};

config.env = 'development';
config.hostname = 'dev.example.com';

//mongo database
config.mongo = {};
config.mongo.uri = process.env.MONGO_URI || 'localhost';
config.mongo.db = 'example_dev';

重写。/config/config.test.js中的默认值

var config = require('./config.global');

config.env = 'test';
config.hostname = 'test.example';
config.mongo.db = 'example_test';

module.exports = config;

在./models/user.js中使用:

var mongoose = require('mongoose')
, cfg = require('../config')
, db = mongoose.createConnection(cfg.mongo.uri, cfg.mongo.db);

在测试环境中运行应用程序:

NODE_ENV=test node ./app.js

很久以后,我发现了一个非常好的Node.js模块来管理配置:nconf。

举个简单的例子:

var nconf = require('nconf');

// First consider commandline arguments and environment variables, respectively.
nconf.argv().env();

// Then load configuration from a designated file.
nconf.file({ file: 'config.json' });

// Provide default values for settings not provided above.
nconf.defaults({
    'http': {
        'port': 1337
    }
});

// Once this is in place, you can just use nconf.get to get your settings.
// So this would configure `myApp` to listen on port 1337 if the port
// has not been overridden by any of the three configuration inputs
// mentioned above.
myApp.listen(nconf.get('http:port'));

它还支持在Redis中存储设置,编写配置文件,并且有一个相当可靠的API,并且还得到了一个更受尊敬的Node.js商店Nodejitsu的支持,作为Flatiron框架计划的一部分,所以它应该是相当经得起未来的。

在Github上查看nconf。

您可以将Konfig用于特定于环境的配置文件。它自动加载json或yaml配置文件,它有默认值和动态配置功能。

Konfig repo的一个例子:

File: config/app.json
----------------------------
{
    "default": {
        "port": 3000,
        "cache_assets": true,
        "secret_key": "7EHDWHD9W9UW9FBFB949394BWYFG8WE78F"
    },

    "development": {
        "cache_assets": false
    },

    "test": {
        "port": 3001
    },

    "staging": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    },

    "production": {
        "port": #{process.env.PORT},
        "secret_key": "3F8RRJR30UHERGUH8UERHGIUERHG3987GH8"
    }
}

在发展:

> config.app.port
3000

在生产环境中,假设我们使用$ NODE_ENV=生产PORT=4567节点app.js启动应用程序

> config.app.port
4567

详情:https://github.com/vngrs/konfig

只需使用npm模块配置(超过300000次下载)

https://www.npmjs.com/package/config

节点配置为应用程序部署组织分层配置。

它允许您定义一组默认参数,并为不同的部署环境(开发、qa、登台、生产等)扩展它们。

$ npm install config
$ mkdir config
$ vi config/default.json


{
      // Customer module configs
      "Customer": {
        "dbConfig": {
          "host": "localhost",
          "port": 5984,
          "dbName": "customers"
        },
        "credit": {
          "initialLimit": 100,
          // Set low for development
          "initialDays": 1
        }
      }
}



$ vi config/production.json

{
  "Customer": {
    "dbConfig": {
      "host": "prod-db-server"
    },
    "credit": {
      "initialDays": 30
    }
  }
}



$ vi index.js

var config = require('config');
//...
var dbConfig = config.get('Customer.dbConfig');
db.connect(dbConfig, ...);

if (config.has('optionalFeature.detail')) {
  var detail = config.get('optionalFeature.detail');
  //...
}


$ export NODE_ENV=production
$ node index.js