I'm becoming a fan of Yos Riady's blog. He's got this nice node.js configuration pattern, which introduced me to the glory of nconf. Unfortunately, that pattern doesn't quite have the flexibility I seek, and leaves more up to nconf's convoluted resolution system than I'd like. So here's mine, with the help of Ramda, my favorite utility belt.
const nconf = require('nconf')
const R = require('ramda')
const defaults =
{
'node_env': 'development',
'mongo': {
'host': 'mongo',
'collection': 'mything'
}
}
const testDefaults = {
'mongo': { 'db': 'mything-test' }
}
const localhostDefaults = {
'mongo': { 'host': 'localhost' }
}
function Config() {
nconf.argv().env({ lowerCase: true }) // get NODE_ENV as node_env
const mergeAllDeepRight = R.reduce(R.mergeDeepRight, {})
const computedDefaults = mergeAllDeepRight([
defaults,
this.env.isTest ? testDefaults : {},
nconf.get('localhost_services') === '1' ? localhostDefaults : {}
])
nconf.defaults(computedDefaults)
}
Config.prototype.get = function(key) {
return nconf.get(key)
}
// for convenience, because `config.env.isTest` is real nice
const nodeEnv = process.env.NODE_ENV
Config.prototype.env = {
'isProd': nodeEnv === 'production',
'isTest': nodeEnv === 'testing',
'isDev': nodeEnv === 'development'
}
module.exports = new Config()
This makes the rules about how defaults are loaded very explicit and very flexible.