question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Proposal for a new v5 options scheme to allow for all kinds of flexibility

See original GitHub issue

We’ve had quite a few requests, some recent and some older, asking for more flexible ways to find, name, and parse files. Here’s what I dug up:

We’ve also had a discussion about the way extensionless rc files are parsed. We’ve talked about adding a parseJs option (to address the request above for alternate flavors of JS); and, as was inevitable, the suggestion came up for parseJson and parseYaml options to allow for alternate flavors of those languages — which got me anticipating eventual requests to parse XML or INI or yet-unheard-of languages. It also got me looking at the current rc, rcStrictJson, and rcExtensions options, and realizing how conceptually tangled they are.

So, I’m wondering if there’s a way we could set up v5 to allow for any filenames, searched for in any order, and parsed with any parsers.

Here’s what I’ve come up with:

What if we do away with most of the existing options (packageProp, rc, js, rcStrictJson, and rcExtensions), and instead have a flexible searchScheme option.

  • searchScheme is an array representing an ordered list of things to search for in each directory.
  • Each item in the array is either an object or a string.
  • Object items can have the following properties:
    • filename: The filename of a file to search for, relative to the directory being searched; e.g. .stylelintrc, .stylelintrc.json, stylelint.config.js, package.json. Could even include a directory if you wanted to search in a .config/ subdirectory of every searched directory.
    • parser: A parser function to use. Optional: If this is not provided, we’ll parse .js as JS, .json as JSON, .yaml and .yml as YAML, and extensionless rc files as YAML (which incorporates JSON). We’d expose some standard parsers on the cosmiconfig object that people could use here, or they could bring their own.
    • property: A property to look for in the file. Optional: The main use case for this is package.json, and by default it will match the moduleName you provided when you initialized cosmiconfig. We could even accept an array to indicate nesting, to address the request above for config.mything within package.json.
  • String items are the equivalent of providing only a filename on an object and accepting the other defaults.

Here are a bunch of examples to illustrate how searchScheme would work to address all these use cases. They all assume your tool’s name is plod.

// The current default settings, verbose.
a = [
  {
    filename: 'package.json',
    property: 'plod',
    parser: cosmiconfig.parseJson
  },
  {
    filename: '.plodrc',
    parser: cosmiconfig.parseYaml
  },
  {
    filename: 'plod.config.js',
    parser: cosmiconfig.parseJs
  }
]

// The current default settings, concise.
b = [
  'package.json',
  '.plodrc',
  'plog.config.js'
]

// The current default plus rcStrictJson: true,
// so not allowing YAML in extensionless rc files.
c = [
  'package.json',
  {
    filename: '.plodrc',
    parser: cosmiconfig.parseJson
  },
  'plod.config.js'
]

// The current default plus rcExtensions: true,
// with string entries. **I suggest we make this
// the new default.**
d = [
  'package.json',
  '.plodrc',
  '.plodrc.json',
  '.plodrc.yaml',
  '.plodrc.yml',
  '.plodrc.js',
  'plod.config.js'
]

// ESLint could do this.
// cf. https://eslint.org/docs/user-guide/configuring#configuration-file-formats
e = [
  '.eslintrc.js',
  '.eslintrc.yaml',
  '.eslintrc.yml',
  '.eslintrc.json',
  '.eslintrc',
  {
    filename: 'package.json',
    property: 'eslintConfig'
  }
]

// Babel could do this.
// cf. https://babeljs.io/docs/usage/babelrc/
f = [
  'package.json',
  {
    filename: '.babelrc',
    parser: someJson5Parser
  }
]

// Allow a JS file with ES2015 module syntax
// and .js or .mjs extensions; or a .ts file;
g = [
  {
    filename: 'plod.js',
    parser: someEs2015ModuleParser
  },
  {
    filename: 'plod.mjs',
    parser: someEs2015ModuleParser
  },
  {
    filename: 'plod.ts',
    parser: someTypeScriptParser
  }
]

// Allow extensionless YAML and JSON files
// within or outside of .config/ subdirectories.
h = [
  {
    filename: '.plodrc',
    parser: cosmiconfig.parseYaml
  },
  {
    filename: '.config/.plodrc',
    parser: cosmiconfig.parseYaml
  }
]

// Look within the config property of package.json.
i = [
  {
    filename: 'package.json',
    property: ['config', 'plod']
  }
]

This proposal wouldn’t affect the way load/loadSync and search/searchSync or the caches work — just the way you configure cosmiconfig to search for and parse the formats you want. I think it could work, and also provide the possibility for indefinite extension without the need to add more options in the future. (At most, we might end up adding more defaults or exposing more parsers in the future, if we find that some unaddressed usage is super common.)

I suggest that we add rc files with extensions to the default configuration because I think it’s being used all over the place. I know that stylelint, Prettier, and lint-staged use it.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:8 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
davidtheclarkcommented, Apr 27, 2018

@olsonpm: That is a very good and devastating point. This whole idea doesn’t address load very well, does it. 🤔

Maybe we should consider the following variation:

  • Three options: loaders, searchPlaces, and packageProp.
  • loaders maps extensions to loaders. Loaders are functions that accept a file’s path and its contents and return a config object or null. Usually they’ll be sync because they already have the file’s contents, just have to parse it in some way. A loaders value can be a single loader function, which we’ll assume to be sync, or an object exposing sync and async function. js, json, yaml, yml, and no-extension all have default loaders; and those default loaders will be exposed on cosmiconfig.loadJson, etc. Users could set js to their Babel-powered loader, or mjs to their ES2015 module loader, or ts to their TypeScript loader, or ini to their INI loader. They could also set no-extension to cosmiconfig.loadJson if they want to only allow strict JSON. loaders can apply to both search and load.
  • searchPlaces is just an array of paths (no objects), determining which files we look at, in which order. It only applies to search.
  • packageProp determines which property to look for in package.json, same as now. We won’t build in the ability to get nested properties on other config files, but users could do that with custom loaders.

I think this plan would address all the use cases described above and also handle load.

0reactions
davidtheclarkcommented, May 5, 2018

Implemented in #129.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ADVANCED DEMAND FLEXIBILITY MANAGEMENT
Offers options to all customers for bill and demand management choices, ... SDG&E's proposal for a new rate for separately metered EV ...
Read more >
Wagner-Peyser Act Staffing Flexibility - Federal Register
One of the goals of providing staffing flexibility is to give States more options in designing their workforce development systems, ...
Read more >
[4910-EX-P] Federal Motor Carrier Safety Administration
Finally, FMCSA proposes to add a new option under § 395.3(a)(3)(iii) that would allow one off-duty break ofat least 30 minutes, ...
Read more >
How To Propose a Flexible Work Schedule - The Balance
A flexible work schedule allows you to work hours that are different from the typical 8 a.m. to 5 p.m. Monday to Friday...
Read more >
Flexibility in Highway Design
A design for new construction, reconstruction, resurfacing. ... All these options may give designers flexibility to use their expertise and judgment.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found