/c12

Smart Configuration Loader

Primary LanguageTypeScriptMIT LicenseMIT

c12

npm version npm downloads Github Actions Codecov

Smart Configuration Loader

Features

  • JSON, CJS, Typescript and ESM config loader with unjs/jiti
  • RC config support with unjs/rc9
  • Multiple sources merged with unjs/defu
  • .env support with dotenv
  • Support extending nested configurations from multiple local or git sources

Usage

Install package:

# npm
npm install c12

# yarn
yarn add c12

# pnpm
pnpm install c12

Import:

// ESM
import { loadConfig } from 'c12'

// CommonJS
const { loadConfig } = require('c12')

Load configuration:

// Get loaded config
const { config } = await loadConfig({})

// Get resolved config and extended layers
const { config, configFile, layers } = await loadConfig({})

Loading priority

c12 merged config sources with unjs/defu by below order:

  1. config overrides passed by options
  2. config file in CWD
  3. RC file in CWD
  4. global RC file in user's home directory
  5. default config passed by options
  6. Extended config layers

Options

cwd

Resolve configuration from this working directory. Default is process.cwd()

name

Configuration base name. Default is config.

configName

Configuration file name without extension . Default is generated from name (name=foo => foo.config).

Set to false to avoid loading config file.

rcFile

RC Config file name. Default is generated from name (name=foo => .foorc).

Set to false to disable loading RC config.

globalRC

Load RC config from the workspace directory and user's home directory. Only enabled when rcFile is provided. Set to false to disable this functionality.

dotenv

Loads .env file if enabled. It is disabled by default.

defaults

Specify default configuration. It has the lowest priority and is applied after extending config.

defaultConfig

Specify default configuration. It is applied before extending config.

overides

Specify override configuration. It has the highest priority and is applied before extending config.

jiti

Custom unjs/jiti instance used to import configuration files.

jitiOptions

Custom unjs/jiti options to import configuration files.

Extending configuration

If resolved config contains a extends key, it will be used to extend configuration.

Extending can be nested and each layer can extend from one base or more.

Final config is merged result of extended options and user options with unjs/defu.

Each item in extends, is a string that can be either an absolute or relative path to current config file pointing to a config file for extending or directory containing config file. If it starts with either of github:, gitlab:, bitbucket: or https:, c12 autmatically clones it.

For custom merging strategies, you can directly access each layer with layers property.

Example:

// config.ts
export default {
  colors: {
    primary: 'user_primary'
  },
  extends: [
    './theme',
    './config.dev.ts'
  ]
}
// config.dev.ts
export default {
  dev: true
}
// theme/config.ts
export default {
  extends: '../base',
  colors: {
    primary: 'theme_primary',
    secondary: 'theme_secondary'
  }
}
// base/config.ts
export default {
  colors: {
    primary: 'base_primary'
    text: 'base_text'
  }
}

Loaded configuration would look like this:

{
  dev: true,
  colors: {
    primary: 'user_primary',
    secondary: 'theme_secondary',
    text: 'base_text'
  }
}

Layers:

[
 { config: /* theme config */, configFile: /* path/to/theme/config.ts */, cwd: /* path/to/theme */ },
 { config: /* base  config */, configFile: /* path/to/base/config.ts  */, cwd: /* path/to/base */ },
 { config: /* dev   config */, configFile: /* path/to/config.dev.ts  */, cwd: /* path/ */ },
]

💻 Development

  • Clone this repository
  • Enable Corepack using corepack enable (use npm i -g corepack for Node.js < 16.10)
  • Install dependencies using pnpm install
  • Run interactive tests using pnpm dev

License

Made with 💛 Published under MIT License.