Skip to content

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

@JoshuaKGoldberg

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

Projects

Status

Evaluating

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions