unifiedjs / unified-engine

Engine to process multiple files with unified
https://unifiedjs.com
MIT License
56 stars 23 forks source link

Implement overrides similar to ESLint #56

Open remcohaszing opened 2 years ago

remcohaszing commented 2 years ago

Initial checklist

Problem

Sometimes certain checks depend on context, not just language.

For example, typically markdown documents need to contain complete and valid markdown documents. Some specific documents may need some specific checks to be included or excluded though. For example:

Solution

ESLint has pretty much the exact problem. They solved it using overrides

The same could be done for unified-engine. For example:

plugins:
  - remark-gfm
  - [remark-lint-first-heading-level, 1]
overrides:
  - files: ['*.mdx']
    plugins:
      - remark-mdx
  - files: [.github/]
    plugins:
      - [remark-lint-first-heading-level, false]

ESLint also uses the globs to determine additional file extensions to check.

Alternatives

I can’t really think of anything else

wooorm commented 2 years ago
remcohaszing commented 2 years ago
  • It’s possible to place different RC files in different folders, how does this interfere with that?

I don’t know. Perhaps we should have a look at how ESLint handles it.

  • What about plugin order? Especially as remark could be used with, say, remark-rehype, to switch to another format.

I think override means the override takes precedence over the original value, including any options. The fact that remark-rehype transforms the AST significantly or has bridge and mutate mode is a detail. Also I don’t think remark-rehype should typically be used with unified-engine. It’s a bit annoying for remark-retext though, but I don’t think it’s likely users will want to apply different retext rules depending on context. Even if they do, it could be overridden programmatically.

const retextPlugins = [
  [someRetextPlugin]
]

export default {
  plugins: [
    ['remark-retext', unified().use(retextPlugins)]
  ],
  overrides: [
    files: ['*.mdx'],
    plugins: [
      ['remark-retext', unified().use([...retextPlugins, anotherRetextPlugin])]
    ],
  ]
}
wooorm commented 2 years ago

It’s possible to place different RC files in different folders, how does this interfere with that?

I think this point won’t need any special handling. It’ll just work. Assuming a user has multiple config files, then they already dealt with them replacing instead of extending each other. Say there’s a config in a monorepo, and one in a subpackage, then the user would presumably understand that overrides for certain files need to be in their closest config file?


Also I don’t think remark-rehype should typically be used with unified-engine

I’m not so sure. At least I find it an an important case to support properly. Maybe, similar to how config files override (replace) each other instead of merge, the same should occur with overrides too? Replace instead of merge.


One even bigger problem I didn’t think of: config files are also presets. 😬 Config files and presets can be loaded from say node_modules. 😬