Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(typescript-estree): add EXPERIMENTAL_useProjectService option to use TypeScript project service #6754



Copy link

@JoshuaKGoldberg JoshuaKGoldberg commented Mar 24, 2023

PR Checklist


Creates an experimental ready-to-try-only-if-you-dare prototype implementation of #6575: using TypeScript's "project service" / server to create programs instead of our existing manual project creation. Doing so brings the "create program(s) for source files" part of typed linting towards how editors behave:

// .eslintrc.js
module.exports = {
  extends: [
  plugins: ['@typescript-eslint'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    EXPERIMENTAL_useProjectService: true,
  root: true,

Technical Details

In essence, this PR:

  • Adds an EXPERIMENTAL_useProjectService option to typescript-estree
    • Setting process.env.TYPESCRIPT_ESLINT_EXPERIMENTAL_TSSERVER can also enable the option
  • Adjusts createParserSettings to call to a new createProjectService function lazily when the experimental option is enabled (thereby setting parseSettings.EXPERIMENTAL_projectService)
  • Adjusts getProgramAndAST to use that project service if it exists, with a new useProgramFromProjectService
  • Massages internal tests to always use absolute (or failing that, relative to project root) paths for files if possible, as the project service expects that (is this phrasing accurate?)
  • Skips tests that aren't applicable anymore when the project service is in use

See for a reproduction case showing this working.

Performance Comparison

Complete Project Linting

for branchName in v6 create-project-service; do
    git checkout $branchName
    hyperfine "yarn lint --skip-nx-cache" > $branchName.txt

hyperfine "TYPESCRIPT_ESLINT_EXPERIMENTAL_TSSERVER=true yarn lint --skip-nx-cache" > enabled.txt
v6 #6754 baseline #6754 enabled #6754 Δ
62.976 s ± 0.479 s 65.383 s ± 0.226 s 31.169 s ± 0.401 s -52% 🟢

Incremental Project Linting

for glob in "eslint-plugin/src/rules/*.ts" "typescript-estree/src/create-program/*.ts" "website/**/*.tsx"; do
    for setting in false true; do
        hyperfine "TYPESCRIPT_ESLINT_EXPERIMENTAL_TSSERVER=$setting npx eslint --config .eslintrc.js packages/$glob"
Glob Baseline Enabled Δ
eslint-plugin/src/rules/*.ts 8.552 s ± 0.100 s 9.525 s ± 0.084 s +11% ❌
packages/typescript-estree/src/create-program/*.ts 7.162 s ± 0.079 s 2.153 s ± 0.007 s -70% 🟢
packages/website/**/*.tsx 9.955 s ± 0.080 s 3.714 s ± 0.029 s -63% 🟢

Copy link

Thanks for the PR, @JoshuaKGoldberg!

typescript-eslint is a 100% community driven project, and we are incredibly grateful that you are contributing to that community.

The core maintainers work on this in their personal time, so please understand that it may not be possible for them to review your work immediately.

Thanks again!

🙏 Please, if you or your company is finding typescript-eslint valuable, help us sustain the project by sponsoring it transparently on

Copy link

netlify bot commented Mar 24, 2023

Deploy Preview for typescript-eslint ready!

Name Link
🔨 Latest commit 7e74202
🔍 Latest deploy log
😎 Deploy Preview
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link

nx-cloud bot commented Mar 24, 2023

☁️ Nx Cloud Report

CI is running/has finished running commands for commit 7e74202. As they complete they will appear below. Click to see the status, the terminal output, and the build insights.

📂 See all runs for this branch

✅ Successfully ran 35 targets

Sent with 💌 from NxCloud.

@bradzacher bradzacher added the DO NOT MERGE PRs which should not be merged yet label Apr 10, 2023
@bradzacher bradzacher added the enhancement New feature or request label Apr 17, 2023
@JoshuaKGoldberg JoshuaKGoldberg changed the title WIP: createProjectService feat(typescript-estree): add EXPERIMENTAL_useProjectService option to use TypeScript project service Apr 18, 2023
Copy link

codecov bot commented Apr 18, 2023

Codecov Report

Merging #6754 (7e74202) into main (606a52c) will decrease coverage by 0.11%.
The diff coverage is 62.50%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6754      +/-   ##
- Coverage   87.57%   87.47%   -0.11%     
  Files         377      379       +2     
  Lines       13201    13230      +29     
  Branches     3901     3906       +5     
+ Hits        11561    11573      +12     
- Misses       1261     1279      +18     
+ Partials      379      378       -1     
Flag Coverage Δ
unittest 87.47% <62.50%> (-0.11%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...escript-estree/src/useProgramFromProjectService.ts 16.66% <16.66%> (ø)
...t-estree/src/create-program/useProvidedPrograms.ts 84.84% <66.66%> (ø) 81.81% <71.42%> (+0.18%) ⬆️
...-estree/src/create-program/createProjectService.ts 80.00% <80.00%> (ø)
packages/eslint-plugin-tslint/src/rules/config.ts 97.77% <100.00%> (+0.05%) ⬆️
packages/typescript-estree/src/clear-caches.ts 100.00% <100.00%> (ø)
...-estree/src/create-program/createProjectProgram.ts 97.56% <100.00%> (-0.12%) ⬇️
.../src/create-program/getWatchProgramsForProjects.ts 82.12% <100.00%> (-2.71%) ⬇️
...ges/typescript-estree/src/create-program/shared.ts 77.50% <100.00%> (ø)

... and 1 file with indirect coverage changes

Copy link
Member Author

Re-requesting review from @bradzacher because I applied a couple of small touchups & answered a question. But otherwise I feel comfortable merging this after we get v6 out the door (just to be safe & not conflict with the v6 release). Woop woop! 🚀

bradzacher previously approved these changes Jun 15, 2023
Copy link

@bradzacher bradzacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JoshuaKGoldberg JoshuaKGoldberg removed this from the 6.0.0 milestone Jun 15, 2023
@bradzacher bradzacher added the 1 approval PR that a maintainer has LGTM'd - any maintainer can merge this when ready label Jun 24, 2023
@JoshuaKGoldberg JoshuaKGoldberg deleted the branch typescript-eslint:main July 10, 2023 17:52
Copy link

may i ask what happened with this PR - is it merged now, or had it to be abandoned?

Copy link
Member Author

JoshuaKGoldberg commented Jul 10, 2023

This was unintentionally auto-closed when we merged the v6 branch 🙃 it'll be recreated reopened.

@JoshuaKGoldberg JoshuaKGoldberg changed the base branch from v6 to main July 10, 2023 21:11
@JoshuaKGoldberg JoshuaKGoldberg dismissed bradzacher’s stale review July 10, 2023 21:11

The base branch was changed.

Copy link
Member Author

JoshuaKGoldberg commented Jul 10, 2023

Now that v6 is merged into main, I'm planning on merging this as well some time in the next 1-2 weeks. Depending on whether there are any major issues reported with 6.0.0:

  • If there are, we'll fix them in next week's release (July 17th) and I'll plan to merge this this in time for the following week (July 24th)
  • If there aren't, I'll plan to merge this in time for next week's release (July 17th)

Note that we're keeping the EXPERIMENTAL prefix on the option name for now. It's very new and scary. We're also going to want to think a bit more deeply on how the parserOptions type shape should look.

FYI @jakebailey - we're moving quickly this month! ⚡

Copy link
Member Author has a small enough number of bugs -and no major architectural issues- reported that I feel comfortable merging this in. Hooray! 🚀

(knocking on wood, fingers crossed 🤞)

@JoshuaKGoldberg JoshuaKGoldberg merged commit 6d3d162 into typescript-eslint:main Jul 16, 2023
48 of 50 checks passed
Copy link
Member Author

This change terrifies me.

Tom Hanks in a captain's outfit saying 'May God have mercy on my soul'

Comment on lines +196 to +226
name: Run Unit Tests with Experimental TSServer
needs: [build]
runs-on: ubuntu-latest
- name: Checkout
uses: actions/checkout@v3
fetch-depth: 2
- name: Install
uses: ./.github/actions/prepare-install
node-version: 18
- name: Build
uses: ./.github/actions/prepare-build
- name: Run unit tests for ${{ matrix.package }}
run: npx nx test ${{ matrix.package }} --coverage=false
CI: true
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was a great thing to add!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
1 approval PR that a maintainer has LGTM'd - any maintainer can merge this when ready enhancement New feature or request
None yet

Successfully merging this pull request may close these issues.

Enhancement: Try using tsserverlibrary's ProjectService to handle type-aware mode
6 participants