Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[RFC] Building a CLI for typescript-eslint #4183

Closed
Assignees
bradzacher
Labels
accepting prsGo ahead, send a pull request that resolves this issue
@bradzacher

Description

@bradzacher

I want to explore is building a CLI for typescript-eslint.

A big issue we run into with our tooling is that we are "at the mercy" of ESLint's CLI. ESLint controls the process - how files are selected, when files are selected, in what order they are linted.

This is a problem because we can't do efficient memory management, nor can we properly prioritise work. We don't have any control or visibility into what files are being linted so we can't "dispose" of a program when it's done: we don't know if or when all the files that belong to the project will be linted (for example it's common that a user might lint a subset of a project). This forces us to keep every single project in memory for the duration of the lint run (which leads to OOMs on any non-trivial codebase).

Additionally due to the fact that ESLint has one API for all use cases we don't know which "state" ESLint is in. ESLint just exposes theESLint API which is used in the "single-run" CLI usecase as well as the persistent IDE usecase.

This means that we're stuck building for the worst case scenario like:

  1. using inefficient APIs when we could use better ones
  2. keeping programs in memory forever just in case we need them again (OOM when many (>10) project configs passed to the parser #1192)

For (1) we've attempted to work around by attempting to detect the CLI usecase (#3512) - which definitely helps! But it has a few unfortunate shortcomings.
For (2) we could probably build on top of the (1) solution to free up programs automatically. But that kind of feels like hacks on hacks on hacks - and we're building a super complicated system which is brittle and pushes us further into a world where we can't get new contributors due to the complexity of our system.

It's worth noting that even for the CLI usecase (which we tend to think of as "one and done") - ESLint can lint a file up to 11 times when it is calculating fixes for a file (1 initial pass and 10 fix passes). Which does cause some unique problems with optimisations we might try to apply.


So I want to explore a new direction - a new CLI which allows us to "work around" these issues from the top down instead of the middle.

My proposal would be a simple CLI along the lines of this:
$ tseslint --helpUsage: tseslint [options] file.js [file.js] [dir]Basic configuration:  -c, --config path::String       Use this configuration, overriding .eslintrc.* config options if presentFixing problems:  --fix                           Automatically fix problems  --fix-type Array                Specify the types of fixes to apply (problem, suggestion, layout)Ignoring files:  --ignore-path path::String      Specify path of ignore file  --ignore-pattern [String]       Pattern of files to ignore (in addition to those in .eslintignore)Handling warnings:  --quiet                         Report errors only - default: false  --max-warnings Int              Number of warnings to trigger nonzero exit code - default: -1Output:  -o, --output-file path::String  Specify file to write report to  -f, --format String             Use a specific output format - default: stylish  --color, --no-color             Force enabling/disabling of colorInline configuration comments:  --no-inline-config              Prevent comments from changing config or rules  --report-unused-disable-directives  Adds reported errors for unused eslint-disable directivesMiscellaneous:  --env-info                      Output execution environment information - default: false  --no-error-on-unmatched-pattern  Prevent errors when pattern is unmatched  --debug                         Output debugging information  -h, --help                      Show help  -v, --version                   Output the version number

A keen eye would notice this proposed CLI is just a subset of the ESLint CLI. This is completely intentional.

At a high level - this would be the proposed workflow for the CLI:

  1. Use ESLint'sFileEnumerator to expand the passed paths/blobs to the list of actual files to lint
  2. For each file resolve the config and bucket them into two buckets: files with type information and files without type information.
  3. For files without type information - we can just run ESLint over them as normal.
  4. For files with type information - we want to group them again. This time we want to group them by which TSConfig they belong to.
  5. Once we have the tsconfig buckets - we can then execute each project in turn:
    1. manually create the TS Program instance for the tsconfig.
    2. lint all files in the bucket.
    3. if there are fixes andn < 10 then apply fixes,n + 1, go to (5.iii).
    4. dispose of the TS Program instance (solvingPurge programs once they are done #1718)

By controlling the order and grouping of files - we can know exactly when we can free up the memory - allowing us to prevent OOMs due to having all programs in memory at once.

This also unlocks other possible optimisations for us like parallelisation!
We know that each project is "isolated" from one another - so we can run each project (eg step 5) in a separate thread. We could also bucket the non-type information files (step 3) in their own separate thread. This should mean that instead of havingO(nm) performance wheren is the number of projects andm is the worst-case lint time for a project, instead we would haveO(m) performance.

If we wanted to - this would also let us rip out the "CLI detection" from the underlying CLI and thus simplify it again to reduce complexities. We could also choose to keep this so we can maintain some level of improved performance for people who continue to use the standardeslint binary.

cc @typescript-eslint/core-team

Metadata

Metadata

Assignees

Labels

accepting prsGo ahead, send a pull request that resolves this issue

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions


    [8]ページ先頭

    ©2009-2025 Movatter.jp