@@ -110,6 +110,10 @@ import {
110
110
versionMajorMinor ,
111
111
VersionRange ,
112
112
} from "./_namespaces/ts" ;
113
+ import {
114
+ getPnpApi ,
115
+ getPnpTypeRoots ,
116
+ } from "./pnp" ;
113
117
114
118
/** @internal */
115
119
export function trace ( host : ModuleResolutionHost , message : DiagnosticMessage , ...args : any [ ] ) : void {
@@ -490,7 +494,7 @@ export function getEffectiveTypeRoots(options: CompilerOptions, host: GetEffecti
490
494
* Returns the path to every node_modules/@types directory from some ancestor directory.
491
495
* Returns undefined if there are none.
492
496
*/
493
- function getDefaultTypeRoots ( currentDirectory : string ) : string [ ] | undefined {
497
+ function getNodeModulesTypeRoots ( currentDirectory : string ) {
494
498
let typeRoots : string [ ] | undefined ;
495
499
forEachAncestorDirectory ( normalizePath ( currentDirectory ) , directory => {
496
500
const atTypes = combinePaths ( directory , nodeModulesAtTypes ) ;
@@ -505,6 +509,18 @@ function arePathsEqual(path1: string, path2: string, host: ModuleResolutionHost)
505
509
return comparePaths ( path1 , path2 , ! useCaseSensitiveFileNames ) === Comparison . EqualTo ;
506
510
}
507
511
512
+ function getDefaultTypeRoots ( currentDirectory : string ) : string [ ] | undefined {
513
+ const nmTypes = getNodeModulesTypeRoots ( currentDirectory ) ;
514
+ const pnpTypes = getPnpTypeRoots ( currentDirectory ) ;
515
+
516
+ if ( nmTypes ?. length ) {
517
+ return [ ...nmTypes , ...pnpTypes ] ;
518
+ }
519
+ else if ( pnpTypes . length ) {
520
+ return pnpTypes ;
521
+ }
522
+ }
523
+
508
524
function getOriginalAndResolvedFileName ( fileName : string , host : ModuleResolutionHost , traceEnabled : boolean ) {
509
525
const resolvedFileName = realPath ( fileName , host , traceEnabled ) ;
510
526
const pathsAreEqual = arePathsEqual ( fileName , resolvedFileName , host ) ;
@@ -784,6 +800,18 @@ export function resolvePackageNameToPackageJson(
784
800
) : PackageJsonInfo | undefined {
785
801
const moduleResolutionState = getTemporaryModuleResolutionState ( cache ?. getPackageJsonInfoCache ( ) , host , options ) ;
786
802
803
+ const pnpapi = getPnpApi ( containingDirectory ) ;
804
+ if ( pnpapi ) {
805
+ try {
806
+ const resolution = pnpapi . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
807
+ const candidate = normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
808
+ return getPackageJsonInfo ( candidate , /*onlyRecordFailures*/ false , moduleResolutionState ) ;
809
+ }
810
+ catch {
811
+ return ;
812
+ }
813
+ }
814
+
787
815
return forEachAncestorDirectory ( containingDirectory , ancestorDirectory => {
788
816
if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
789
817
const nodeModulesFolder = combinePaths ( ancestorDirectory , "node_modules" ) ;
@@ -2963,7 +2991,16 @@ function loadModuleFromNearestNodeModulesDirectoryWorker(extensions: Extensions,
2963
2991
}
2964
2992
2965
2993
function lookup ( extensions : Extensions ) {
2966
- return forEachAncestorDirectory ( normalizeSlashes ( directory ) , ancestorDirectory => {
2994
+ const issuer = normalizeSlashes ( directory ) ;
2995
+ if ( getPnpApi ( issuer ) ) {
2996
+ const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , issuer , redirectedReference , state ) ;
2997
+ if ( resolutionFromCache ) {
2998
+ return resolutionFromCache ;
2999
+ }
3000
+ return toSearchResult ( loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions , moduleName , issuer , state , typesScopeOnly , cache , redirectedReference ) ) ;
3001
+ }
3002
+
3003
+ return forEachAncestorDirectory ( issuer , ancestorDirectory => {
2967
3004
if ( getBaseFileName ( ancestorDirectory ) !== "node_modules" ) {
2968
3005
const resolutionFromCache = tryFindNonRelativeModuleNameInCache ( cache , moduleName , mode , ancestorDirectory , redirectedReference , state ) ;
2969
3006
if ( resolutionFromCache ) {
@@ -3002,11 +3039,34 @@ function loadModuleFromImmediateNodeModulesDirectory(extensions: Extensions, mod
3002
3039
}
3003
3040
}
3004
3041
3042
+ function loadModuleFromImmediateNodeModulesDirectoryPnP ( extensions : Extensions , moduleName : string , directory : string , state : ModuleResolutionState , typesScopeOnly : boolean , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3043
+ const issuer = normalizeSlashes ( directory ) ;
3044
+
3045
+ if ( ! typesScopeOnly ) {
3046
+ const packageResult = tryLoadModuleUsingPnpResolution ( extensions , moduleName , issuer , state , cache , redirectedReference ) ;
3047
+ if ( packageResult ) {
3048
+ return packageResult ;
3049
+ }
3050
+ }
3051
+
3052
+ if ( extensions & Extensions . Declaration ) {
3053
+ return tryLoadModuleUsingPnpResolution ( Extensions . Declaration , `@types/${ mangleScopedPackageNameWithTrace ( moduleName , state ) } ` , issuer , state , cache , redirectedReference ) ;
3054
+ }
3055
+ }
3056
+
3005
3057
function loadModuleFromSpecificNodeModulesDirectory ( extensions : Extensions , moduleName : string , nodeModulesDirectory : string , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3006
3058
const candidate = normalizePath ( combinePaths ( nodeModulesDirectory , moduleName ) ) ;
3007
3059
const { packageName, rest } = parsePackageName ( moduleName ) ;
3008
3060
const packageDirectory = combinePaths ( nodeModulesDirectory , packageName ) ;
3061
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , nodeModulesDirectoryExists , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3062
+ }
3009
3063
3064
+ function loadModuleFromPnpResolution ( extensions : Extensions , packageDirectory : string , rest : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) : Resolved | undefined {
3065
+ const candidate = normalizePath ( combinePaths ( packageDirectory , rest ) ) ;
3066
+ return loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions , /*nodeModulesDirectoryExists*/ true , state , cache , redirectedReference , candidate , rest , packageDirectory ) ;
3067
+ }
3068
+
3069
+ function loadModuleFromSpecificNodeModulesDirectoryImpl ( extensions : Extensions , nodeModulesDirectoryExists : boolean , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined , candidate : string , rest : string , packageDirectory : string ) : Resolved | undefined {
3010
3070
let rootPackageInfo : PackageJsonInfo | undefined ;
3011
3071
// First look for a nested package.json, as in `node_modules/foo/bar/package.json`.
3012
3072
let packageInfo = getPackageJsonInfo ( candidate , ! nodeModulesDirectoryExists , state ) ;
@@ -3333,3 +3393,22 @@ function useCaseSensitiveFileNames(state: ModuleResolutionState) {
3333
3393
typeof state . host . useCaseSensitiveFileNames === "boolean" ? state . host . useCaseSensitiveFileNames :
3334
3394
state . host . useCaseSensitiveFileNames ( ) ;
3335
3395
}
3396
+
3397
+ function loadPnpPackageResolution ( packageName : string , containingDirectory : string ) {
3398
+ try {
3399
+ const resolution = getPnpApi ( containingDirectory ) . resolveToUnqualified ( packageName , `${ containingDirectory } /` , { considerBuiltins : false } ) ;
3400
+ return normalizeSlashes ( resolution ) . replace ( / \/ $ / , "" ) ;
3401
+ }
3402
+ catch {
3403
+ // Nothing to do
3404
+ }
3405
+ }
3406
+
3407
+ function tryLoadModuleUsingPnpResolution ( extensions : Extensions , moduleName : string , containingDirectory : string , state : ModuleResolutionState , cache : ModuleResolutionCache | undefined , redirectedReference : ResolvedProjectReference | undefined ) {
3408
+ const { packageName, rest } = parsePackageName ( moduleName ) ;
3409
+
3410
+ const packageResolution = loadPnpPackageResolution ( packageName , containingDirectory ) ;
3411
+ return packageResolution
3412
+ ? loadModuleFromPnpResolution ( extensions , packageResolution , rest , state , cache , redirectedReference )
3413
+ : undefined ;
3414
+ }
0 commit comments