Skip to content

Change Request: Support "cross-file" linting #352

Description

@JoshuaKGoldberg

Which packages would you like to change?

  • @eslint/compat
  • @eslint/config-array
  • @eslint/config-helpers
  • @eslint/core
  • @eslint/mcp
  • @eslint/migrate-config
  • @eslint/object-schema
  • @eslint/plugin-kit

What problem do you want to solve?

"Cross-file" or "multi-file" linting is an increasingly common need in many lint plugins. Two common user needs are from:

ESLint today does not have any native concepts of cross-file dependencies, stateful parsing, or type information. It does not provide APIs for them. As a result, userland plugins have needed to put cross-file parsing into parsers such as @typescript-eslint/parser. This is the only way to get it to work in ESLint right now, but is problematic:

  • ESLint's parsers are intended to be isolated and stateless. Using them for contextually aware and/or stateful logic breaks that paradigm.
    • ESLint's --cache is fundamentally unreliable when users opt into any form of cross-file linting, as cache invalidation does not account for cross-file information.
  • Parsers don't receive information like a full list of files, what form of session ESLint is being run in, etc. - which would be useful for optimizing cross-file things.
    • (From my anecdotal recollection) ESLint's --concurrency often ends up being slower on large codebases using typed linting, as each thread/worker instantiates TypeScript type services that end up significantly overlapping in functionality

What do you think is the correct solution?

I personally have been advocating for a two-step approach:

  1. Since users are using plugins for cross-file linting now (and have been since at least typescript-eslint was introduced in 2019), adding in rudimentary stateful information to parsers.
  2. In the big ESLint rewrite, add a more native concept of a stateful entity. Something that has setup and teardown phases, knows the full list of files, and can instantiate services such as a module dependency graph or a type-checker.

The feedback we've gotten from the TSC has been that only the latter is desirable.

Participation

  • I am willing to submit a pull request for this change.

Additional comments

I asked about this internally and was suggested by @nzakas to post an issue. This is that issue! 🙂 Is there other information that would be useful for me to file that isn't in the major past discussions? For quick reference:

Terminology aside: I've personally been calling this "cross-file" linting to convey that it uses an understanding of code built up across-files. "Multi-file" makes me think the linter is reporting on multiple files at once, or that lint rules are targeted to multiple files at a time. I'm not intending to suggest completely redesigning the core concept of "each rule looks at a file at a time". Just that the information they use on each file is more informed.

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type
No fields configured for issues without a type.

Projects

Status
Evaluating

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions