我一直在开发一些Node应用程序,我一直在寻找一种存储部署相关设置的良好模式。在Django世界(我来自那里),常见的做法是有一个settings.py文件包含标准设置(时区等),然后有一个local_settings.py用于部署特定的设置,即。要与什么数据库通信、什么memcache套接字、管理员的电子邮件地址等等。
我一直在为Node寻找类似的模式。只要一个配置文件就好了,这样它就不必与app.js中的其他所有东西挤在一起,但我发现有一种方法在源代码控制之外的文件中拥有特定于服务器的配置很重要。同一款应用可以部署在不同设置的服务器上,必须处理合并冲突,这不是我的乐趣所在。
那么是否存在某种框架/工具,或者每个人都只是自己拼凑一些东西?
我的解决办法相当简单:
在./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
下面是本文启发的一个简洁的方法。它不需要任何额外的包,除了无处不在的lodash包。此外,它还允许您使用特定于环境的覆盖来管理嵌套默认值。
首先,在包的根路径中创建一个配置文件夹,如下所示
package
|_config
|_ index.js
|_ defaults.json
|_ development.json
|_ test.json
|_ production.json
这是index.js文件
const _ = require("lodash");
const defaults = require("./defaults.json");
const envConf = require("./" + (process.env.NODE_ENV || "development") + ".json" );
module.exports = _.defaultsDeep(envConf, defaults);
现在我们假设有一个默认值。像这样的Json
{
"confKey1": "value1",
"confKey2": {
"confKey3": "value3",
"confKey4": "value4"
}
}
和发展。像这样的Json
{
"confKey2": {
"confKey3": "value10",
}
}
如果你执行config = require('./config'),你会得到这样的结果
{
"confKey1": "value1",
"confKey2": {
"confKey3": "value10",
"confKey4": "value4"
}
}
注意,除了在特定于环境的文件中定义的值外,您可以得到所有的默认值。因此,您可以管理配置层次结构。使用defaultsDeep可以确保您甚至可以拥有嵌套的默认值。
我使用Dotenv-Flow进行配置管理。
这和预期的一样。通常情况下你会有多个
本地、开发、登台和生产等环境。看这些
步骤创建您自己的环境。
1. 我喜欢流动。
2. 创建像.env | .env.dev | .env.prod这样的文件。
出于测试目的,复制此内容
.env
DATABASE_HOST=global
DATABASE_PORT=global
DATABASE_USER=global
DATABASE_PASS=global
DATABASE_NAME=global
.env.dev
DATABASE_NAME=dev
DATABASE_PASS=dev
.env.prod
DATABASE_NAME=prod
DATABASE_PASS=prod
现在使用这些环境变量创建一个测试文件。
. js
console.log('database host:', process.env.DATABASE_HOST);
console.log('database port:', process.env.DATABASE_PORT);
console.log('database user:', process.env.DATABASE_USER);
console.log('database pass:', process.env.DATABASE_PASS);
console.log('database name:', process.env.DATABASE_NAME);
现在使用这些命令运行脚本。
node -r dotenv-flow/config test.js
node -r dotenv-flow/config test.js --node-env=dev
node -r dotenv-flow/config test.js --node-env=prod
如果您在特定的文件夹中创建这些环境变量文件,就像我在envs文件夹中创建这些文件一样,那么使用下面的命令。
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=dev
node -r dotenv-flow/config test.js --dotenv-flow-path=./envs --node-env=prod
很久以后,我发现了一个非常好的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。
尝试使用properties-gen
https://www.npmjs.com/package/properties-gen
node-config与node-config非常相似,后者加载配置基础文件,并根据所设置的环境使用ext文件对其进行扩展,但这是一个按需运行且完全可配置的cli。
npx properties-gen init
要创建cli配置,然后将其安装到项目中
npm install properties-gen --save-dev
定义您的配置文件(基本和扩展),并在构建过程之前或在项目中启动开发服务器之前运行generate命令。
{
"name": "myApp",
"scripts": {
"config": "properties-gen generate",
"dev": "npm run config && next dev",
"build": "npm run config && next build",
"start": "next start"
}
}
一件很酷的事情是,您可以定义多个配置组,以防您需要生成多个输出,例如特定于客户端和服务器的文件。