UNPKG

17.1 kBMarkdownView Raw
1# cosmiconfig
2
3[![Build Status](https://img.shields.io/travis/davidtheclark/cosmiconfig/master.svg?label=unix%20build)](https://travis-ci.org/davidtheclark/cosmiconfig) [![Build status](https://img.shields.io/appveyor/ci/davidtheclark/cosmiconfig/master.svg?label=windows%20build)](https://ci.appveyor.com/project/davidtheclark/cosmiconfig/branch/master)
4
5Cosmiconfig searches for and loads configuration for your program.
6
7It features smart defaults based on conventional expectations in the JavaScript ecosystem.
8But it's also flexible enough to search wherever you'd like to search, and load whatever you'd like to load.
9
10By default, Cosmiconfig will start where you tell it to start and search up the directory tree for the following:
11
12- a `package.json` property
13- a JSON or YAML, extensionless "rc file"
14- an "rc file" with the extensions `.json`, `.yaml`, `.yml`, or `.js`.
15- a `.config.js` CommonJS module
16
17For example, if your module's name is "soursocks", cosmiconfig will search up the directory tree for configuration in the following places:
18
19- a `soursocks` property in `package.json`
20- a `.soursocksrc` file in JSON or YAML format
21- a `.soursocksrc.json` file
22- a `.soursocksrc.yaml`, `.soursocksrc.yml`, or `.soursocksrc.js` file
23- a `soursocks.config.js` file exporting a JS object
24
25Cosmiconfig continues to search up the directory tree, checking each of these places in each directory, until it finds some acceptable configuration (or hits the home directory).
26
27👀 **Looking for the v4 docs?**
28v5 involves significant revisions to Cosmiconfig's API, allowing for much greater flexibility and clarifying some things.
29If you have trouble switching from v4 to v5, please file an issue.
30If you are still using v4, those v4 docs are available [in the `4.0.0` tag](https://github.com/davidtheclark/cosmiconfig/tree/4.0.0).
31
32## Table of contents
33
34- [Installation](#installation)
35- [Usage](#usage)
36- [Result](#result)
37- [cosmiconfig()](#cosmiconfig-1)
38 - [moduleName](#modulename)
39- [explorer.search()](#explorersearch)
40 - [searchFrom](#searchfrom)
41- [explorer.searchSync()](#explorersearchsync)
42- [explorer.load()](#explorerload)
43- [explorer.loadSync()](#explorerloadsync)
44- [explorer.clearLoadCache()](#explorerclearloadcache)
45- [explorer.clearSearchCache()](#explorerclearsearchcache)
46- [explorer.clearCaches()](#explorerclearcaches)
47- [cosmiconfigOptions](#cosmiconfigoptions)
48 - [searchPlaces](#searchplaces)
49 - [loaders](#loaders)
50 - [packageProp](#packageprop)
51 - [stopDir](#stopdir)
52 - [cache](#cache)
53 - [transform](#transform)
54 - [ignoreEmptySearchPlaces](#ignoreemptysearchplaces)
55- [Caching](#caching)
56- [Differences from rc](#differences-from-rc)
57- [Contributing & Development](#contributing--development)
58
59## Installation
60
61```
62npm install cosmiconfig
63```
64
65Tested in Node 4+.
66
67## Usage
68
69Create a Cosmiconfig explorer, then either `search` for or directly `load` a configuration file.
70
71```js
72const cosmiconfig = require('cosmiconfig');
73// ...
74const explorer = cosmiconfig(moduleName);
75
76// Search for a configuration by walking up directories.
77// See documentation for search, below.
78explorer.search()
79 .then((result) => {
80 // result.config is the parsed configuration object.
81 // result.filepath is the path to the config file that was found.
82 // result.isEmpty is true if there was nothing to parse in the config file.
83 })
84 .catch((error) => {
85 // Do something constructive.
86 });
87
88// Load a configuration directly when you know where it should be.
89// The result object is the same as for search.
90// See documentation for load, below.
91explorer.load(pathToConfig).then(..);
92
93// You can also search and load synchronously.
94const searchedFor = explorer.searchSync();
95const loaded = explorer.loadSync(pathToConfig);
96```
97
98## Result
99
100The result object you get from `search` or `load` has the following properties:
101
102- **config:** The parsed configuration object. `undefined` if the file is empty.
103- **filepath:** The path to the configuration file that was found.
104- **isEmpty:** `true` if the configuration file is empty. This property will not be present if the configuration file is not empty.
105
106## cosmiconfig()
107
108```js
109const explorer = cosmiconfig(moduleName[, cosmiconfigOptions])
110```
111
112Creates a cosmiconfig instance ("explorer") configured according to the arguments, and initializes its caches.
113
114### moduleName
115
116Type: `string`. **Required.**
117
118Your module name. This is used to create the default [`searchPlaces`] and [`packageProp`].
119
120**[`cosmiconfigOptions`] are documented below.**
121You may not need them, and should first read about the functions you'll use.
122
123## explorer.search()
124
125```js
126explorer.search([searchFrom]).then(result => {..})
127```
128
129Searches for a configuration file. Returns a Promise that resolves with a [result] or with `null`, if no configuration file is found.
130
131You can do the same thing synchronously with [`searchSync()`].
132
133Let's say your module name is `goldengrahams` so you initialized with `const explorer = cosmiconfig('goldengrahams');`.
134Here's how your default [`search()`] will work:
135
136- Starting from `process.cwd()` (or some other directory defined by the `searchFrom` argument to [`search()`]), look for configuration objects in the following places:
137 1. A `goldengrahams` property in a `package.json` file.
138 2. A `.goldengrahamsrc` file with JSON or YAML syntax.
139 3. A `.goldengrahamsrc.json` file.
140 4. A `.goldengrahamsrc.yaml`, `.goldengrahamsrc.yml`, or `.goldengrahamsrc.js` file.
141 5. A `goldengrahams.config.js` JS file exporting the object.
142- If none of those searches reveal a configuration object, move up one directory level and try again.
143 So the search continues in `./`, `../`, `../../`, `../../../`, etc., checking the same places in each directory.
144- Continue searching until arriving at your home directory (or some other directory defined by the cosmiconfig option [`stopDir`]).
145- If at any point a parseable configuration is found, the [`search()`] Promise resolves with its [result] \(or, with [`searchSync()`], the [result] is returned).
146- If no configuration object is found, the [`search()`] Promise resolves with `null` (or, with [`searchSync()`], `null` is returned).
147- If a configuration object is found *but is malformed* (causing a parsing error), the [`search()`] Promise rejects with that error (so you should `.catch()` it). (Or, with [`searchSync()`], the error is thrown.)
148
149**If you know exactly where your configuration file should be, you can use [`load()`], instead.**
150
151**The search process is highly customizable.**
152Use the cosmiconfig options [`searchPlaces`] and [`loaders`] to precisely define where you want to look for configurations and how you want to load them.
153
154### searchFrom
155
156Type: `string`.
157Default: `process.cwd()`.
158
159A filename.
160[`search()`] will start its search here.
161
162If the value is a directory, that's where the search starts.
163If it's a file, the search starts in that file's directory.
164
165## explorer.searchSync()
166
167```js
168const result = explorer.searchSync([searchFrom]);
169```
170
171Synchronous version of [`search()`].
172
173Returns a [result] or `null`.
174
175## explorer.load()
176
177```js
178explorer.load(loadPath).then(result => {..})
179```
180
181Loads a configuration file. Returns a Promise that resolves with a [result] or rejects with an error (if the file does not exist or cannot be loaded).
182
183Use `load` if you already know where the configuration file is and you just need to load it.
184
185```js
186explorer.load('load/this/file.json'); // Tries to load load/this/file.json.
187```
188
189If you load a `package.json` file, the result will be derived from whatever property is specified as your [`packageProp`].
190
191## explorer.loadSync()
192
193```js
194const result = explorer.loadSync(loadPath);
195```
196
197Synchronous version of [`load()`].
198
199Returns a [result].
200
201## explorer.clearLoadCache()
202
203Clears the cache used in [`load()`].
204
205## explorer.clearSearchCache()
206
207Clears the cache used in [`search()`].
208
209## explorer.clearCaches()
210
211Performs both [`clearLoadCache()`] and [`clearSearchCache()`].
212
213## cosmiconfigOptions
214
215### searchPlaces
216
217Type: `Array<string>`.
218Default: See below.
219
220An array of places that [`search()`] will check in each directory as it moves up the directory tree.
221Each place is relative to the directory being searched, and the places are checked in the specified order.
222
223**Default `searchPlaces`:**
224
225```js
226[
227 'package.json',
228 `.${moduleName}rc`,
229 `.${moduleName}rc.json`,
230 `.${moduleName}rc.yaml`,
231 `.${moduleName}rc.yml`,
232 `.${moduleName}rc.js`,
233 `${moduleName}.config.js`,
234]
235```
236
237Create your own array to search more, fewer, or altogether different places.
238
239Every item in `searchPlaces` needs to have a loader in [`loaders`] that corresponds to its extension.
240(Common extensions are covered by default loaders.)
241Read more about [`loaders`] below.
242
243`package.json` is a special value: When it is included in `searchPlaces`, Cosmiconfig will always parse it as JSON and load a property within it, not the whole file.
244That property is defined with the [`packageProp`] option, and defaults to your module name.
245
246Examples, with a module named `porgy`:
247
248```js
249// Disallow extensions on rc files:
250[
251 'package.json',
252 '.porgyrc',
253 'porgy.config.js'
254]
255
256// ESLint searches for configuration in these places:
257[
258 '.eslintrc.js',
259 '.eslintrc.yaml',
260 '.eslintrc.yml',
261 '.eslintrc.json',
262 '.eslintrc',
263 'package.json'
264]
265
266// Babel looks in fewer places:
267[
268 'package.json',
269 '.babelrc'
270]
271
272// Maybe you want to look for a wide variety of JS flavors:
273[
274 'porgy.config.js',
275 'porgy.config.mjs',
276 'porgy.config.ts',
277 'porgy.config.coffee'
278]
279// ^^ You will need to designate custom loaders to tell
280// Cosmiconfig how to handle these special JS flavors.
281
282// Look within a .config/ subdirectory of every searched directory:
283[
284 'package.json',
285 '.porgyrc',
286 '.config/.porgyrc',
287 '.porgyrc.json',
288 '.config/.porgyrc.json'
289]
290```
291
292### loaders
293
294Type: `Object`.
295Default: See below.
296
297An object that maps extensions to the loader functions responsible for loading and parsing files with those extensions.
298
299Cosmiconfig exposes its default loaders for `.js`, `.json`, and `.yaml` as `cosmiconfig.loadJs`, `cosmiconfig.loadJson`, and `cosmiconfig.loadYaml`, respectively.
300
301**Default `loaders`:**
302
303```js
304{
305 '.json': cosmiconfig.loadJson,
306 '.yaml': cosmiconfig.loadYaml,
307 '.yml': cosmiconfig.loadYaml,
308 '.js': cosmiconfig.loadJs,
309 noExt: cosmiconfig.loadYaml
310}
311```
312
313(YAML is a superset of JSON; which means YAML parsers can parse JSON; which is how extensionless files can be either YAML *or* JSON with only one parser.)
314
315**If you provide a `loaders` object, your object will be *merged* with the defaults.**
316So you can override one or two without having to override them all.
317
318**Keys in `loaders`** are extensions (starting with a period), or `noExt` to specify the loader for files *without* extensions, like `.soursocksrc`.
319
320**Values in `loaders`** are either a loader function (described below) or an object with `sync` and/or `async` properties, whose values are loader functions.
321
322**The most common use case for custom loaders value is to load extensionless `rc` files as strict JSON**, instead of JSON *or* YAML (the default).
323To accomplish that, provide the following `loaders` value:
324
325```js
326{
327 noExt: cosmiconfig.loadJson
328}
329```
330
331If you want to load files that are not handled by the loader functions Cosmiconfig exposes, you can write a custom loader function.
332
333**Use cases for custom loader function:**
334
335- Allow configuration syntaxes that aren't handled by Cosmiconfig's defaults, like JSON5, INI, or XML.
336- Allow ES2015 modules from `.mjs` configuration files.
337- Parse JS files with Babel before deriving the configuration.
338
339**Custom loader functions** have the following signature:
340
341```js
342// Sync
343(filepath: string, content: string) => Object | null
344
345// Async
346(filepath: string, content: string) => Object | null | Promise<Object | null>
347```
348
349Cosmiconfig reads the file when it checks whether the file exists, so it will provide you with both the file's path and its content.
350Do whatever you need to, and return either a configuration object or `null` (or, for async-only loaders, a Promise that resolves with one of those).
351`null` indicates that no real configuration was found and the search should continue.
352
353It's easiest if you make your custom loader function synchronous.
354Then it can be used regardless of whether you end up calling [`search()`] or [`searchSync()`], [`load()`] or [`loadSync()`].
355If you want or need to provide an async-only loader, you can do so by making the value of `loaders` an object with an `async` property whose value is the async loader.
356You can also add a `sync` property to designate a sync loader, if you want to use both async and sync search and load functions.
357
358A few things to note:
359
360- If you use a custom loader, be aware of whether it's sync or async and how that aligned with your usage of sync or async search and load functions.
361- **Special JS syntax can also be handled by using a `require` hook**, because `cosmiconfig.loadJs` just uses `require`.
362 Whether you use custom loaders or a `require` hook is up to you.
363
364Examples:
365
366```js
367// Allow JSON5 syntax:
368{
369 '.json': json5Loader
370}
371
372// Allow XML, and treat sync and async separately:
373{
374 '.xml': { async: asyncXmlLoader, sync: syncXmlLoader }
375}
376
377// Allow a special configuration syntax of your own creation:
378{
379 '.special': specialLoader
380}
381
382// Allow many flavors of JS, using custom loaders:
383{
384 '.mjs': esmLoader,
385 '.ts': typeScriptLoader,
386 '.coffee': coffeeScriptLoader
387}
388
389// Allow many flavors of JS but rely on require hooks:
390{
391 '.mjs': cosmiconfig.loadJs,
392 '.ts': cosmiconfig.loadJs,
393 '.coffee': cosmiconfig.loadJs
394}
395```
396
397### packageProp
398
399Type: `string`.
400Default: `` `${moduleName}` ``.
401
402Name of the property in `package.json` to look for.
403
404### stopDir
405
406Type: `string`.
407Default: Absolute path to your home directory.
408
409Directory where the search will stop.
410
411### cache
412
413Type: `boolean`.
414Default: `true`.
415
416If `false`, no caches will be used.
417Read more about ["Caching"](#caching) below.
418
419### transform
420
421Type: `(Result) => Promise<Result> | Result`.
422
423A function that transforms the parsed configuration. Receives the [result].
424
425If using [`search()`] or [`load()`] \(which are async), the transform function can return the transformed result or return a Promise that resolves with the transformed result.
426If using [`searchSync()`] or [`loadSync()`], the function must be synchronous and return the transformed result.
427
428The reason you might use this option — instead of simply applying your transform function some other way — is that *the transformed result will be cached*. If your transformation involves additional filesystem I/O or other potentially slow processing, you can use this option to avoid repeating those steps every time a given configuration is searched or loaded.
429
430### ignoreEmptySearchPlaces
431
432Type: `boolean`.
433Default: `true`.
434
435By default, if [`search()`] encounters an empty file (containing nothing but whitespace) in one of the [`searchPlaces`], it will ignore the empty file and move on.
436If you'd like to load empty configuration files, instead, set this option to `false`.
437
438Why might you want to load empty configuration files?
439If you want to throw an error, or if an empty configuration file means something to your program.
440
441## Caching
442
443As of v2, cosmiconfig uses caching to reduce the need for repetitious reading of the filesystem or expensive transforms. Every new cosmiconfig instance (created with `cosmiconfig()`) has its own caches.
444
445To avoid or work around caching, you can do the following:
446
447- Set the `cosmiconfig` option [`cache`] to `false`.
448- Use the cache-clearing methods [`clearLoadCache()`], [`clearSearchCache()`], and [`clearCaches()`].
449- Create separate instances of cosmiconfig (separate "explorers").
450
451## Differences from [rc](https://github.com/dominictarr/rc)
452
453[rc](https://github.com/dominictarr/rc) serves its focused purpose well. cosmiconfig differs in a few key ways — making it more useful for some projects, less useful for others:
454
455- Looks for configuration in some different places: in a `package.json` property, an rc file, a `.config.js` file, and rc files with extensions.
456- Built-in support for JSON, YAML, and CommonJS formats.
457- Stops at the first configuration found, instead of finding all that can be found up the directory tree and merging them automatically.
458- Options.
459- Asynchronous by default (though can be run synchronously).
460
461## Contributing & Development
462
463Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
464
465And please do participate!
466
467[result]: #result
468
469[`load()`]: #explorerload
470
471[`loadsync()`]: #explorerloadsync
472
473[`search()`]: #explorersearch
474
475[`searchsync()`]: #explorersearchsync
476
477[`clearloadcache()`]: #explorerclearloadcache
478
479[`clearsearchcache()`]: #explorerclearsearchcache
480
481[`clearcaches()`]: #explorerclearcaches
482
483[`packageprop`]: #packageprop
484
485[`cache`]: #cache
486
487[`stopdir`]: #stopdir
488
489[`searchplaces`]: #searchplaces
490
491[`loaders`]: #loaders
492
493[`cosmiconfigoptions`]: #cosmiconfigoptions