@robpc/config v2.0.5
@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/configUsage
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
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
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}.jsonprocess.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
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: 10config/ui.yml
auth:
api: /api/v1/authconfig/server.dev.yml
auth:
token: 123434sdFASDFqwe$$%2323RQWER$qr32config/ui.dev.yml
auth:
alwaysAdminUsers:
- robpcserver/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');