@robpc/config
TypeScript icon, indicating that this package has built-in type declarations

2.0.5 • Public • Published

@robpc/config

NOTE: Recently updated to v2, for v1 see v1/README.md.

Simple configuration library for use in node and the browser. Inspired by config, but doubles down on the webpack use case and removes the dynamic require errors in webpack.

Installation

npm install --save @robpc/config

Usage

const config = require('@robpc/config/json-loader');

const name = config.get('name');
const morningGreeting = config.get('greeting.morning');

console.log(`${morningGreeting}, ${name}!`);

This example uses the json-loader but all configs have the same interface.

interface Config {
  // get individual values from the config using
  // a '.' path separator. Return undefined if any
  // part of the path is undefined
  get: (path: string) => string | undefined;

  // used in the webpack scenario to to export to
  // an environment variable
  toEnv: () => string;

  // Access the raw merged config directly
  json: Record<string, any>;
}

Loaders

There are three loaders that can be referenced directly using the pattern @robpc/config/[name]-loader. These have default configuratons and only contain code for their respecive needs (ie env-loader does not require fs, and json-loader does not require js-yaml). The default package import @robpc/config is a factory to generate a config with custom options. See the sections below for more information.

File Loaders

Example Project

NOTE: The yaml-loader works in the same way but looks for .yml files instead of .json.

The json-loader loads configuration files from the config/ directory at the root of the project. The library will load the default.json first followed by any json has a name matching the value in the NODE_ENV environmnent variable overriding previous values. So given the following configuration files:

config/default.json

{
  "name": "Bob",
  "greeting": {
    "morning": "Good Morning"
  }
}

config/production.json

{
  "name": "Rob"
}

If the NODE_ENV is set to production, then the effective value of the config would be:

{
  "name": "Rob",
  "greeting": {
    "morning": "Good Morning"
  }
}

Here the default name Bob is changed to Rob for production.

Env Loader

Example Project

The env-loader loads configuration files from the NODE_CONFIG environmnent variable.

Example NODE_CONFIG

{\"name\":\"Rob\",\"greeting\":{\"morning\":\"Good Morning\"}}

Custom Loader

The custom loader utilizes all the above loaders and will look for config names in the following order:

  • ${baseDir}/${name}.yml
  • ${baseDir}/${name}.json
  • process.env[name]
const configLoader = require('@robpc/config');

const deployStage = process.env.NODE_ENV;

// Can be a string or an array of strings that list the configs
// to be loaded. The later configs will take higher precedence
const configNames = [deployStage, 'APP_CONFIG_OVERRIDE'];

// (Optional) ability to override the following defaults
const configOptions = {
  baseDir: './config', // directory with configuration files
  default: 'default', // base config to be included by default
}

const config = configLoader.load(process.env.NODE_ENV, options);

const name = config.get('name');
const morningGreeting = config.get('greeting.morning');

console.log(`${morningGreeting}, ${name}!`);

Webpack

Combining the Env and File Loaders

Example

The file loader can be used to seed the NODE_CONFIG using webpack, allowing the benefits of merging configurations without adding all the files into the bundle. With this method, the configuration files can be defined as intended for the json-loader, but using the env-loader for browser code.

const { DefinePlugin } = require('webpack');

const config = require('@robpc/config');
const NODE_CONFIG = config.load(env.APP_STAGE).toEnv();

module.exports = {
  // ...
  plugins: [
    new DefinePlugin({
      'process.env.NODE_CONFIG': NODE_CONFIG,
    }),
    // ...
  ],
};

NOTE: The json-loader and yaml-loader can also be used in this way though it is not recommended since they use the NODE_ENV environment which can cause issues.

This would also allow frontend and backend code to use the same configuration files and allow sharing of values between them.

Advanced Example

A more advanced usage allows sharing a subset of values between frontend and backend

config/common.yml

validation:
  minItems: 2
  maxItems: 10

config/ui.yml

auth:
  api: /api/v1/auth

config/server.dev.yml

auth:
  token: 123434sdFASDFqwe$$%2323RQWER$qr32

config/ui.dev.yml

auth:
  alwaysAdminUsers:
    - robpc

server/config.js

const configLoader = require('@robpc/config');

const { APP_STAGE } = process.env;

module.exports = configLoader.load(
  ['server', `server.${APP_STAGE}`]),
  { default: 'common' },
);

app/webpack.config.js

const { DefinePlugin } = require('webpack');

const configLoader = require('@robpc/config');

const { APP_STAGE } = process.env;

const config = configLoader.load(
  ['ui', `ui.${APP_STAGE}`]),
  { default: 'common' },
);

module.exports = {
  // ...
  plugins: [
    new DefinePlugin({
      'process.env.NODE_CONFIG': config.toEnv(),
    }),
    // ...
  ],
};

app/index.js

const config = require('@robpc/config/env-loader');

const authApi = config.get('auth.api');
const validation = config.get('validation');

Package Sidebar

Install

npm i @robpc/config

Weekly Downloads

0

Version

2.0.5

License

ISC

Unpacked Size

21.5 kB

Total Files

12

Last publish

Collaborators

  • robpc