@@ -11,6 +11,7 @@ import {
1111 comparePaths ,
1212 Comparison ,
1313 CompilerOptions ,
14+ concatenate ,
1415 containsIgnoredPath ,
1516 containsPath ,
1617 createGetCanonicalFileName ,
@@ -48,13 +49,15 @@ import {
4849 getOwnKeys ,
4950 getPackageJsonTypesVersionsPaths ,
5051 getPackageNameFromTypesPackageName ,
52+ getPackageScopeForPath ,
5153 getPathsBasePath ,
5254 getRelativePathFromDirectory ,
5355 getRelativePathToDirectoryOrUrl ,
5456 getResolvePackageJsonExports ,
5557 getResolvePackageJsonImports ,
5658 getSourceFileOfModule ,
5759 getSupportedExtensions ,
60+ getTemporaryModuleResolutionState ,
5861 getTextOfIdentifierOrLiteral ,
5962 hasJSFileExtension ,
6063 hasTSFileExtension ,
@@ -84,6 +87,7 @@ import {
8487 ModuleDeclaration ,
8588 ModuleKind ,
8689 ModulePath ,
90+ ModuleResolutionHost ,
8791 ModuleResolutionKind ,
8892 ModuleSpecifierCache ,
8993 ModuleSpecifierEnding ,
@@ -92,6 +96,7 @@ import {
9296 NodeFlags ,
9397 NodeModulePathParts ,
9498 normalizePath ,
99+ PackageJsonPathFields ,
95100 pathContainsNodeModules ,
96101 pathIsBareSpecifier ,
97102 pathIsRelative ,
@@ -102,6 +107,7 @@ import {
102107 removeTrailingDirectorySeparator ,
103108 replaceFirstStar ,
104109 ResolutionMode ,
110+ resolveModuleName ,
105111 resolvePath ,
106112 ScriptKind ,
107113 shouldAllowImportingTsExtension ,
@@ -254,7 +260,7 @@ export function getNodeModulesPackageName(
254260 options : ModuleSpecifierOptions = { } ,
255261) : string | undefined {
256262 const info = getInfo ( importingSourceFile . fileName , host ) ;
257- const modulePaths = getAllModulePaths ( info , nodeModulesFileName , host , preferences , options ) ;
263+ const modulePaths = getAllModulePaths ( info , nodeModulesFileName , host , preferences , compilerOptions , options ) ;
258264 return firstDefined ( modulePaths , modulePath => tryGetModuleNameAsNodeModule ( modulePath , info , importingSourceFile , host , compilerOptions , preferences , /*packageNameOnly*/ true , options . overrideImportMode ) ) ;
259265}
260266
@@ -269,7 +275,7 @@ function getModuleSpecifierWorker(
269275 options : ModuleSpecifierOptions = { } ,
270276) : string {
271277 const info = getInfo ( importingSourceFileName , host ) ;
272- const modulePaths = getAllModulePaths ( info , toFileName , host , userPreferences , options ) ;
278+ const modulePaths = getAllModulePaths ( info , toFileName , host , userPreferences , compilerOptions , options ) ;
273279 return firstDefined ( modulePaths , modulePath => tryGetModuleNameAsNodeModule ( modulePath , info , importingSourceFile , host , compilerOptions , userPreferences , /*packageNameOnly*/ undefined , options . overrideImportMode ) ) ||
274280 getLocalModuleSpecifier ( toFileName , info , compilerOptions , host , options . overrideImportMode || getDefaultResolutionModeForFile ( importingSourceFile , host , compilerOptions ) , preferences ) ;
275281}
@@ -361,7 +367,7 @@ export function getModuleSpecifiersWithCacheInfo(
361367 if ( ! moduleSourceFile ) return { moduleSpecifiers : emptyArray , computedWithoutCache } ;
362368
363369 computedWithoutCache = true ;
364- modulePaths ||= getAllModulePathsWorker ( getInfo ( importingSourceFile . fileName , host ) , moduleSourceFile . originalFileName , host ) ;
370+ modulePaths ||= getAllModulePathsWorker ( getInfo ( importingSourceFile . fileName , host ) , moduleSourceFile . originalFileName , host , compilerOptions , options ) ;
365371 const result = computeModuleSpecifiers (
366372 modulePaths ,
367373 compilerOptions ,
@@ -691,6 +697,7 @@ function getAllModulePaths(
691697 importedFileName : string ,
692698 host : ModuleSpecifierResolutionHost ,
693699 preferences : UserPreferences ,
700+ compilerOptions : CompilerOptions ,
694701 options : ModuleSpecifierOptions = { } ,
695702) {
696703 const importingFilePath = toPath ( info . importingSourceFileName , host . getCurrentDirectory ( ) , hostGetCanonicalFileName ( host ) ) ;
@@ -700,14 +707,45 @@ function getAllModulePaths(
700707 const cached = cache . get ( importingFilePath , importedFilePath , preferences , options ) ;
701708 if ( cached ?. modulePaths ) return cached . modulePaths ;
702709 }
703- const modulePaths = getAllModulePathsWorker ( info , importedFileName , host ) ;
710+ const modulePaths = getAllModulePathsWorker ( info , importedFileName , host , compilerOptions , options ) ;
704711 if ( cache ) {
705712 cache . setModulePaths ( importingFilePath , importedFilePath , preferences , options , modulePaths ) ;
706713 }
707714 return modulePaths ;
708715}
709716
710- function getAllModulePathsWorker ( info : Info , importedFileName : string , host : ModuleSpecifierResolutionHost ) : readonly ModulePath [ ] {
717+ const runtimeDependencyFields = [ "dependencies" , "peerDependencies" , "optionalDependencies" ] as const ;
718+
719+ function getAllRuntimeDependencies ( packageJson : PackageJsonPathFields ) {
720+ let result ;
721+ for ( const field of runtimeDependencyFields ) {
722+ const deps = packageJson [ field ] ;
723+ if ( deps && typeof deps === "object" ) {
724+ result = concatenate ( result , getOwnKeys ( deps ) ) ;
725+ }
726+ }
727+ return result ;
728+ }
729+
730+ function getAllModulePathsWorker ( info : Info , importedFileName : string , host : ModuleSpecifierResolutionHost , compilerOptions : CompilerOptions , options : ModuleSpecifierOptions ) : readonly ModulePath [ ] {
731+ const cache = host . getModuleResolutionCache ?.( ) ;
732+ const links = host . getSymlinkCache ?.( ) ;
733+ if ( cache && links && host . readFile && ! pathContainsNodeModules ( info . importingSourceFileName ) ) {
734+ Debug . type < ModuleResolutionHost > ( host ) ;
735+ // Cache resolutions for all `dependencies` of the `package.json` context of the input file.
736+ // This should populate all the relevant symlinks in the symlink cache, and most, if not all, of these resolutions
737+ // should get (re)used.
738+ const state = getTemporaryModuleResolutionState ( cache . getPackageJsonInfoCache ( ) , host , { } ) ;
739+ const packageJson = getPackageScopeForPath ( info . importingSourceFileName , state ) ;
740+ if ( packageJson ) {
741+ const toResolve = getAllRuntimeDependencies ( packageJson . contents . packageJsonContent ) ;
742+ for ( const depName of ( toResolve || emptyArray ) ) {
743+ const resolved = resolveModuleName ( depName , combinePaths ( packageJson . packageDirectory , "package.json" ) , compilerOptions , host , cache , /*redirectedReference*/ undefined , options . overrideImportMode ) ;
744+ links . setSymlinksFromResolution ( resolved . resolvedModule ) ;
745+ }
746+ }
747+ }
748+
711749 const allFileNames = new Map < string , { path : string ; isRedirect : boolean ; isInNodeModules : boolean ; } > ( ) ;
712750 let importedFileFromNodeModules = false ;
713751 forEachFileNameOfModule (
0 commit comments