Sergey Danilov

web developer at Fleetmatics

Configuration manager for Node.js

Kea-config

Main feature of it is merging configuration files depending on Node.js environment, support references to other keys and using templates with objects for complex string values.


$ npm install kea-config --save

Idea

./config/main.js



    let config.web = {
        port: 3005,
        paging: {
            itemsPerPage: 25,
            visiblePages: 10
        }
    }
    
    export default config;

Idea

./config/development.js



    let config.web = {
        port: 4343
    };
    
    export default config;

Idea

./config/production.js



    let config.web = {
        port: 80
    };
    
    export default config;

Idea

Initialization and usage



    import configManager from 'kea-config';

    configManager.setup('./config');
    // For process.env.NODE_ENV === 'development';
    configManager.get('web.port'); // 4343
    // For process.env.NODE_ENV === 'production';
    configManager.get('web.port'); // 80

Idea

Usage without merging



    import configManager from 'kea-config';

    configManager.init('./config/main');

    configManager.get('web.port'); // 3005

Using

./config/main.js



    let config.web = {
        port: 3005,
        paging: {
            itemsPerPage: 25,
            visiblePages: 10
        }
    }
    
    export default config;

Using


    configManager.get('web.port'); // 3005

    configManager.get('web.paging');
    /*
        {
            itemsPerPage: 25,
            visiblePages: 10
        }
    */

Key as reference

    {
         nameValue: 'loginName',
         sessionKey: '6ketaq3cgo315rk9',
         dbParams: {
             username: { $ref: 'web.nameValue' },
             password: '12345'
         },
         dbConnection: {
             user: { $ref: 'web.dbParams' },
             key: { $ref: 'web.sessionKey' }
         },
         dbConectionStr: {
             $ref: 'web.dbConnection',
             $tmpl: 'db:{user.username}::{user.password}@{key}'
         }
    }

Configuration example

Key as reference



        configManager.get('dbConnection');
        
        //should return object
        // {
        //   user: {
        //       username: 'loginName',
        //       password: '12345'
        //   },
        //   key: '6ketaq3cgo315rk9'
        // }

Reference

Key as reference



        configManager.get('dbConectionStr'); 

        // should return string
        // 'db:loginName::12345@6ketaq3cgo315rk9'

Reference with template

API

    
    configManager.get('some.long.key')
    // return key value
    
    configManager.set('other.key', true)
    // return `this` reference for chaining
    
    configManager.has('other.key') // true

Plugin for hapi.js

var Hapi = require('hapi');
var server = new Hapi.Server();
var pluginOptions = {
    confPath: './path-to-config-flies',
    decorateServer: true
};
// for hapi >= 8.0.0 or use server.pack.register for hapi < 8.0.0 
server.register({
        plugin: require('hapi-kea-config'),
        options: pluginOptions
    }, function(err) {
        if (err) {
            console.log('error', 'Failed loading plugin: hapi-kea-config');
        }
});
// Usage in the code 
var configManager = server.plugins['hapi-kea-config'];
if (configManager.has('web')) {
    var port = configManager.get('web.port');
}

Facts

  • Inspired by web.config transformations in ASP.NET

  • 100% code coverage by tests

  • High performance (a few millions operations per sec simple get / set operations and a few tens of thousands operations per sec for key with references and templates)

  • Gulp used for test, benchmarks and preparing README.md

Questions