npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@vamship/config

v1.5.2

Published

Wraps a config and provides access methods for scoped config values

Downloads

34

Readme

@vamship/config

Singleton module for configuration and initialization of application wide configuration objects.

This library does not actually provide logging functionality, but merely abstracts the configuration and creation of application wide config objects. Actual logging functionality is provided by rc

API Documentation

API documentation can be found here.

Motivation

Using configuration files to avoid hard coding parameters is a well understood practice. Most applications leverage configuration files to store values specific to certain execution environments (ex: dev, qa, prod, etc.), allowing the code to be environment agnostic.

There are several good libraries available for working with configuration files, such as: rc and config, some of which even support multiple execution environments, albeit with some drawbacks (like dependency on a NODE_ENV variable, for example).

This library is does not reimplement functionality already provided by these libraries. Instead, it is focused on solving the problem of being able to initialize and select environment specific (also referred to as scope specific) configurations consistently from within different modules in a single application.

Most applications rely on having multiple code modules, broken up into separate files, and each module may want to read configuration data during execution. It is important that each sub module load configuration for the correct execution environment, and this is typically addressed in one of two ways: This is typically addressed in one of two ways:

  1. Each module looks up an environment variable (such as NODE_ENV), and uses this value to determine the current execution environment.
  2. The entry point for the application initializes the config, and passes the entire config, or relevant parts of it down to all other objects that are created within the application

The use of an environment variable to load specific configuration data works for many scenarios, and this functionality is supported out of the box by modules such as config. However, does not work very well with stateless execution environments such as those encountered with AWS Lambdas. Lambda functions are executed within containers behind the scenes, and each execution instance may require different configurations (based on the alias, for example).

Initializing the configuration object at the entry point and passing it down to each of the submodules alleviates this problem, but that makes the object interfaces clunky, sometimes requiring a parent object to accept a config object for the sole reaon that its child components need it.

This library attempts to solve these problems by providing static interfaces for the configuration and instantiation of a config object. The config object is configured with application wide settings in the main entry point of the program, such as an index.js file. All other modules with the application can then use this library to instantiate config objects that are specific to that module/class. As long as config configuration occurs prior to instantiation, everything is good.

Configuration Data Structure

Data for this module can be present in a file named .<appName>rc, or in environment variables. This is standard functionality supported by the rc library. However, in order to support multiple environments, configuration data must be structured as follows:

When using a config file:

{
    "default": {
        // Default configuration parameters go here.
    },
    "dev": {
        // Dev specific overrides go here.
    },
    "prod": {
        // Prod specific overrides go here.
    }
}

When using environment variables:

export myApp_default__host='dev.example.com'
export myApp_default__log__level='info'
export myApp_dev__log__level='debug'
export myApp_prod__host='prod.example.com'

Installation

This library can be installed using npm:

npm install @vamship/config

Usage

Using the config

Before creating any config instances, the config must be configured using the configure() method. Optionally, a default scope can be set for the application, so that each call to getConfig() always brings back configuration specific to a runtime environment.

If application scope is not set by calling setApplicationScope(), then each module must explicitly pass in a scope value when calling getConfig().

index.js (application entry point):

const config = require('@vamship/config')
                // Configure application wide configuration
                .configure('myApp', {
                    // Hard coded default properties
                    api: {
                        host: 'example.com'
                    }
                })
                // Set default application scope.
                .setApplicationScope(process.env.NODE_ENV)
                // Get the config object
                .getConfig();

// Read config parameters
const host = config.get('api.host');

api.js (Class that makes API calls):

const config = require('@vamship/config').getConfig();

class API {
    constructor() {
        // Nested properties can be accessed via dot separated property names!
        this._host = config.get('api.host');
    }
}

Note on using config with AWS Lambdas

AWS Lambdas are intended to be stateless, with execution contexts changing based on the invocation alias or version number. When using aliases, it is possible to have multiple aliases pointing to a single instance of the lambda function, running within the same container. It is also possible that when executing, different executions may require different configuration to be loaded.

In order to handle such scenarios gracefully, it is best to not set a default application scope on the config, and explicitly load configuration for a specific scope by using getConfig(<scope>), as shown below:

module.exports = (event, context, callback) => {

    ...

    alias = (alias === undefined || alias === '$LATEST') ? 'default' : alias;
    let alias = arn.split(':')[7];

    const config = require('@vamship/config')
                    // Configure application wide configuration
                    .configure('myApp', {
                        // Hard coded default properties
                        api: {
                            host: 'example.com'
                        }
                    })

                    // Get the config object based on alias
                    .getConfig(alias);

    ...
};