nconf
Hierarchical node.js configuration with files, environment variables, comma...
README
nconf
Hierarchical node.js configuration with files, environment variables, command-line arguments, and atomic object merging.
Example
Using nconf is easy; it is designed to be a simple key-value store with support for both local and remote storage. Keys are namespaced and delimited by :. Let's dive right into sample usage:
- ``` js
- // sample.js
- var nconf = require('nconf');
- //
- // Setup nconf to use (in-order):
- // 1. Command-line arguments
- // 2. Environment variables
- // 3. A file located at 'path/to/config.json'
- //
- nconf.argv()
- .env()
- .file({ file: 'path/to/config.json' });
- //
- // Set a few variables on `nconf`.
- //
- nconf.set('database:host', '127.0.0.1');
- nconf.set('database:port', 5984);
- //
- // Get the entire database object from nconf. This will output
- // { host: '127.0.0.1', port: 5984 }
- //
- console.log('foo: ' + nconf.get('foo'));
- console.log('NODE_ENV: ' + nconf.get('NODE_ENV'));
- console.log('database: ' + nconf.get('database'));
- //
- // Save the configuration object to disk
- //
- nconf.save(function (err) {
- require('fs').readFile('path/to/your/config.json', function (err, data) {
- console.dir(JSON.parse(data.toString()))
- });
- });
- ```
If you run the below script:
- ``` shell
- $ NODE_ENV=production node sample.js --foo bar
- ```
The output will be:
- ``` null
- foo: bar
- NODE_ENV: production
- database: { host: '127.0.0.1', port: 5984 }
- ```
Hierarchical configuration
Configuration management can get complicated very quickly for even trivial applications running in production. nconfaddresses this problem by enabling you to setup a hierarchy for different sources of configuration with no defaults. The order in which you attach these configuration sources determines their priority in the hierarchy.Let's take a look at the options available to you
nconf.argv(options)Loads process.argvusing yargs. If optionsis supplied it is passed along to yargs.
nconf.env(options)Loads process.envinto the hierarchy.
nconf.file(options)Loads the configuration data at options.file into the hierarchy.
nconf.defaults(options)Loads the data in options.store into the hierarchy.
nconf.overrides(options)Loads the data in options.store into the hierarchy.
A sane default for this could be:
- ``` js
- var nconf = require('nconf');
- //
- // 1. any overrides
- //
- nconf.overrides({
- 'always': 'be this value'
- });
- //
- // 2. `process.env`
- // 3. `process.argv`
- //
- nconf.env().argv();
- //
- // 4. Values in `config.json`
- //
- nconf.file('/path/to/config.json');
- //
- // Or with a custom name
- // Note: A custom key must be supplied for hierarchy to work if multiple files are used.
- //
- nconf.file('custom', '/path/to/config.json');
- //
- // Or searching from a base directory.
- // Note: `name` is optional.
- //
- nconf.file(name, {
- file: 'config.json',
- dir: 'search/from/here',
- search: true
- });
- //
- // 5. Any default values
- //
- nconf.defaults({
- 'if nothing else': 'use this value'
- });
- ```
API Documentation
The top-level of nconfis an instance of the nconf.Providerabstracts this all for you into a simple API.
nconf.add(name, options)
Adds a new store with the specified nameand options. If options.typeis not set, then namewill be used instead:
- ``` js
- nconf.add('supplied', { type: 'literal', store: { 'some': 'config' } });
- nconf.add('user', { type: 'file', file: '/path/to/userconf.json' });
- nconf.add('global', { type: 'file', file: '/path/to/globalconf.json' });
- ```
nconf.any(names, callback)
Given a set of key names, gets the value of the first key found to be truthy. The key names can be given as separate arguments or as an array. If the last argument is a function, it will be called with the result; otherwise, the value is returned.
- ``` js
- //
- // Get one of 'NODEJS_PORT' and 'PORT' as a return value
- //
- var port = nconf.any('NODEJS_PORT', 'PORT');
- //
- // Get one of 'NODEJS_IP' and 'IPADDRESS' using a callback
- //
- nconf.any(['NODEJS_IP', 'IPADDRESS'], function(err, value) {
- console.log('Connect to IP address ' + value);
- });
- ```
nconf.use(name, options)
Similar to nconf.add, except that it can replace an existing store if new options are provided
- ``` js
- //
- // Load a file store onto nconf with the specified settings
- //
- nconf.use('file', { file: '/path/to/some/config-file.json' });
- //
- // Replace the file store with new settings
- //
- nconf.use('file', { file: 'path/to/a-new/config-file.json' });
- ```
nconf.remove(name)
Removes the store with the specified name.The configuration stored at that level will no longer be used for lookup(s).
- ``` js
- nconf.remove('file');
- ```
nconf.required(keys)
Declares a set of string keys to be mandatory, and throw an error if any are missing.
- ``` js
- nconf.defaults({
- keya: 'a',
- });
- nconf.required(['keya', 'keyb']);
- // Error: Missing required keys: keyb
- ```
You can also chain .required()calls when needed. for example when a configuration depends on another configuration store
- ``` js
- config
- .argv()
- .env()
- .required([ 'STAGE']) //here you should have STAGE otherwise throw an error
- .file( 'stage', path.resolve( 'configs', 'stages', config.get( 'STAGE' ) + '.json' ) )
- .required([ 'OAUTH:redirectURL']) // here you should have OAUTH:redirectURL, otherwise throw an error
- .file( 'oauth', path.resolve( 'configs', 'oauth', config.get( 'OAUTH:MODE' ) + '.json' ) )
- .file( 'app', path.resolve( 'configs', 'app.json' ) )
- .required([ 'LOGS_MODE']) // here you should haveLOGS_MODE, otherwise throw an error
- .add( 'logs', {
- type: 'literal',
- store: require( path.resolve( 'configs', 'logs', config.get( 'LOGS_MODE' ) + '.js') )
- } )
- .defaults( defaults );
- ```