Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ded5d21

Browse files
JoshuaKGoldbergJosh-Cenaarmano2
authored
docs: blog post on parserOptions.project = true (typescript-eslint#7368)
* WIP: blog post on parserOptions.project = true * Filled out the rest * Rename heading to 'Investigating' * Apply suggestions from code review Co-authored-by: Joshua Chen <[email protected]> * Apply suggestions from code review Co-authored-by: Joshua Chen <[email protected]> * Update date for this week * Update packages/website/blog/2023-09-12-parser-options-project-true.md Co-authored-by: Armano <[email protected]> * Publish date: 18th * formatting with the space for email --------- Co-authored-by: Joshua Chen <[email protected]> Co-authored-by: Armano <[email protected]>
1 parent 9cb9211 commit ded5d21

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
---
2+
authors:
3+
- image_url: https://www.joshuakgoldberg.com/img/josh.jpg
4+
name: Josh Goldberg
5+
title: typescript-eslint Maintainer
6+
url: https://github.com/JoshuaKGoldberg
7+
description: Simplifying how many projects resolve their
8+
slug: parser-options-project-true
9+
tags: [parser, parser options, project, tsconfig]
10+
title: Relative TSConfig Projects with `parserOptions.project = true`
11+
---
12+
13+
["Typed linting"](/linting/typed-linting), or enabling ESLint rules to tap into the power of the TypeScript type checker, is one of the best parts of typescript-eslint.
14+
But enabling the type checker in repositories with multiple `tsconfig.json` files can be annoying to set up.
15+
Even worse, specifying the wrong include paths could result in incorrect rule reports and/or unexpectedly slow lint times.
16+
17+
Improving the setup experience for typed lint rules has been a long-standing goal for typescript-eslint.
18+
One long-standing feature request for that experience has been to support automatically detecting TSConfigs for developers.
19+
We're happy to say that we now support that by setting `parserOptions.project` equal to `true` in ESLint configurations.
20+
21+
This post will explain what life was like before, what's changed, and what's coming next. 🎉
22+
23+
<!--truncate-->
24+
25+
## The Problem With Projects
26+
27+
The `@typescript-eslint/parser` package is what enables ESLint to parse TypeScript source files.
28+
It converts raw TypeScript code into an ["AST" format](./2022-12-05-asts-and-typescript-eslint.md).
29+
When [`parserOptions.project`](/packages/parser#project) is specified, it additionally sets up TypeScript programs that can be used by [typed rules](/developers/custom-rules#typed-rules).
30+
31+
Many projects today start with ESLint configs that look something like:
32+
33+
```js
34+
module.exports = {
35+
// ...
36+
parserOptions: {
37+
project: './tsconfig.json',
38+
tsconfigRootDir: __dirname,
39+
},
40+
// ...
41+
};
42+
```
43+
44+
In larger repos, `parserOptions.project` often ends up being one of the three traditionally allowed forms:
45+
46+
- Path, such as `project: './tsconfig.json'`
47+
- Glob pattern, such as `project: './packages/**/tsconfig.json'`
48+
- Array of paths and/or glob patterns, such as `project: ['./packages/**/tsconfig.json', './separate-package/tsconfig.json']`
49+
50+
Explicitly indicating which TSConfig files are used for typed linting can be useful.
51+
Developers like being given explicit control over their tooling.
52+
However, we've seen a few issues arise from this approach:
53+
54+
- Particularly large repos can end up with so many TSConfig globs, they become confusing to developers or even cause [performance issues from overly permissive globs](/linting/troubleshooting/performance-troubleshooting#wide-includes-in-your-eslint-options)
55+
- Needing to change a template ESLint config every time it's used for a different repository structure is a pain
56+
- Using a TSConfig that's different from what your editor uses can result in different lint reports between the editor and the command-line
57+
58+
Although developers may sometimes need exact control over their `parserOptions.project`, most of the time we just want to use the _nearest `tsconfig.json` to each linted file_, which is the TSConfig used by the editor by default.
59+
60+
In other words, many developers want our [issue #101: Feature request: support looking up tsconfig.json relative to linted file](https://github.com/typescript-eslint/typescript-eslint/issues/101).
61+
62+
## Introducing `true`
63+
64+
As of typescript-eslint 5.52.0, we now support providing `true` for `parserOptions.project`:
65+
66+
```js
67+
module.exports = {
68+
// ...
69+
parserOptions: {
70+
project: true,
71+
tsconfigRootDir: __dirname,
72+
},
73+
// ...
74+
};
75+
```
76+
77+
Doing so indicates that each source file being linted should use type information based on the nearest `tsconfig.json` in its directory.
78+
For each file, `@typescript-eslint/parser` will check that file's directory, then the parent directory, and so on - until a `tsconfig.json` file is found.
79+
80+
:::tip
81+
We recommend setting the [`tsconfigRootDir`](/packages/parser#tsconfigrootdir) ESLint config to the project's root directory (most commonly, `__dirname`).
82+
That way, if you accidentally delete or rename the root `tsconfig.json` file, `@typescript-eslint/parser` won't search parent directories for higher `tsconfig.json` files.
83+
:::
84+
85+
### Why Try `true`
86+
87+
If your project uses typed linting and manually specifies `tsconfig.json` files, we'd highly recommend trying out `parserOptions.project: true`.
88+
We've seen it reduce lines of code in ESLint configurations in many early adopters.
89+
Sometimes, it even reduces time spent on typed linting by helping projects use a simpler set of TSConfigs. 🚀
90+
91+
In the long term, we're hoping to further improve the configuration and performance for typed linting (see _[Project Services](#project-services)_ below).
92+
Simplifying your configuration now will make it easier to onboard to our new options when they're available.
93+
94+
### How It Works
95+
96+
When `@typescript-eslint/parser` is configured to generate type information, it attaches a backing TypeScript "Program" for each file it parses.
97+
Those Programs provide type checking APIs used by lint rules.
98+
Each TSConfig file on disk is generally used to create exactly one Program, and files included by the same TSConfig file will reuse the same Program.
99+
100+
Depending on how the ESLint config's `parserOptions.project` was specified, determining _which_ TSConfig file to use for each file can be different:
101+
102+
- For a single path (e.g. `"tsconfig.json"`), only one Program will be created, and all linted files will reuse it.
103+
- For globs and/or arrays (e.g. `"./packages/*/tsconfig.json"`), each linted file will use the Program created by the _first_ matched TSConfig file.
104+
105+
For `true`, each linted file will first try the `tsconfig.json` in its directory, then its parent directory, and so on until one is found on disk or the directory root (`parserOptions.tsconfigRootDir`) is reached.
106+
107+
:::note
108+
`@typescript-eslint/parser` caches those directory `tsconfig.json` file lookups for a duration corresponding to [`parserOptions.cacheLifetime`](/packages/parser#cachelifetime).
109+
No potential TSConfig path should be checked more than once in a lint run.
110+
:::
111+
112+
See [feat(typescript-estree): allow specifying project: true](https://github.com/typescript-eslint/typescript-eslint/pull/6084) for the backing code changes.
113+
114+
## What's Next
115+
116+
### Investigating Custom TSConfig Names
117+
118+
Some projects use TSConfig files with names other than `tsconfig.json`: most commonly, `tsconfig.eslint.json`.
119+
`parserOptions.project: true` does not support specifying different name(s) to search for.
120+
We have two followup issues filed to investigate fleshing out that support:
121+
122+
- [Enhancement: Allow altering the file names that project: true searches for](https://github.com/typescript-eslint/typescript-eslint/issues/7383)
123+
- [Enhancement: Allow parserOptions.project to be (true | string)[]?](https://github.com/typescript-eslint/typescript-eslint/issues/7384)
124+
125+
If either of those two issues would benefit you, please 👍 react to them.
126+
And if your project has a use case not yet mentioned in their comments, please post that use case.
127+
We want to know what's important for users!
128+
129+
### Project Services
130+
131+
The downside of having users specify `parserOptions.project` at all is that `@typescript-eslint/parser` needs manual logic to create TypeScript Programs and associate them with linted files.
132+
Manual Program creation logic comes with a few issues:
133+
134+
- Complex project setups can be difficult to get right.
135+
- For example, [typescript-eslint does not yet support Project References](https://github.com/typescript-eslint/typescript-eslint/issues/2094).
136+
- The TypeScript compiler options used in the user's editor might differ from the compiler options in the TSConfigs they specified on disk.
137+
- Files not included in created Programs can't be linted with type information, even though editors still typically surface type information when editing those files.
138+
- Most commonly, `.eslintrc.(c)js` files can be tricky to lint, resulting in the dreaded [_TSConfig does not include this file_ error](/linting/troubleshooting#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-file).
139+
140+
We're working on an option to instead call the same TypeScript "Project Service" APIs that editors such as VS Code use to create Programs for us instead.
141+
Project Services will automatically detect the TSConfig for each file (like `project: true`), and will also allow type information to be computed for JavaScript files without the `allowJs` compiler option (unlike `project: true`).
142+
143+
We hope this option will eventually become the standard way to enable typed linting.
144+
However, because it's so new and untested, we're keeping it under the `EXPERIMENTAL_` prefix for at least all of the `6.X` versions.
145+
146+
See [Packages > Parser > `EXPERIMENTAL_useProjectService`](/packages/parser#EXPERIMENTAL_useProjectService) for more information.
147+
148+
## Supporting typescript-eslint
149+
150+
If you enjoyed this blog post and/or use typescript-eslint, please consider [supporting us on Open Collective](https://opencollective.com/typescript-eslint).
151+
We're a small volunteer team and could use your support to make the ESLint experience on TypeScript great.
152+
Thanks! 💖

0 commit comments

Comments
 (0)