eslint / eslint/rewrite

Change Request: Support "cross-file" linting

Open
#352 3 comments 8 reactions 1 assignee Claimed by @JoshuaKGoldberg View on GitHub
enhancement
Dominant language
JavaScript
Stars
348
Forks
51
Avg merge
2d 10h
Merged PRs (30d)
11

Description

### Which packages would you like to change?

- [ ] `@eslint/compat`
- [ ] `@eslint/config-array`
- [ ] `@eslint/config-helpers`
- [x] `@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:

* Cross file types like [typescript-eslint](https://typescript-eslint.io)'s [typed linting](https://typescript-eslint.io/getting-started/typed-linting).
* Import analysis in plugins like [`eslint-plugin-import`](https://github.com/import-js/eslint-plugin-import) and [`eslint-plugin-import-x`](https://www.npmjs.com/package/eslint-plugin-import-x)

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`](https://typescript-eslint.io/packages/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

- [x] 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:

* https://github.com/eslint/eslint/discussions/16557: past discussion opening up this rewrite repo & touching on points such as making ESLint type-aware and/or project-aware
* https://github.com/eslint/eslint/discussions/16819: further discussion on these topics
* https://github.com/eslint/rfcs/pull/102: has a lot of links & text explaining needs around session information
* https://github.com/typescript-eslint/typescript-eslint/issues/11677: further explains the typescript-eslint perspective & list of needs blocked on stateful services

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.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.