-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Reduce file lookups in node_modules module resolution #16568
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
Conversation
src/compiler/moduleNameResolver.ts
Outdated
TypeScript, /** '.ts', '.tsx', or '.d.ts' */ | ||
JavaScript, /** '.js' or '.jsx' */ | ||
DtsOnly /** Only '.d.ts' */ | ||
const enum Extensions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Name this enum as Extensions
seems misleading. I was expecting file extensions....though I have no good idea for alternatives 😞
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about ExtensionsToTry
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe ExtensionsOfKind
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On reflection, calling this ExtensionsToTry
is better. Renaming instances to extensionsToTry
would help clarify their use as well.
"Directory '/node_modules/@types' does not exist, skipping all lookups in it.", | ||
"Loading module 'foo' from 'node_modules' folder, target file type 'JavaScript'.", | ||
"File '/node_modules/foo.js' does not exist.", | ||
"File '/node_modules/foo.jsx' does not exist.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removal of this path lookup seems incorrect.
Refer https://nodejs.org/api/modules.html
LOAD_NODE_MODULES(X, START)
- let DIRS=NODE_MODULES_PATHS(START)
- for each DIR in DIRS:
a. LOAD_AS_FILE(DIR/X)
b. LOAD_AS_DIRECTORY(DIR/X)
It looks like node does look for node_modules/foo.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, but as far as I know, every package manager fills node_modules
with only directories, and searching for a file there is costing us a lot of fileExists
calls (as you can see from the diff).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pinging @DanielRosenwasser , as he may have some more insight into whether we want to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its unlikely we will break anyone with this change, but I'd like to see what kind of performance gain we get out of removing these extraneous lookups.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ran the perf tests and there is basically no change between this branch and master
-- a 0.5% improvement in parse time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a technical perspective, looks good modulo the naming of Extensions
and some minor nits.
Still not sure we want to go ahead and make this change to explicitly drop supporting node-modules/foo.ts
as a target of module resolution.
Can you test the effect of the change on RWC?
src/compiler/moduleNameResolver.ts
Outdated
@@ -920,22 +939,26 @@ namespace ts { | |||
return combinePaths(directory, "package.json"); | |||
} | |||
|
|||
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined { | |||
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName)); | |||
// Inside of node_modules we should be looking for '.d.ts' files before '.ts' files. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps:
Inside node_modules
, we should look for '.d.ts' ...
src/compiler/moduleNameResolver.ts
Outdated
} | ||
|
||
function loadModuleFromNodeModules(extensions: Extensions, moduleName: string, directory: string, failedLookupLocations: Push<string>, state: ModuleResolutionState, cache: NonRelativeModuleNameResolutionCache): SearchResult<Resolved> { | ||
return loadModuleFromNodeModulesWorker(extensions, moduleName, directory, failedLookupLocations, state, /*typesOnly*/ false, cache); | ||
// In node_modules, we will look for a '.d.ts' file first. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering what the next line says, not sure what this comment adds.
src/compiler/moduleNameResolver.ts
Outdated
function loadModuleFromNodeModulesFolder(extensions: Extensions, moduleName: string, nodeModulesFolder: string, nodeModulesFolderExists: boolean, failedLookupLocations: Push<string>, state: ModuleResolutionState): Resolved | undefined { | ||
const candidate = normalizePath(combinePaths(nodeModulesFolder, moduleName)); | ||
// Inside of node_modules we should be looking for '.d.ts' files before '.ts' files. | ||
type NodeModulesExtensions = Extensions.TypeScriptDtsFirst | Extensions.JavaScript | Extensions.DtsOnly; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would move this type declaration next to the enum declaration for Extensions
.
src/compiler/moduleNameResolver.ts
Outdated
TypeScript, /** '.ts', '.tsx', or '.d.ts' */ | ||
JavaScript, /** '.js' or '.jsx' */ | ||
DtsOnly /** Only '.d.ts' */ | ||
const enum Extensions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On reflection, calling this ExtensionsToTry
is better. Renaming instances to extensionsToTry
would help clarify their use as well.
src/compiler/moduleNameResolver.ts
Outdated
@@ -32,10 +32,27 @@ namespace ts { | |||
* Kinds of file that we are currently looking for. | |||
* Typically there is one pass with Extensions.TypeScript, then a second pass with Extensions.JavaScript. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a comment explaining the significance of the enum's members' values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is pretty heavily commented already, what should I add?
src/compiler/moduleNameResolver.ts
Outdated
* '.ts', '.tsx', or '.d.ts' | ||
* This is for regular imports of TypeScript code. | ||
*/ | ||
TypeScript = "TypeScript", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would adding ('.ts' preferred)
make sense here? May clarify debugging for people looking at trace-reoslution output.
@Andy-MS please refresh this PR. |
Thanks for your contribution. This PR has not been updated in a while and cannot be automatically merged at the time being. For housekeeping purposes we are closing stale PRs. If you'd still like to continue working on this PR, please leave a message and one of the maintainers can reopen it. |
node_modules
, look for a '.d.ts' file before looking for a '.ts' file -- opposite of how it is normally.node_modules/foo.d.ts
, onlynode_modules/foo/index.d.ts
.Edit by @DanielRosenwasser: Addresses issues seen in #16426.