UNPKG

27.6 kBMarkdownView Raw
1# cosmiconfig
2
3[![codecov](https://codecov.io/gh/cosmiconfig/cosmiconfig/branch/main/graph/badge.svg)](https://codecov.io/gh/cosmiconfig/cosmiconfig)
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 check the current directory 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`, `.js`, `.ts`, `.mjs`, or `.cjs`
15- any of the above two inside a `.config` subdirectory
16- a `.config.js`, `.config.ts`, `.config.mjs`, or `.config.cjs` file
17
18For example, if your module's name is "myapp", cosmiconfig will search up the directory tree for configuration in the following places:
19
20- a `myapp` property in `package.json`
21- a `.myapprc` file in JSON or YAML format
22- a `.myapprc.json`, `.myapprc.yaml`, `.myapprc.yml`, `.myapprc.js`, `.myapprc.ts`, `.myapprc.mjs`, or `.myapprc.cjs` file
23- a `myapprc`, `myapprc.json`, `myapprc.yaml`, `myapprc.yml`, `myapprc.js`, `myapprc.ts`, `myapprc.mjs`, or `myapprc.cjs` file inside a `.config` subdirectory
24- a `myapp.config.js`, `myapp.config.ts`, `myapp.config.mjs`, or `myapp.config.cjs` file
25
26Optionally, you can tell it to search up the directory tree using [search strategies],
27checking each of these places in each directory, until it finds some acceptable configuration (or hits the home directory).
28
29## Table of contents
30
31- [Installation](#installation)
32- [Usage for tooling developers](#usage-for-tooling-developers)
33- [Result](#result)
34- [Asynchronous API](#asynchronous-api)
35 - [cosmiconfig()](#cosmiconfig-1)
36 - [explorer.search()](#explorersearch)
37 - [explorer.load()](#explorerload)
38 - [explorer.clearLoadCache()](#explorerclearloadcache)
39 - [explorer.clearSearchCache()](#explorerclearsearchcache)
40 - [explorer.clearCaches()](#explorerclearcaches)
41- [Synchronous API](#synchronous-api)
42 - [cosmiconfigSync()](#cosmiconfigsync)
43 - [explorerSync.search()](#explorersyncsearch)
44 - [explorerSync.load()](#explorersyncload)
45 - [explorerSync.clearLoadCache()](#explorersyncclearloadcache)
46 - [explorerSync.clearSearchCache()](#explorersyncclearsearchcache)
47 - [explorerSync.clearCaches()](#explorersyncclearcaches)
48- [cosmiconfigOptions](#cosmiconfigoptions)
49 - [searchStrategy](#searchstrategy)
50 - [searchPlaces](#searchplaces)
51 - [loaders](#loaders)
52 - [packageProp](#packageprop)
53 - [stopDir](#stopdir)
54 - [cache](#cache)
55 - [transform](#transform)
56 - [ignoreEmptySearchPlaces](#ignoreemptysearchplaces)
57- [Loading JS modules](#loading-js-modules)
58- [Caching](#caching)
59- [Differences from rc](#differences-from-rc)
60- [Usage for end users](#usage-for-end-users)
61 - [Imports](#imports)
62- [Contributing & Development](#contributing--development)
63
64## Installation
65
66```
67npm install cosmiconfig
68```
69
70Tested in Node 14+.
71
72## Usage for tooling developers
73
74*If you are an end user (i.e. a user of a tool that uses cosmiconfig, like `prettier` or `stylelint`),
75you can skip down to [the end user section](#usage-for-end-users).*
76
77Create a Cosmiconfig explorer, then either `search` for or directly `load` a configuration file.
78
79```js
80const { cosmiconfig, cosmiconfigSync } = require('cosmiconfig');
81// ...
82const explorer = cosmiconfig(moduleName);
83
84// Search for a configuration by walking up directories.
85// See documentation for search, below.
86explorer.search()
87 .then((result) => {
88 // result.config is the parsed configuration object.
89 // result.filepath is the path to the config file that was found.
90 // result.isEmpty is true if there was nothing to parse in the config file.
91 })
92 .catch((error) => {
93 // Do something constructive.
94 });
95
96// Load a configuration directly when you know where it should be.
97// The result object is the same as for search.
98// See documentation for load, below.
99explorer.load(pathToConfig).then(/* ... */);
100
101// You can also search and load synchronously.
102const explorerSync = cosmiconfigSync(moduleName);
103
104const searchedFor = explorerSync.search();
105const loaded = explorerSync.load(pathToConfig);
106```
107
108## Result
109
110The result object you get from `search` or `load` has the following properties:
111
112- **config:** The parsed configuration object. `undefined` if the file is empty.
113- **filepath:** The path to the configuration file that was found.
114- **isEmpty:** `true` if the configuration file is empty. This property will not be present if the configuration file is not empty.
115
116## Asynchronous API
117
118### cosmiconfig()
119
120```js
121const { cosmiconfig } = require('cosmiconfig');
122const explorer = cosmiconfig(moduleName, /* optional */ cosmiconfigOptions)
123```
124
125Creates a cosmiconfig instance ("explorer") configured according to the arguments, and initializes its caches.
126
127#### moduleName
128
129Type: `string`. **Required.**
130
131Your module name. This is used to create the default [`searchPlaces`] and [`packageProp`].
132
133If your [`searchPlaces`] value will include files, as it does by default (e.g. `${moduleName}rc`), your `moduleName` must consist of characters allowed in filenames. That means you should not copy scoped package names, such as `@my-org/my-package`, directly into `moduleName`.
134
135**[`cosmiconfigOptions`] are documented below.**
136You may not need them, and should first read about the functions you'll use.
137
138### explorer.search()
139
140```js
141explorer.search([searchFrom]).then(result => { /* ... */ })
142```
143
144Searches for a configuration file. Returns a Promise that resolves with a [result] or with `null`, if no configuration file is found.
145
146You can do the same thing synchronously with [`explorerSync.search()`].
147
148Let's say your module name is `goldengrahams` so you initialized with `const explorer = cosmiconfig('goldengrahams');`.
149Here's how your default [`search()`] will work:
150
151- Starting from `process.cwd()` (or some other directory defined by the `searchFrom` argument to [`search()`]), look for configuration objects in the following places:
152 1. A `goldengrahams` property in a `package.json` file.
153 2. A `.goldengrahamsrc` file with JSON or YAML syntax.
154 3. A `.goldengrahamsrc.json`, `.goldengrahamsrc.yaml`, `.goldengrahamsrc.yml`, `.goldengrahamsrc.js`, `.goldengrahamsrc.ts`, `.goldengrahamsrc.mjs`, or `.goldengrahamsrc.cjs` file. (To learn more about how JS files are loaded, see ["Loading JS modules"].)
155 4. A `goldengrahamsrc`, `goldengrahamsrc.json`, `goldengrahamsrc.yaml`, `goldengrahamsrc.yml`, `goldengrahamsrc.js`, `goldengrahamsrc.ts`, `goldengrahamsrc.mjs`, or `goldengrahamsrc.cjs` file in the `.config` subdirectory.
156 5. A `goldengrahams.config.js`, `goldengrahams.config.ts`, `goldengrahams.config.mjs`, or `goldengrahams.config.cjs` file. (To learn more about how JS files are loaded, see ["Loading JS modules"].)
157- If none of those searches reveal a configuration object, continue depending on the current search strategy:
158 - If it's `none` (which is the default if you don't specify a [`stopDir`] option), stop here and return/resolve with `null`.
159 - If it's `global` (which is the default if you specify a [`stopDir`] option), move up one directory level and try again,
160 recursing until arriving at the configured [`stopDir`] option, which defaults to the user's home directory.
161 - After arriving at the [`stopDir`], the global configuration directory (as defined by [`env-paths`] without prefix) is also checked,
162 looking at the files `config`, `config.json`, `config.yaml`, `config.yml`, `config.js`, `config.ts`, `config.cjs`, and `config.mjs`
163 in the directory `~/.config/goldengrahams/` (on Linux; see [`env-paths`] documentation for other OSs).
164 - If it's `project`, check whether a `package.json` file is present in the current directory, and if not,
165 move up one directory level and try again, recursing until there is one.
166- If at any point a parsable configuration is found, the [`search()`] Promise resolves with its [result] \(or, with [`explorerSync.search()`], the [result] is returned).
167- If no configuration object is found, the [`search()`] Promise resolves with `null` (or, with [`explorerSync.search()`], `null` is returned).
168- 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 [`explorerSync.search()`], the error is thrown.)
169
170**If you know exactly where your configuration file should be, you can use [`load()`], instead.**
171
172**The search process is highly customizable.**
173Use the cosmiconfig options [`searchPlaces`] and [`loaders`] to precisely define where you want to look for configurations and how you want to load them.
174
175#### searchFrom
176
177Type: `string`.
178Default: `process.cwd()`.
179
180A filename.
181[`search()`] will start its search here.
182
183If the value is a directory, that's where the search starts.
184If it's a file, the search starts in that file's directory.
185
186### explorer.load()
187
188```js
189explorer.load(loadPath).then(result => { /* ... */ })
190```
191
192Loads 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).
193
194Use `load` if you already know where the configuration file is and you just need to load it.
195
196```js
197explorer.load('load/this/file.json'); // Tries to load load/this/file.json.
198```
199
200If you load a `package.json` file, the result will be derived from whatever property is specified as your [`packageProp`].
201`package.yaml` will work as well if you specify these file names in your [`searchPlaces`].
202
203You can do the same thing synchronously with [`explorerSync.load()`].
204
205### explorer.clearLoadCache()
206
207Clears the cache used in [`load()`].
208
209### explorer.clearSearchCache()
210
211Clears the cache used in [`search()`].
212
213### explorer.clearCaches()
214
215Performs both [`clearLoadCache()`] and [`clearSearchCache()`].
216
217## Synchronous API
218
219### cosmiconfigSync()
220
221```js
222const { cosmiconfigSync } = require('cosmiconfig');
223const explorerSync = cosmiconfigSync(moduleName, /* optional */ cosmiconfigOptions)
224```
225
226Creates a *synchronous* cosmiconfig instance ("explorerSync") configured according to the arguments, and initializes its caches.
227
228See [`cosmiconfig()`](#cosmiconfig-1).
229
230### explorerSync.search()
231
232```js
233const result = explorerSync.search([searchFrom]);
234```
235
236Synchronous version of [`explorer.search()`].
237
238Returns a [result] or `null`.
239
240### explorerSync.load()
241
242```js
243const result = explorerSync.load(loadPath);
244```
245
246Synchronous version of [`explorer.load()`].
247
248Returns a [result].
249
250### explorerSync.clearLoadCache()
251
252Clears the cache used in [`load()`].
253
254### explorerSync.clearSearchCache()
255
256Clears the cache used in [`search()`].
257
258### explorerSync.clearCaches()
259
260Performs both [`clearLoadCache()`] and [`clearSearchCache()`].
261
262## cosmiconfigOptions
263
264Type: `Object`.
265
266Possible options are documented below.
267
268### searchStrategy
269
270Type: `string`
271Default: `global` if [`stopDir`] is specified, `none` otherwise.
272
273The strategy that should be used to determine which directories to check for configuration files.
274
275- `none`: Only checks in the current working directory.
276- `project`: Starts in the current working directory, traversing upwards until a `package.{json,yaml}` file is found.
277- `global`: Starts in the current working directory, traversing upwards until the configured [`stopDir`]
278 (or the current user's home directory if none is given). Then, if no configuration is found, also look in the
279 operating system's default configuration directory (according to [`env-paths`] without prefix),
280 where a different set of file names is checked:
281
282```js
283[
284 `config`,
285 `config.json`,
286 `config.yaml`,
287 `config.yml`,
288 `config.js`,
289 `config.ts`,
290 `config.cjs`,
291 `config.mjs`
292]
293```
294
295### searchPlaces
296
297Type: `Array<string>`.
298Default: See below.
299
300An array of places that [`search()`] will check in each directory as it moves up the directory tree.
301Each place is relative to the directory being searched, and the places are checked in the specified order.
302
303**Default `searchPlaces`:**
304
305For the [asynchronous API](#asynchronous-api), these are the default `searchPlaces`:
306
307```js
308[
309 'package.json',
310 `.${moduleName}rc`,
311 `.${moduleName}rc.json`,
312 `.${moduleName}rc.yaml`,
313 `.${moduleName}rc.yml`,
314 `.${moduleName}rc.js`,
315 `.${moduleName}rc.ts`,
316 `.${moduleName}rc.mjs`,
317 `.${moduleName}rc.cjs`,
318 `.config/${moduleName}rc`,
319 `.config/${moduleName}rc.json`,
320 `.config/${moduleName}rc.yaml`,
321 `.config/${moduleName}rc.yml`,
322 `.config/${moduleName}rc.js`,
323 `.config/${moduleName}rc.ts`,
324 `.config/${moduleName}rc.mjs`,
325 `.config/${moduleName}rc.cjs`,
326 `${moduleName}.config.js`,
327 `${moduleName}.config.ts`,
328 `${moduleName}.config.mjs`,
329 `${moduleName}.config.cjs`,
330];
331```
332
333For the [synchronous API](#synchronous-api), the only difference is that `.mjs` files are not included. See ["Loading JS modules"] for more information.
334
335Create your own array to search more, fewer, or altogether different places.
336
337Every item in `searchPlaces` needs to have a loader in [`loaders`] that corresponds to its extension.
338(Common extensions are covered by default loaders.)
339Read more about [`loaders`] below.
340
341`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.
342That property is defined with the [`packageProp`] option, and defaults to your module name.
343
344`package.yaml` (used by pnpm) works the same way.
345
346Examples, with a module named `porgy`:
347
348```js
349// Disallow extensions on rc files:
350['package.json', '.porgyrc', 'porgy.config.js']
351```
352
353```js
354// Limit the options dramatically:
355['package.json', '.porgyrc']
356```
357
358```js
359// Maybe you want to look for a wide variety of JS flavors:
360[
361 'porgy.config.js',
362 'porgy.config.mjs',
363 'porgy.config.ts',
364 'porgy.config.coffee'
365]
366// ^^ You will need to designate a custom loader to tell
367// Cosmiconfig how to handle `.coffee` files.
368```
369
370```js
371// Look within a .config/ subdirectory of every searched directory:
372[
373 'package.json',
374 '.porgyrc',
375 '.config/.porgyrc',
376 '.porgyrc.json',
377 '.config/.porgyrc.json'
378]
379```
380
381### loaders
382
383Type: `Object`.
384Default: See below.
385
386An object that maps extensions to the loader functions responsible for loading and parsing files with those extensions.
387
388Cosmiconfig exposes its default loaders on the named export `defaultLoaders` and `defaultLoadersSync`.
389
390**Default `loaders`:**
391
392```js
393const { defaultLoaders, defaultLoadersSync } = require('cosmiconfig');
394
395console.log(Object.entries(defaultLoaders));
396// [
397// [ '.mjs', [Function: loadJs] ],
398// [ '.cjs', [Function: loadJs] ],
399// [ '.js', [Function: loadJs] ],
400// [ '.ts', [Function: loadTs] ],
401// [ '.json', [Function: loadJson] ],
402// [ '.yaml', [Function: loadYaml] ],
403// [ '.yml', [Function: loadYaml] ],
404// [ 'noExt', [Function: loadYaml] ]
405// ]
406
407console.log(Object.entries(defaultLoadersSync));
408// [
409// [ '.cjs', [Function: loadJsSync] ],
410// [ '.js', [Function: loadJsSync] ],
411// [ '.ts', [Function: loadTsSync] ],
412// [ '.json', [Function: loadJson] ],
413// [ '.yaml', [Function: loadYaml] ],
414// [ '.yml', [Function: loadYaml] ],
415// [ 'noExt', [Function: loadYaml] ]
416// ]
417```
418
419(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.)
420
421**If you provide a `loaders` object, your object will be *merged* with the defaults.**
422So you can override one or two without having to override them all.
423
424**Keys in `loaders`** are extensions (starting with a period), or `noExt` to specify the loader for files *without* extensions, like `.myapprc`.
425
426**Values in `loaders`** are a loader function (described below) whose values are loader functions.
427
428**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).
429To accomplish that, provide the following `loaders` value:
430
431```js
432{
433 noExt: defaultLoaders['.json'];
434}
435```
436
437If you want to load files that are not handled by the loader functions Cosmiconfig exposes, you can write a custom loader function or use one from NPM if it exists.
438
439**Use cases for custom loader function:**
440
441- Allow configuration syntaxes that aren't handled by Cosmiconfig's defaults, like JSON5, INI, or XML.
442- Parse JS files with Babel before deriving the configuration.
443
444**Custom loader functions** have the following signature:
445
446```ts
447// Sync
448type SyncLoader = (filepath: string, content: string) => Object | null
449
450// Async
451type AsyncLoader = (filepath: string, content: string) => Object | null | Promise<Object | null>
452```
453
454Cosmiconfig reads the file when it checks whether the file exists, so it will provide you with both the file's path and its content.
455Do 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).
456`null` indicates that no real configuration was found and the search should continue.
457
458A few things to note:
459
460- If you use a custom loader, be aware of whether it's sync or async: you cannot use async customer loaders with the sync API ([`cosmiconfigSync()`]).
461- **Special JS syntax can also be handled by using a `require` hook**, because `defaultLoaders['.js']` just uses `require`.
462 Whether you use custom loaders or a `require` hook is up to you.
463
464Examples:
465
466```js
467// Allow JSON5 syntax:
468cosmiconfig('foo', {
469 loaders: {
470 '.json': json5Loader
471 }
472});
473
474// Allow a special configuration syntax of your own creation:
475cosmiconfig('foo', {
476 loaders: {
477 '.special': specialLoader
478 }
479});
480
481// Allow many flavors of JS, using custom loaders:
482cosmiconfig('foo', {
483 loaders: {
484 '.coffee': coffeeScriptLoader
485 }
486});
487
488// Allow many flavors of JS but rely on require hooks:
489cosmiconfig('foo', {
490 loaders: {
491 '.coffee': defaultLoaders['.js']
492 }
493});
494```
495
496### packageProp
497
498Type: `string | Array<string>`.
499Default: `` `${moduleName}` ``.
500
501Name of the property in `package.json` (or `package.yaml`) to look for.
502
503Use a period-delimited string or an array of strings to describe a path to nested properties.
504
505For example, the value `'configs.myPackage'` or `['configs', 'myPackage']` will get you the `"myPackage"` value in a `package.json` like this:
506
507```json
508{
509 "configs": {
510 "myPackage": {"option": "value"}
511 }
512}
513```
514
515If nested property names within the path include periods, you need to use an array of strings. For example, the value `['configs', 'foo.bar', 'baz']` will get you the `"baz"` value in a `package.json` like this:
516
517```json
518{
519 "configs": {
520 "foo.bar": {
521 "baz": {"option": "value"}
522 }
523 }
524}
525```
526
527If a string includes period but corresponds to a top-level property name, it will not be interpreted as a period-delimited path. For example, the value `'one.two'` will get you the `"three"` value in a `package.json` like this:
528
529```json
530{
531 "one.two": "three",
532 "one": {
533 "two": "four"
534 }
535}
536```
537
538### stopDir
539
540Type: `string`.
541Default: Absolute path to your home directory.
542
543Directory where the search will stop.
544
545### cache
546
547Type: `boolean`.
548Default: `true`.
549
550If `false`, no caches will be used.
551Read more about ["Caching"](#caching) below.
552
553### transform
554
555Type: `(Result) => Promise<Result> | Result`.
556
557A function that transforms the parsed configuration. Receives the [result].
558
559If 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.
560If using `cosmiconfigSync`, [`search()`] or [`load()`], the function must be synchronous and return the transformed result.
561
562The 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.
563
564### ignoreEmptySearchPlaces
565
566Type: `boolean`.
567Default: `true`.
568
569By 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.
570If you'd like to load empty configuration files, instead, set this option to `false`.
571
572Why might you want to load empty configuration files?
573If you want to throw an error, or if an empty configuration file means something to your program.
574
575## Loading JS modules
576
577Your end users can provide JS configuration files as ECMAScript modules (ESM) under the following conditions:
578
579- You (the cosmiconfig user) use cosmiconfig's [asynchronous API](#asynchronous-api).
580- Your end user runs a version of Node that supports ESM ([>=12.17.0](https://nodejs.org/en/blog/release/v12.17.0/), or earlier with the `--experimental-modules` flag).
581- Your end user provides an `.mjs` configuration file, or a `.js` file whose nearest parent `package.json` file contains `"type": "module"`. (See [Node's method for determining a file's module system](https://nodejs.org/api/packages.html#packages_determining_module_system).)
582
583With cosmiconfig's [asynchronous API](#asynchronous-api), the default [`searchPlaces`] include `.js`, `.ts`, `.mjs`, and `.cjs` files. Cosmiconfig loads all these file types with the [dynamic `import` function](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports).
584
585With the [synchronous API](#synchronous-api), JS configuration files are always treated as CommonJS, and `.mjs` files are ignored, because there is no synchronous API for the dynamic `import` function.
586
587## Caching
588
589As 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.
590
591To avoid or work around caching, you can do the following:
592
593- Set the `cosmiconfig` option [`cache`] to `false`.
594- Use the cache-clearing methods [`clearLoadCache()`], [`clearSearchCache()`], and [`clearCaches()`].
595- Create separate instances of cosmiconfig (separate "explorers").
596
597## Differences from [rc](https://github.com/dominictarr/rc)
598
599[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:
600
601- Looks for configuration in some different places: in a `package.json` property, an rc file, a `.config.js` file, and rc files with extensions.
602- Built-in support for JSON, YAML, and CommonJS formats.
603- Stops at the first configuration found, instead of finding all that can be found up the directory tree and merging them automatically.
604- Options.
605- Asynchronous by default (though can be run synchronously).
606
607## Usage for end users
608
609When configuring a tool, you can use multiple file formats and put these in multiple places.
610
611Usually, a tool would mention this in its own README file,
612but by default, these are the following places, where `{NAME}` represents the name of the tool:
613
614```
615package.json
616.{NAME}rc
617.{NAME}rc.json
618.{NAME}rc.yaml
619.{NAME}rc.yml
620.{NAME}rc.js
621.{NAME}rc.ts
622.{NAME}rc.cjs
623.config/{NAME}rc
624.config/{NAME}rc.json
625.config/{NAME}rc.yaml
626.config/{NAME}rc.yml
627.config/{NAME}rc.js
628.config/{NAME}rc.ts
629.config/{NAME}rc.mjs
630.config/{NAME}rc.cjs
631{NAME}.config.js
632{NAME}.config.ts
633{NAME}.config.mjs
634{NAME}.config.cjs
635```
636
637The contents of these files are defined by the tool.
638For example, you can configure prettier to enforce semicolons at the end of the line
639using a file named `.config/prettierrc.yml`:
640
641```yaml
642semi: true
643```
644
645Additionally, you have the option to put a property named after the tool in your `package.json` file,
646with the contents of that property being the same as the file contents. To use the same example as above:
647
648```json
649{
650 "name": "your-project",
651 "dependencies": {},
652 "prettier": {
653 "semi": true
654 }
655}
656```
657
658This has the advantage that you can put the configuration of all tools
659(at least the ones that use cosmiconfig) in one file.
660
661You can also add a `cosmiconfig` key within your `package.json` file or create one of the following files
662to configure `cosmiconfig` itself:
663
664```
665.config/config.json
666.config/config.yaml
667.config/config.yml
668.config/config.js
669.config/config.ts
670.config/config.cjs
671```
672
673The following properties are currently actively supported in these places:
674
675```yaml
676cosmiconfig:
677 # adds places where configuration files are being searched
678 searchPlaces:
679 - .config/{name}.yml
680 # to enforce a custom naming convention and format, don't merge the above with the tool-defined search places
681 # (`true` is the default setting)
682 mergeSearchPlaces: false
683```
684
685> **Note:** technically, you can overwrite all options described in [cosmiconfigOptions](#cosmiconfigoptions) here,
686> but everything not listed above should be used at your own risk, as it has not been tested explicitly.
687> The only exceptions to this are the `loaders` property, which is explicitly not supported at this time,
688> and the `searchStrategy` property, which is intentionally disallowed.
689
690You can also add more root properties outside the `cosmiconfig` property
691to configure your tools, entirely eliminating the need to look for additional configuration files:
692
693```yaml
694cosmiconfig:
695 searchPlaces: []
696
697prettier:
698 semi: true
699```
700
701### Imports
702
703Wherever you put your configuration (the package.json file, a root config file or a package-specific config file),
704you can use the special `$import` key to import another file as a base.
705
706For example, you can import from an npm package (in this example, `@foocorp/config`).
707
708`.prettierrc.base.yml` in said npm package could define some company-wide defaults:
709
710```yaml
711printWidth: 120
712semi: true
713tabWidth: 2
714```
715
716And then, the `.prettierrc.yml` file in the project itself would just reference that file,
717optionally overriding the defaults with project-specific settings:
718
719```yaml
720$import: node_modules/@foocorp/config/.prettierrc.base.yml
721# we want more space!
722printWidth: 200
723```
724
725It is possible to import multiple base files by specifying an array of paths,
726which will be processed in declaration order;
727that means that the last entry will win if there are conflicting properties.
728
729It is also possible to import file formats other than the importing format
730as long as they are supported by the loaders specified by the developer of the tool you're configuring.
731
732```yaml
733$import: [first.yml, second.json, third.config.js]
734```
735
736## Contributing & Development
737
738Please 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.
739
740And please do participate!
741
742[result]: #result
743
744[`load()`]: #explorerload
745
746[`search()`]: #explorersearch
747
748[`clearloadcache()`]: #explorerclearloadcache
749
750[`clearsearchcache()`]: #explorerclearsearchcache
751
752[`cosmiconfig()`]: #cosmiconfig
753
754[`cosmiconfigSync()`]: #cosmiconfigsync
755
756[`clearcaches()`]: #explorerclearcaches
757
758[`packageprop`]: #packageprop
759
760[`cache`]: #cache
761
762[`stopdir`]: #stopdir
763
764[`searchplaces`]: #searchplaces
765
766[`loaders`]: #loaders
767
768[`cosmiconfigoptions`]: #cosmiconfigoptions
769
770[`explorerSync.search()`]: #explorersyncsearch
771
772[`explorerSync.load()`]: #explorersyncload
773
774[`explorer.search()`]: #explorersearch
775
776[`explorer.load()`]: #explorerload
777
778["Loading JS modules"]: #loading-js-modules
779
780[`env-paths`]: https://github.com/sindresorhus/env-paths
781
782[search strategies]: #searchstrategy