configomatic v1.2.0
configomatic
Builds upon cosmiconfig to provide the ability for configuration files to infinitely extend from other config files.
Install
$ npm install configomatic
Example Config
The extends
keyword can be a string:
{
"extends": "some-other-package"
}
or an array of strings:
{
"extends": ["some-other-package"]
}
Extending Configs
The extends
keyword supports a string
or an array of strings (string[]
).
Any configuration file can extend from any other configuration file. The Node.js resolution algorithm is used, so relative requests, and references to package dependencies are supported.
For requests to package dependencies, the main
field in package.json
is
respected and used to resolve a config file.
File extensions can be omitted in the request path, configomatic
will attempt
to resolve the request based on the configured
loaders.
How it works
The default merging logic (which you can override using the merge option), uses the following logic:
{...parentConfig, ...currentConfig}
The only exception is for properties named plugins
or presets
, the values of
these properties are merged together using the following logic:
mergedConfig[key] = [...parentConfig[key], ...currentConfig[key]]
No attempt is made to filter the presets
or plugins
arrays in order to make
them unique, as some packages may need to rely on a plugin being used multiple
times at different indexes. Additionally, no restrictions are placed on the
inner array contents of presets
or plugins
.
Usage
configomatic
is a drop-in replacement that builds on cosmiconfig,
so it inherits all of it's features and documentation.
All static properties assigned to the cosmiconfig
function are included in
configomatic
.
One major difference from cosmiconfig
is that
JSON5 is already configured as the
default JSON parser in order to support JSON configs with comments.
Options
Only three options have been added to the cosmiconfig
options:
merge
Custom method to merge the current configuration with the parent config that it extends.
Type: function
Signature:
merge?(currentConfig: T, parentConfig: T): T
You can also import defaultMergeFunc
(same signature as above) from
configomatic
if you'd still like to use the default merge function before or
after applying your custom merge logic.
Example:
import { defaultMergeFunc } from 'configomatic'
function merge(currentConfig, parentConfig) {
const mergedConfig = defaultMergeFunc(currentConfig, parentConfig)
if (mergedConfig.rules !== undefined) {
mergedConfig.rules = {
...parentConfig.rules,
...currentConfig.rules
}
}
return mergedConfig
}
const explorer = configomatic('foo', { merge })
resolve
Resolve logic for configuration files, currently only one option is available:
alias
Provide a key/value pair of a config name and the absolute path to the config file.
Example:
const explorer = configomatic('foo', {
resolve: {
alias: {
'foo:recommended': path.resolve(__dirname, 'recommended.json')
}
}
})
validate
Validate each loaded configuration.
This behaves very similar to the transform
function in cosmiconfig
:
If using search()
or load()
(which are async), the validate
function can
throw an error, return a boolean
or return a Promise that resolves to a
boolean
. If using searchSync()
or loadSync()
, the function must be
synchronous and throw an error or return a boolean
.
Type: function
Signature:
validate?(result: ConfigResult): Promise<boolean> | boolean
Config Results
The result of load
, loadSync
, search
, and searchSync
is the same as
cosmiconfig
, with the addition of the extends
property being included in the
result object. extends
is an array
of all the configuration files the parent
config inherits from and in the order they were processed.
TypeScript
Types are included in the package, and you can optionally include a return type for your configuration:
interface Config {
foobar: string
}
const explorer = configomatic<Config>('your-package-name')
Now load
, loadSync
, search
, and searchSync
will resolve with your
provided config type.