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

What's up with the twoparserOptions?#6830

Jutanium started this conversation inTechnical Discussions
Discussion options

I'm new to ESLint. There appear to be twoparserOptions, one of which is often redundant.

If I settsconfigRootDir to a directory, ESLint knows where to find my project. Why should I setproject?

As a side note,project is an ambiguous name - what kind of project? What kind of value? (The possibletrue value makes this even more confusing.)

You must be logged in to vote

Replies: 4 comments 3 replies

Comment options

Some context:@Jutanium and I paired on Twitch to set up a new Astro+Solid+TypeScript project with linting. The typescript-eslint setup steps were mostly smooth untilTyped Linting (#6826,#6828). This was another issue we had that I asked Dan to start as a discussion here: the two config values weren't intuitive in our pair, and I think it'd be good to discuss if we can make it simpler and/or more obvious what things do.

For example, if the user specifiestsconfigRootDir, maybe we could defaultproject totrue?

You must be logged in to vote
3 replies
@bradzacher
Comment options

project is explained deeply inthe parser docs.

tsconfigRootDir is explainedin the parser docs.

Both of these options are described in the getting started guide and the above docs sections are linked as well (though the links are at different points in the guide)
Screenshot 2023-04-03 at 15 16 16

the two config values weren't intuitive in our pair

What would be the preferred way to document them aside from what's already in the guide?

@JoshuaKGoldberg
Comment options

@bradzacher I think the direction here is more: just reading a config, they're not very intuitive. So no matter how much we document them, it's not ideal. A goal beyond documenting them could be ideating a way to set up the options that makes more sense on the surface.

@bradzacher
Comment options

I guess my question would be "why does it matter if a config option is meaningless without the docs?" - config is an inherently complex thing - so it's kind of expected that either "you know what you're doing" or that you're referencing the docs.

As an example - TS project references are configured via thereferences config property. What does that mean? What does referencing a project mean? What will setting this do to by typecheck?

Not saying we can't improve at all! I'm just trying to gauge the scope and thinking.

Comment options

Why are there two?

Well until a month or so ago you had no option but to tell us the explicit paths to your tsconfig(s).
However if you setproject: './tsconfig.json' - what is that path relative to? Well as a user it's obvious "this path is relative to my.eslintrc.js file". However for our parser it's not that simple!

Unfortunately ESLint doesn't tell the parser the path to the config file for various reasons[1] so the only paths we explicitly know about are (1) the CWD and (2) the path to the file currently being linted. (2) is obviously useless as a marker to resolve a relative path against so we have to leverage (1) the CWD.

The problem you run into is that the CWD is dynamic! It's not uncommon tocd into a subfolder and run the lint. If a user does that then the path we resolve against has changed and now we can't find the project!
By settingtsconfigRootDir: __dirname it gives us that constant marker to resolve against so you can run your lint anywhere within your project without it breaking.

Why do we allow relative paths at all?

A few reasons reasons:

  1. For most lint runstsconfigRootDir doesn't actually matter - people mostly just run the lint from the project root - so the difference between relative or absolute doesn't matter.
    • Monorepo setups make it more common to doyarn lint from a subdir, but most of the time people still doyarn lint ./package/foo instead ofcd package/foo && yarn lint because the latter requiresscripts in the package directory.
  2. It's much nicer to define
    {project:['./one/tsconfig','./two/tsconfig',/* ... */],tsconfigRootDir:__dirname,}
    As opposed to like
    {project:['./one/tsconfig','./two/tsconfig',/* ... */].map(p=>path.resolve(__dirname,p)),// orproject:[`${__dirname}/one/tsconfig', '${__dirname}/two/tsconfig',/* ... */],}
  3. In some setups it can actually desirable to have relative paths resolved to the CWD. For example in a monorepo you couldcd package/foo && yarn lint and have./tsconfig.json resolve topackage/foo/tsconfig.json instead of the project root as a kind of automatic project resolution! (note - some people actually do rely on this behaviour!!!)

With the newproject: true config,tsconfigRootDir instead acts as a marker for where our algorithm should stop traversing when looking for a tsconfig that contains the linted file. It's a small perf optimisation but ultimately wouldn't change the result of the parser (i.e. it's notstrictly necessary).


Worth noting that you may not realise it but there's actually THREE parser options for type-aware linting - the third beingprojectFolderIgnoreList. This option was added not long after we added support for globs inparserOptions.project - it was added because some users noted that using globs would match./node_modules/package_that_ships_a_tsconfig_for_no_reason/tsconfig.json - which slowed down linting as our parser would create a uselessts.Program for that config.

I don't think there's many (if any) people that change this from its default of "ignorenode_modules" - but it's there as an option!


[1] reasons ESLint doesn't tell the parser about the config file path:

  • You can haven different multiple config files which "cascade" merge into a single ESLint config.
    • ESLint keeps cascading until it (a) reaches a config withroot: true or (b) reaches the disk root. So technically a config outside the "project dir" could influence the project's config!
    • In the past you could even have a global, "personal" config file in your home folder which would cascade into the project config. This has since been deprecated and removed in ESLint v8.
  • You can specify any config option via cli arguments - you could specify yourentire config via cli arguments! CLI arguments explicitly override any config specified in any config file.

The cascading and overriding means that ultimately ESLint does not keep track of where the final value for each property came from - it just knows the final value. So knowing one of the possible config paths is technically meaningless in the world of ESLint!

You must be logged in to vote
0 replies
Comment options

Some fun facts on the history of the names - you can trace the namesproject andtsconfigRootDir all the way back to theiroriginal implementation almost 5 years ago!

parserOptions.project

project might sound ambiguous until you consider it in the context of TypeScript. TypeScript's CLI accepts a--project argument to specify the path to atsconfig.json to build. TypeScript also allows you to specify "project references" which are similarly paths totsconfig.jsons.

At some point we probably should have renamed it toparserOptions.projects given most cases will pass an array of paths or globs, but TBH it never seemed worth the user-land churn/overhead of forcing people to add a single character to their config "just because it's technically correct".

parserOptions.tsconfigRootDir

tsconfigRootDir is kinda poorly named and always has been given thatproject was named at the same time - it probably should have beenprojectRootDir. TBH I've never actually thought about renaming it - the disjoint naming never even occurred to me heh.

parserOptions.projectFolderIgnoreList

Probably should have been calledprojectGlobIgnoreList to better describe when specifically it is applied, but it's probably "good enough"

You must be logged in to vote
0 replies
Comment options

In regards to the best path forwards...

For example, if the user specifies tsconfigRootDir, maybe we could default project to true?

Personally I don't think we should make such a change - I think people shouldalways provideproject to explicitly opt-in to type-aware linting. If we start implicitly setting it then that's a really large breaking change that might impact users more than we think - for example if a shared config setstsconfigRootDir for whatever reason then that implicitly opts the lint run in and hugely impacts the lint run duration.

We do haveproject: null to allow people to opt-out of type-aware linting, but it would be kind of sucky if you added shared config and it just implicitly opted you in by accident!


If I had to specify a "north star" - I would probably want to introduce a state like this to group the config:

typePath=RelativePath|AbsolutePath|GlobPath;interfaceExplicitProjectConfig{/** Paths to the tsconfigs to explicitly load for type information */tsconfigPaths:Path[];/** Paths to ignore when resolving globs from `tsconfigPaths` */globIgnoreList?:Path[];/** Absolute path to the project root to use when resolving relative paths */relativeRootDir?:AbsolutePath;}interfaceAutomaticProjectConfig{/** Explicitly opt-in to the automatic resolution and also a disjoin union field??? */automatic:true;/** Absolute path to the project root to stop traversing at when looking for tsconfigs */traversalRootDir:AbsolutePath;}interfaceParserOptions{/**   * `null` allows people to explicitly opt folders out of type-aware linting   * for specific paths. It allows users to write configs as "type-aware-first" and   * have non-type-aware linting being the edge case applied via `overrides` by   * the config `plugin:@typescript-eslint/disable-type-checked`   */project:ExplicitProjectConfig|AutomaticProjectConfig|null;}
You must be logged in to vote
0 replies
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Labels
None yet
3 participants
@Jutanium@JoshuaKGoldberg@bradzacher

[8]ページ先頭

©2009-2025 Movatter.jp