@@ -1132,12 +1132,19 @@ func (r resolverQuery) dirInfoCached(path string) *dirInfo {
11321132
11331133 // Cache hit: stop now
11341134 if ! ok {
1135+ // Update the cache to indicate failure. Even if the read failed, we don't
1136+ // want to retry again later. The directory is inaccessible so trying again
1137+ // is wasted. Doing this before calling "dirInfoUncached" prevents stack
1138+ // overflow in case this directory is recursively encountered again.
1139+ r .dirCache [path ] = nil
1140+
11351141 // Cache miss: read the info
11361142 cached = r .dirInfoUncached (path )
11371143
1138- // Update the cache unconditionally. Even if the read failed, we don't want to
1139- // retry again later. The directory is inaccessible so trying again is wasted.
1140- r .dirCache [path ] = cached
1144+ // Only update the cache again on success
1145+ if cached != nil {
1146+ r .dirCache [path ] = cached
1147+ }
11411148 }
11421149
11431150 if r .debugLogs != nil {
@@ -1294,7 +1301,8 @@ func (r resolverQuery) parseTSConfigFromSource(source logger.Source, visited map
12941301 if entry , _ := entries .Get ("package.json" ); entry != nil && entry .Kind (r .fs ) == fs .FileEntry {
12951302 // Check the "exports" map
12961303 if packageJSON := r .parsePackageJSON (result .pkgDirPath ); packageJSON != nil && packageJSON .exportsMap != nil {
1297- if absolute , ok , _ := r .esmResolveAlgorithm (result .pkgIdent , "." + result .pkgSubpath , packageJSON , result .pkgDirPath , source .KeyPath .Text ); ok {
1304+ if absolute , ok , _ := r .esmResolveAlgorithm (finalizeImportsExportsYarnPnPTSConfigExtends ,
1305+ result .pkgIdent , "." + result .pkgSubpath , packageJSON , result .pkgDirPath , source .KeyPath .Text ); ok {
12981306 base , err := r .parseTSConfig (absolute .Primary .Text , visited , configDir )
12991307 if result , shouldReturn := maybeFinishOurSearch (base , err , absolute .Primary .Text ); shouldReturn {
13001308 return result
@@ -2236,14 +2244,22 @@ func (r resolverQuery) loadPackageImports(importPath string, dirInfoPackageJSON
22362244 }
22372245
22382246 absolute , ok , diffCase := r .finalizeImportsExportsResult (
2247+ finalizeImportsExportsNormal ,
22392248 dirInfoPackageJSON .absPath , conditions , * packageJSON .importsMap , packageJSON ,
22402249 resolvedPath , status , debug ,
22412250 "" , "" , "" ,
22422251 )
22432252 return absolute , ok , diffCase , nil
22442253}
22452254
2246- func (r resolverQuery ) esmResolveAlgorithm (esmPackageName string , esmPackageSubpath string , packageJSON * packageJSON , absPkgPath string , absPath string ) (PathPair , bool , * fs.DifferentCase ) {
2255+ func (r resolverQuery ) esmResolveAlgorithm (
2256+ kind finalizeImportsExportsKind ,
2257+ esmPackageName string ,
2258+ esmPackageSubpath string ,
2259+ packageJSON * packageJSON ,
2260+ absPkgPath string ,
2261+ absPath string ,
2262+ ) (PathPair , bool , * fs.DifferentCase ) {
22472263 if r .debugLogs != nil {
22482264 r .debugLogs .addNote (fmt .Sprintf ("Looking for %q in \" exports\" map in %q" , esmPackageSubpath , packageJSON .source .KeyPath .Text ))
22492265 r .debugLogs .increaseIndent ()
@@ -2278,6 +2294,7 @@ func (r resolverQuery) esmResolveAlgorithm(esmPackageName string, esmPackageSubp
22782294 resolvedPath , status , debug = r .esmHandlePostConditions (resolvedPath , status , debug )
22792295
22802296 return r .finalizeImportsExportsResult (
2297+ kind ,
22812298 absPkgPath , conditions , * packageJSON .exportsMap , packageJSON ,
22822299 resolvedPath , status , debug ,
22832300 esmPackageName , esmPackageSubpath , absPath ,
@@ -2358,7 +2375,7 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
23582375 if pkgDirInfo := r .dirInfoCached (result .pkgDirPath ); pkgDirInfo != nil {
23592376 // Check the "exports" map
23602377 if packageJSON := pkgDirInfo .packageJSON ; packageJSON != nil && packageJSON .exportsMap != nil {
2361- absolute , ok , diffCase := r .esmResolveAlgorithm (result .pkgIdent , "." + result .pkgSubpath , packageJSON , pkgDirInfo .absPath , absPath )
2378+ absolute , ok , diffCase := r .esmResolveAlgorithm (finalizeImportsExportsNormal , result .pkgIdent , "." + result .pkgSubpath , packageJSON , pkgDirInfo .absPath , absPath )
23622379 return absolute , ok , diffCase , nil
23632380 }
23642381
@@ -2393,7 +2410,7 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
23932410 // Check for self-references
23942411 if dirInfoPackageJSON != nil {
23952412 if packageJSON := dirInfoPackageJSON .packageJSON ; packageJSON .name == esmPackageName && packageJSON .exportsMap != nil {
2396- absolute , ok , diffCase := r .esmResolveAlgorithm (esmPackageName , esmPackageSubpath , packageJSON ,
2413+ absolute , ok , diffCase := r .esmResolveAlgorithm (finalizeImportsExportsNormal , esmPackageName , esmPackageSubpath , packageJSON ,
23972414 dirInfoPackageJSON .absPath , r .fs .Join (dirInfoPackageJSON .absPath , esmPackageSubpath ))
23982415 return absolute , ok , diffCase , nil
23992416 }
@@ -2412,7 +2429,7 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
24122429 if pkgDirInfo := r .dirInfoCached (absPkgPath ); pkgDirInfo != nil {
24132430 // Check the "exports" map
24142431 if packageJSON := pkgDirInfo .packageJSON ; packageJSON != nil && packageJSON .exportsMap != nil {
2415- absolute , ok , diffCase := r .esmResolveAlgorithm (esmPackageName , esmPackageSubpath , packageJSON , absPkgPath , absPath )
2432+ absolute , ok , diffCase := r .esmResolveAlgorithm (finalizeImportsExportsNormal , esmPackageName , esmPackageSubpath , packageJSON , absPkgPath , absPath )
24162433 return absolute , ok , diffCase , nil , true
24172434 }
24182435
@@ -2524,7 +2541,15 @@ func (r resolverQuery) checkForBuiltInNodeModules(importPath string) (PathPair,
25242541 return PathPair {}, false , nil
25252542}
25262543
2544+ type finalizeImportsExportsKind uint8
2545+
2546+ const (
2547+ finalizeImportsExportsNormal finalizeImportsExportsKind = iota
2548+ finalizeImportsExportsYarnPnPTSConfigExtends
2549+ )
2550+
25272551func (r resolverQuery ) finalizeImportsExportsResult (
2552+ kind finalizeImportsExportsKind ,
25282553 absDirPath string ,
25292554 conditions map [string ]bool ,
25302555 importExportMap pjMap ,
@@ -2551,6 +2576,14 @@ func (r resolverQuery) finalizeImportsExportsResult(
25512576 r .debugLogs .addNote (fmt .Sprintf ("The resolved path %q is exact" , absResolvedPath ))
25522577 }
25532578
2579+ // Avoid calling "dirInfoCached" recursively for "tsconfig.json" extends with Yarn PnP
2580+ if kind == finalizeImportsExportsYarnPnPTSConfigExtends {
2581+ if r .debugLogs != nil {
2582+ r .debugLogs .addNote (fmt .Sprintf ("Resolved to %q" , absResolvedPath ))
2583+ }
2584+ return PathPair {Primary : logger.Path {Text : absResolvedPath , Namespace : "file" }}, true , nil
2585+ }
2586+
25542587 resolvedDirInfo := r .dirInfoCached (r .fs .Dir (absResolvedPath ))
25552588 base := r .fs .Base (absResolvedPath )
25562589 extensionOrder := r .options .ExtensionOrder
0 commit comments