unified-engine icon indicating copy to clipboard operation
unified-engine copied to clipboard

Support .config folder for storing configuration by default

Open ChristianMurphy opened this issue 2 years ago • 6 comments

Initial checklist

Problem

Project root folders being stuck with a bunch of . configs files for various tools, remark or rehype being just one of many. As a result, it is harder to find actual source files in the project.

Solution

.config/ is a convention supported by cosmiconfig, and by extension a number command line tools (stylelint, prettier, eslint-mdx, and others). Which allows top level configuration files to be moved out of the root folder and into .config/ folder, clarifying the intent of the files, and separating source code from configuration files/code.

Alternatives

Leave configuration system as it is today, adding notes/recommendations pointing towards either:

  • package.json remarkConfig property as a way to combine files
  • and/or pointing adopters set --rc-path a layer of abstraction up in https://github.com/unifiedjs/unified-args#cli to point to the .config folder on their own.

ChristianMurphy avatar Feb 13 '23 18:02 ChristianMurphy

A potential consideration, is it creates ambiguity on whether any markdown files in .config/ should or should not be linted. Currently they would not, but that could change based on https://github.com/unifiedjs/unified-engine/issues/55

ChristianMurphy avatar Feb 13 '23 18:02 ChristianMurphy

As a result, it is harder to find actual source files in the project.

I feel like source files are typically in src/ or lib/, maybe packages/? I get that with many files, things become harder to find, but config files are the only ones that are in the root, the rest is neatly in folders. And doesn’t the . already classify config files as different from source files?

clarifying the intent of the files

I feel like a name of .remarkrc.js is already clear about the tool it’s for (remark), what the file does (., and rc, configuration), and what language it’s in (js).


My main problem with this is: For every file that we found (say, example.md), we currently search in every folder it’s in, for 8 files (.remarkrc, .remarkrc.json, .remarkrc.cjs, .remarkrc.mjs, .remarkrc.js, .remarkrc.yml, .remarkrc.yaml, package.json). We will have to double that work: for every folder, also search for 8 files in .config/. This seems


it creates ambiguity on whether any markdown files in .config/ should or should not be linted. Currently they would not, but that could change based on https://github.com/unifiedjs/unified-engine/issues/55

I’m leaning a bit more into thinking that dotfiles should be included by default. Even if it didn’t land, people can still pas remark . .config to include the folder explicitly. So, the question is more: .config/example.md will be configured by .config/.config/.remarkrc* (which feels weird) and if that doesn’t exist by .config/.remarkrc* (which might not be what you expected when that config file was authored).


Another alternative: I think a symlink for a .remarkrc to .config/.remarkrc might work too

wooorm avatar Feb 28 '23 09:02 wooorm

Cross-linking to config-dir proposal.

Since this is an egg-and-chicken problem (more tools won't use .config unless streamlined ones do!) maybe it is worth to add .config/ dir checks as fallback? (so no merging but only fallback to unblock the possibility for end-users and pushing it forward 🙏🏼 )

pi0 avatar Feb 14 '24 20:02 pi0

Glad that you're working on this! Appreciated!

When is the work done? When .config is supported? When only .config instead of root folder works? Do you want tools to drop root folder support?

Say we have a markdown linter, which has a .xrc config file, should that file when placed in .config apply to markdown in .config, or does it need to be at .config/.config/.xrc?

wooorm avatar Feb 14 '24 21:02 wooorm

For the sake of simplicity I’m just using remark as an example here.

The config-dir proposal explicitly states .config/[name].[ext] should be used. So for example .config/remark.json, not .config/.remarkrc.

Maybe we should support only that, and also fewer formats. Fewer options means less ambiguity regarding which file is used or which one takes precedence over which one.

Just a thought, we could support:

  • .config/remark.js — Imported using a dynamic import. Useful if the configuration contains more than just JSON serializable values, i.e. for remark-retext.
  • .config/remark.json — Loaded with jsonc-parser to support comments. IIRC good for caching over JavaScript?
  • .config/remark.mjs — Useful for projects that use CommonJS.

This means removing support for:

  • .remarkrc — Extensionless causes ambiguity about the format. We know it’s JSON, but most other tools such as code viewers and editors don’t.
  • .remarkrc.cjs — Not really useful. CJS can be imported from ESM, and most packages a remark config uses, are ESM.
  • .remarkrc.js — Moved to .config/remark.js
  • .remarkrc.json — Moved to .config/remark.json
  • .remarkrc.mjs — Moved to .config/remark.mjs
  • .remarkrc.yaml — I personally like YAML, but it’s yet another format to support. One of the biggest benefits compared to JSON IMO is that it supports comments. This would be solved by using JSONC.
  • .remarkrc.yml — Same as .remarkrc.yaml

Then there’s also the remarkConfig key in package.json. I’m not a fan of this. It’s a format that doesn’t support comments. Also this gets published to npm. The benefit with this is to reduce the number of files in a project root, which is the same problem the config-dir proposal solves.

Of course removing support for existing config files would be semver major.

remcohaszing avatar Feb 15 '24 10:02 remcohaszing

Cross-referencing this discussion, where support for other projects is tracked.

https://github.com/pi0/config-dir/discussions/6

remcohaszing avatar Feb 15 '24 10:02 remcohaszing