@@ -74,6 +74,7 @@ import {
7474 ModuleResolutionKind ,
7575 moduleResolutionOptionDeclarations ,
7676 moduleResolutionSupportsPackageJsonExportsAndImports ,
77+ ModuleSpecifierResolutionHost ,
7778 noop ,
7879 normalizePath ,
7980 normalizeSlashes ,
@@ -788,7 +789,7 @@ export function resolvePackageNameToPackageJson(
788789) : PackageJsonInfo | undefined {
789790 const moduleResolutionState = getTemporaryModuleResolutionState ( cache ?. getPackageJsonInfoCache ( ) , host , options ) ;
790791
791- return forEachAncestorDirectory ( containingDirectory , ancestorDirectory => {
792+ return forEachAncestorDirectoryStoppingAtGlobalCache ( host , containingDirectory , ancestorDirectory => {
792793 if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
793794 const nodeModulesFolder = combinePaths ( ancestorDirectory , "node_modules" ) ;
794795 const candidate = combinePaths ( nodeModulesFolder , packageName ) ;
@@ -2383,7 +2384,8 @@ export interface PackageJsonInfoContents {
23832384 * @internal
23842385 */
23852386export function getPackageScopeForPath ( directory : string , state : ModuleResolutionState ) : PackageJsonInfo | undefined {
2386- return forEachAncestorDirectory (
2387+ return forEachAncestorDirectoryStoppingAtGlobalCache (
2388+ state . host ,
23872389 directory ,
23882390 dir => getPackageJsonInfo ( dir , /*onlyRecordFailures*/ false , state ) ,
23892391 ) ;
@@ -3003,18 +3005,41 @@ function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions,
30033005 }
30043006
30053007 function lookup ( extensions : Extensions ) {
3006- return forEachAncestorDirectory ( normalizeSlashes ( directory ) , ancestorDirectory => {
3007- if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
3008- const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , ancestorDirectory , redirectedReference , state ) ;
3009- if ( resolutionFromCache ) {
3010- return resolutionFromCache ;
3008+ return forEachAncestorDirectoryStoppingAtGlobalCache (
3009+ state . host ,
3010+ normalizeSlashes ( directory ) ,
3011+ ancestorDirectory => {
3012+ // Dont go past global cache location
3013+ if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
3014+ const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , ancestorDirectory , redirectedReference , state ) ;
3015+ if ( resolutionFromCache ) {
3016+ return resolutionFromCache ;
3017+ }
3018+ return toSearchResult ( loadModuleFromImmediateNodeModulesDirectory ( extensions , moduleName , ancestorDirectory , state , typesScopeOnly , cache , redirectedReference ) ) ;
30113019 }
3012- return toSearchResult ( loadModuleFromImmediateNodeModulesDirectory ( extensions , moduleName , ancestorDirectory , state , typesScopeOnly , cache , redirectedReference ) ) ;
3013- }
3014- } ) ;
3020+ } ,
3021+ ) ;
30153022 }
30163023}
30173024
3025+ /**
3026+ * Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result.
3027+ * Stops at global cache location
3028+ * @internal
3029+ */
3030+ export function forEachAncestorDirectoryStoppingAtGlobalCache < T , P extends string > (
3031+ host : ModuleResolutionHost | ModuleSpecifierResolutionHost ,
3032+ directory : P ,
3033+ callback : ( directory : P ) => T | undefined ,
3034+ ) : T | undefined {
3035+ const globalCache = host ?. getGlobalTypingsCacheLocation ?.( ) ;
3036+ return forEachAncestorDirectory ( directory , ancestorDirectory => {
3037+ const result = callback ( ancestorDirectory as P ) ;
3038+ if ( result !== undefined ) return result ;
3039+ if ( ancestorDirectory === globalCache ) return false ;
3040+ } ) || undefined ;
3041+ }
3042+
30183043function loadModuleFromImmediateNodeModulesDirectory ( extensions : Extensions , moduleName : string , directory : string , state : ModuleResolutionState , typesScopeOnly : boolean , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
30193044 const nodeModulesFolder = combinePaths ( directory , "node_modules" ) ;
30203045 const nodeModulesFolderExists = directoryProbablyExists ( nodeModulesFolder , state . host ) ;
@@ -3258,14 +3283,18 @@ export function classicNameResolver(moduleName: string, containingFile: string,
32583283
32593284 if ( ! isExternalModuleNameRelative ( moduleName ) ) {
32603285 // Climb up parent directories looking for a module.
3261- const resolved = forEachAncestorDirectory ( containingDirectory , directory => {
3262- const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , /*mode*/ undefined , directory , redirectedReference , state ) ;
3263- if ( resolutionFromCache ) {
3264- return resolutionFromCache ;
3265- }
3266- const searchName = normalizePath ( combinePaths ( directory , moduleName ) ) ;
3267- return toSearchResult ( loadModuleFromFileNoPackageId ( extensions , searchName , /*onlyRecordFailures*/ false , state ) ) ;
3268- } ) ;
3286+ const resolved = forEachAncestorDirectoryStoppingAtGlobalCache (
3287+ state . host ,
3288+ containingDirectory ,
3289+ directory => {
3290+ const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , /*mode*/ undefined , directory , redirectedReference , state ) ;
3291+ if ( resolutionFromCache ) {
3292+ return resolutionFromCache ;
3293+ }
3294+ const searchName = normalizePath ( combinePaths ( directory , moduleName ) ) ;
3295+ return toSearchResult ( loadModuleFromFileNoPackageId ( extensions , searchName , /*onlyRecordFailures*/ false , state ) ) ;
3296+ } ,
3297+ ) ;
32693298 if ( resolved ) return resolved ;
32703299 if ( extensions & ( Extensions . TypeScript | Extensions . Declaration ) ) {
32713300 // If we didn't find the file normally, look it up in @types.
0 commit comments