Expand auto-import to all package.json dependencies by andrewbranch · Pull Request #38923 · microsoft/TypeScript (original) (raw)

This PR creates an auxiliary program in the language service layer that contains node_modules packages that are specified as a direct dependency (including devDependencies peerDependencies) in a package.json file visible to the project’s root directory and not already present in the main program. This program is then supplied to the auto-imports machinery as a provider of additional modules that can be used for auto-import. Effectively, this means that packages that ship their own types should be available for auto-import immediately after npm installing them, lifting a long-despised limitation of “you have to write out the import manually once in your project before auto-imports will work, unless it’s in @types, because @types is special.”

Performance

I compared a few operations against master on the output of @angular/cli (with routing). (I chose this as a test because it’s a realistic scenario where a user’s package.json will contain more dependencies with self-shipped types than are actually used in the program. For example, @angular/forms is a listed dependency but isn’t used in the boilerplate.) Measurements are an average of three trials run in VS Code 1.46.0-insider (b1ef2bf) with extensions disabled.

master PR Diff
Startup time (ms) 2729 2636 -92 ms (-3%)
Type “P”*
updateGraph 18 15 -4 ms (-20%)
completionInfo 102 115 +13 ms (+13%)
Backspace, Type “P”**
completionInfo 44 38 -6 ms (-13%)
Comment out import***
getApplicableRefactors 44 62 +18 ms (+42%)

* This triggers completions, including import suggestions for PatternValidator from @angular/forms in the PR trials, a suggestion that is not included in the master trials.

** This triggers completions again without disrupting the auto-import cache populated in the previous action.

*** This changes the structure of the primary program, which triggers an update of the auto-import provider program. The time it takes to do so is included in the subsequent getApplicableRefactors measurement.

Observations:

Limitations

tsconfig.json  
project/  
  node_modules/  
  package.json  
  index.ts  

the project/package.json file won’t be found.

Memory considerations

The auxiliary program is configured to be as light as possible, but in a project references editing scenario, it’s possible to have many projects open at once. Each project has its own language service, so each open project will typically have one of these auxiliary programs. Some possibilities for mitigating high memory usage in these scenarios: (updated: decided to exclude devDependencies for UX reasons)

However, at this point I’m not convinced that any of these mitigations are necessary. The size of these programs is usually in the ballpark of a browser tab (around 50 MB from one early test). But we have avenues to explore if needed.

Fixes #37812
Fixes #36042


¹ “file that belongs to the project” here means “file whose default project is the project in question,” in contrast to “file that is contained by the project”