@@ -1132,12 +1132,19 @@ func (r resolverQuery) dirInfoCached(path string) *dirInfo {
1132
1132
1133
1133
// Cache hit: stop now
1134
1134
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
+
1135
1141
// Cache miss: read the info
1136
1142
cached = r .dirInfoUncached (path )
1137
1143
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
+ }
1141
1148
}
1142
1149
1143
1150
if r .debugLogs != nil {
@@ -1294,7 +1301,8 @@ func (r resolverQuery) parseTSConfigFromSource(source logger.Source, visited map
1294
1301
if entry , _ := entries .Get ("package.json" ); entry != nil && entry .Kind (r .fs ) == fs .FileEntry {
1295
1302
// Check the "exports" map
1296
1303
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 {
1298
1306
base , err := r .parseTSConfig (absolute .Primary .Text , visited , configDir )
1299
1307
if result , shouldReturn := maybeFinishOurSearch (base , err , absolute .Primary .Text ); shouldReturn {
1300
1308
return result
@@ -2236,14 +2244,22 @@ func (r resolverQuery) loadPackageImports(importPath string, dirInfoPackageJSON
2236
2244
}
2237
2245
2238
2246
absolute , ok , diffCase := r .finalizeImportsExportsResult (
2247
+ finalizeImportsExportsNormal ,
2239
2248
dirInfoPackageJSON .absPath , conditions , * packageJSON .importsMap , packageJSON ,
2240
2249
resolvedPath , status , debug ,
2241
2250
"" , "" , "" ,
2242
2251
)
2243
2252
return absolute , ok , diffCase , nil
2244
2253
}
2245
2254
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 ) {
2247
2263
if r .debugLogs != nil {
2248
2264
r .debugLogs .addNote (fmt .Sprintf ("Looking for %q in \" exports\" map in %q" , esmPackageSubpath , packageJSON .source .KeyPath .Text ))
2249
2265
r .debugLogs .increaseIndent ()
@@ -2278,6 +2294,7 @@ func (r resolverQuery) esmResolveAlgorithm(esmPackageName string, esmPackageSubp
2278
2294
resolvedPath , status , debug = r .esmHandlePostConditions (resolvedPath , status , debug )
2279
2295
2280
2296
return r .finalizeImportsExportsResult (
2297
+ kind ,
2281
2298
absPkgPath , conditions , * packageJSON .exportsMap , packageJSON ,
2282
2299
resolvedPath , status , debug ,
2283
2300
esmPackageName , esmPackageSubpath , absPath ,
@@ -2358,7 +2375,7 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
2358
2375
if pkgDirInfo := r .dirInfoCached (result .pkgDirPath ); pkgDirInfo != nil {
2359
2376
// Check the "exports" map
2360
2377
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 )
2362
2379
return absolute , ok , diffCase , nil
2363
2380
}
2364
2381
@@ -2393,7 +2410,7 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
2393
2410
// Check for self-references
2394
2411
if dirInfoPackageJSON != nil {
2395
2412
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 ,
2397
2414
dirInfoPackageJSON .absPath , r .fs .Join (dirInfoPackageJSON .absPath , esmPackageSubpath ))
2398
2415
return absolute , ok , diffCase , nil
2399
2416
}
@@ -2412,7 +2429,7 @@ func (r resolverQuery) loadNodeModules(importPath string, dirInfo *dirInfo, forb
2412
2429
if pkgDirInfo := r .dirInfoCached (absPkgPath ); pkgDirInfo != nil {
2413
2430
// Check the "exports" map
2414
2431
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 )
2416
2433
return absolute , ok , diffCase , nil , true
2417
2434
}
2418
2435
@@ -2524,7 +2541,15 @@ func (r resolverQuery) checkForBuiltInNodeModules(importPath string) (PathPair,
2524
2541
return PathPair {}, false , nil
2525
2542
}
2526
2543
2544
+ type finalizeImportsExportsKind uint8
2545
+
2546
+ const (
2547
+ finalizeImportsExportsNormal finalizeImportsExportsKind = iota
2548
+ finalizeImportsExportsYarnPnPTSConfigExtends
2549
+ )
2550
+
2527
2551
func (r resolverQuery ) finalizeImportsExportsResult (
2552
+ kind finalizeImportsExportsKind ,
2528
2553
absDirPath string ,
2529
2554
conditions map [string ]bool ,
2530
2555
importExportMap pjMap ,
@@ -2551,6 +2576,14 @@ func (r resolverQuery) finalizeImportsExportsResult(
2551
2576
r .debugLogs .addNote (fmt .Sprintf ("The resolved path %q is exact" , absResolvedPath ))
2552
2577
}
2553
2578
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
+
2554
2587
resolvedDirInfo := r .dirInfoCached (r .fs .Dir (absResolvedPath ))
2555
2588
base := r .fs .Base (absResolvedPath )
2556
2589
extensionOrder := r .options .ExtensionOrder
0 commit comments