Change Request: Support arbitrary config loaders #17211
Labels
archived due to age
This issue has been archived; please open a new issue for any further discussion
core
Relates to ESLint's core APIs and features
enhancement
This change enhances an existing feature of ESLint
ESLint version
8.40.0
What problem do you want to solve?
Now that flat config is in place, and is going to become the default in v9 (as I understand it), I'd like to discuss re-opening supporting non-JS config files again, a la #12078 and eslint/rfcs/pull/50.
From reading through the various comments made at the time, I think the main objection was pulling external support into ESLint to handle non-JS files, effectively being a "kingmaker" by making anything else first-class - and a more general system that doesn't favour any particular language or tooling was the preferred way to go, but proposals stalled with flat config going on at the time.
I'm not suggesting specifically supporting Typescript config files, or any other language, but I think we can capitalise on the fact that flat config has now simplified how configuration is handled.
(full disclosure, supporting typescript configuration files is my main goal here, so that I can get type checked configurations and rule options, but I'm trying to show due consideration to the issues raised previously 😄)
What do you think is the correct solution?
From my understanding of flat config in lib/eslint/flat-eslint.js, configuration is now only loaded from a single entry-point by loading a single file as a module via
import()
(eslint.config.js
or--config
), and there's no longer any complex file traversal to resolve additional configs (except to traverse upwards to find the nearest config file.)Given this, I think it's now relatively easy to support other config loaders.
My solution would be to widen what flat config will load from - since it already
import()
's a JS config file you specify, it seems easy enough to loosen that to "load any specified module", and expect that module to resolve to a flat config array for processing. This allows for arbitrary loading semantics, but ESLint itself maintains the simple API of "load a flat config array from X".For example, Typescript (or whatever language) support could be plugged in by creating an npm package that looks for
eslint.config.ts
and does the necessary Typescript compilation/execution and resolves as itsexport default
a flat config array. ESLint would then justimport()
that package and process as normal the flat config array it gets handed.This also eliminates all the potential problems of
peerDependencies
and magic behaviour, at least from ESLint's point of view - the external package would be responsible for handling dependencies and any magic behaviour is opt-in, since you need to tell ESLint to load the package.The current logic of traversing for
eslint.config.js
and loading it can be encapsulated separately from the generic loading logic, and it would just be the default config module to be loaded if no custom one is specified.Another possible scenario could be the creation of some enforced shared config within an organization - publish the enforced shared config as an npm package and tell ESLint to load it with no possibility of locally overriding (because there's no local config file at all!)
I'm not sure yet how you'd specify this alternative module in a way you can commit to git (perhaps an
eslintConfigModule
property inpackage.json
?)I'm aware that you could emulate this today by creating
eslint.config.js
and putting some equivalent toexport default import('some-module')
, but that's very untidy if you then want to have a propereslint.config.xx
right next to it?I know this sort of change will likely require an RFC, and I'm willing to put one together if there's interest. If what I'm proposing isn't entirely clear, I'm also happy to put together a proof of concept to demonstrate.
Participation
Additional comments
No response
The text was updated successfully, but these errors were encountered: