- Notifications
You must be signed in to change notification settings - Fork 13.1k
Description
Suggestion
This is roughly a copy of typescript-eslint/typescript-eslint#3798, which I transferred here as suggested by the maintainers of the @typescript-eslint project as there was little they could do on their side to improve this.
🔍 Search Terms
custom module resolution
module resolution invalidation
user provided resolution
✅ Viability Checklist
My suggestion meets these guidelines:
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This feature would agree with the rest of TypeScript's Design Goals.
⭐ Suggestion
Any project that provides a custom module resolver suffers from this, I tried in different projects and got the same results.
The actual implementation of the resolveModuleNames
can be as simple as (moduleNames) => moduleNames.map(n => undefined)
and it is still way slower even with caching.
I have a custom module resolver with cache, and running @typescript-eslint
with it presents a 3x slowdown compared to using TS's native resolution. I've debugged it a bit (with my limited knowledge about the TS compiler) and found that the root cause may be that the TS compiler is invalidating all the resolutions whenever a new file is checked because the Program is re-synchronized and re-created no matter what, as a custom module resolution was provided (comment says: "All resolutions are invalid if user provided resolutions").
Even though my custom resolveModuleName
has cache and returns the cached paths immediately after the first seconds of running, the overhead of invalidating all the resolutions and re-creating the Program several times is still way too great and causes this significant slowdown.
Example run:
Original TS
synchronizeProgram called 1047 times
createNewProgram called 1 times
resolveModuleNames called 1744 times
Custom module resolution
synchronizeProgram called 1047 times
createNewProgram called 1047 times
resolveModuleNames called 1,766,289 times
Custom module resolution with TS compiler patched, forcing the variable userProvidedResolution=false
synchronizeProgram called 1047 times
createNewProgram called 1 times
resolveModuleNames called 1687 times
📃 Motivating Example
This would improve the speeds of custom module resolvers.
💻 Use Cases
This would improve the speeds of custom module resolvers.