@@ -193,63 +193,66 @@ namespace ts {
193
193
194
194
const failedLookupLocations : string [ ] = [ ] ;
195
195
196
- // Check primary library paths
197
- if ( typeRoots && typeRoots . length ) {
196
+ let resolved = primaryLookup ( ) ;
197
+ let primary = true ;
198
+ if ( ! resolved ) {
199
+ resolved = secondaryLookup ( ) ;
200
+ primary = false ;
201
+ }
202
+
203
+ let resolvedTypeReferenceDirective : ResolvedTypeReferenceDirective | undefined ;
204
+ if ( resolved ) {
205
+ resolved = realpath ( resolved , host , traceEnabled ) ;
198
206
if ( traceEnabled ) {
199
- trace ( host , Diagnostics . Resolving_with_primary_search_path_0 , typeRoots . join ( ", " ) ) ;
207
+ trace ( host , Diagnostics . Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2 , typeReferenceDirectiveName , resolved , primary ) ;
200
208
}
201
- for ( const typeRoot of typeRoots ) {
202
- const candidate = combinePaths ( typeRoot , typeReferenceDirectiveName ) ;
203
- const candidateDirectory = getDirectoryPath ( candidate ) ;
209
+ resolvedTypeReferenceDirective = { primary, resolvedFileName : resolved } ;
210
+ }
204
211
205
- const resolved = resolvedTypeScriptOnly (
206
- loadNodeModuleFromDirectory ( Extensions . DtsOnly , candidate , failedLookupLocations ,
207
- ! directoryProbablyExists ( candidateDirectory , host ) , moduleResolutionState ) ) ;
212
+ return { resolvedTypeReferenceDirective, failedLookupLocations } ;
208
213
209
- if ( resolved ) {
210
- if ( traceEnabled ) {
211
- trace ( host , Diagnostics . Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2 , typeReferenceDirectiveName , resolved , true ) ;
212
- }
213
- return {
214
- resolvedTypeReferenceDirective : { primary : true , resolvedFileName : resolved } ,
215
- failedLookupLocations
216
- } ;
214
+ function primaryLookup ( ) : string | undefined {
215
+ // Check primary library paths
216
+ if ( typeRoots && typeRoots . length ) {
217
+ if ( traceEnabled ) {
218
+ trace ( host , Diagnostics . Resolving_with_primary_search_path_0 , typeRoots . join ( ", " ) ) ;
217
219
}
220
+ return forEach ( typeRoots , typeRoot => {
221
+ const candidate = combinePaths ( typeRoot , typeReferenceDirectiveName ) ;
222
+ const candidateDirectory = getDirectoryPath ( candidate ) ;
223
+ return resolvedTypeScriptOnly (
224
+ loadNodeModuleFromDirectory ( Extensions . DtsOnly , candidate , failedLookupLocations ,
225
+ ! directoryProbablyExists ( candidateDirectory , host ) , moduleResolutionState ) ) ;
226
+ } ) ;
218
227
}
219
- }
220
- else {
221
- if ( traceEnabled ) {
222
- trace ( host , Diagnostics . Root_directory_cannot_be_determined_skipping_primary_search_paths ) ;
228
+ else {
229
+ if ( traceEnabled ) {
230
+ trace ( host , Diagnostics . Root_directory_cannot_be_determined_skipping_primary_search_paths ) ;
231
+ }
223
232
}
224
233
}
225
234
226
- let resolvedFile : string ;
227
- const initialLocationForSecondaryLookup = containingFile && getDirectoryPath ( containingFile ) ;
235
+ function secondaryLookup ( ) : string | undefined {
236
+ let resolvedFile : string ;
237
+ const initialLocationForSecondaryLookup = containingFile && getDirectoryPath ( containingFile ) ;
228
238
229
- if ( initialLocationForSecondaryLookup !== undefined ) {
230
- // check secondary locations
231
- if ( traceEnabled ) {
232
- trace ( host , Diagnostics . Looking_up_in_node_modules_folder_initial_location_0 , initialLocationForSecondaryLookup ) ;
233
- }
234
- resolvedFile = resolvedTypeScriptOnly ( loadModuleFromNodeModules ( Extensions . DtsOnly , typeReferenceDirectiveName , initialLocationForSecondaryLookup , failedLookupLocations , moduleResolutionState ) ) ;
235
- if ( traceEnabled ) {
236
- if ( resolvedFile ) {
237
- trace ( host , Diagnostics . Type_reference_directive_0_was_successfully_resolved_to_1_primary_Colon_2 , typeReferenceDirectiveName , resolvedFile , false ) ;
239
+ if ( initialLocationForSecondaryLookup !== undefined ) {
240
+ // check secondary locations
241
+ if ( traceEnabled ) {
242
+ trace ( host , Diagnostics . Looking_up_in_node_modules_folder_initial_location_0 , initialLocationForSecondaryLookup ) ;
238
243
}
239
- else {
244
+ resolvedFile = resolvedTypeScriptOnly ( loadModuleFromNodeModules ( Extensions . DtsOnly , typeReferenceDirectiveName , initialLocationForSecondaryLookup , failedLookupLocations , moduleResolutionState ) ) ;
245
+ if ( ! resolvedFile && traceEnabled ) {
240
246
trace ( host , Diagnostics . Type_reference_directive_0_was_not_resolved , typeReferenceDirectiveName ) ;
241
247
}
248
+ return resolvedFile ;
242
249
}
243
- }
244
- else {
245
- if ( traceEnabled ) {
246
- trace ( host , Diagnostics . Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder ) ;
250
+ else {
251
+ if ( traceEnabled ) {
252
+ trace ( host , Diagnostics . Containing_file_is_not_specified_and_root_directory_cannot_be_determined_skipping_lookup_in_node_modules_folder ) ;
253
+ }
247
254
}
248
255
}
249
- return {
250
- resolvedTypeReferenceDirective : resolvedFile ? { primary : false , resolvedFileName : resolvedFile } : undefined ,
251
- failedLookupLocations
252
- } ;
253
256
}
254
257
255
258
/**
@@ -546,7 +549,7 @@ namespace ts {
546
549
const result = tryResolve ( Extensions . TypeScript ) || tryResolve ( Extensions . JavaScript ) ;
547
550
if ( result ) {
548
551
const { resolved, isExternalLibraryImport } = result ;
549
- return createResolvedModuleWithFailedLookupLocations ( resolved && resolvedWithRealpath ( resolved , host , traceEnabled ) , isExternalLibraryImport , failedLookupLocations ) ;
552
+ return createResolvedModuleWithFailedLookupLocations ( resolved , isExternalLibraryImport , failedLookupLocations ) ;
550
553
}
551
554
return { resolvedModule : undefined , failedLookupLocations } ;
552
555
@@ -561,7 +564,8 @@ namespace ts {
561
564
trace ( host , Diagnostics . Loading_module_0_from_node_modules_folder , moduleName ) ;
562
565
}
563
566
const resolved = loadModuleFromNodeModules ( extensions , moduleName , containingDirectory , failedLookupLocations , state ) ;
564
- return resolved && { resolved, isExternalLibraryImport : true } ;
567
+ // For node_modules lookups, get the real path so that multiple accesses to an `npm link`-ed module do not create duplicate files.
568
+ return resolved && { resolved : { path : realpath ( resolved . path , host , traceEnabled ) , extension : resolved . extension } , isExternalLibraryImport : true } ;
565
569
}
566
570
else {
567
571
const candidate = normalizePath ( combinePaths ( containingDirectory , moduleName ) ) ;
@@ -571,16 +575,16 @@ namespace ts {
571
575
}
572
576
}
573
577
574
- function resolvedWithRealpath ( resolved : Resolved , host : ModuleResolutionHost , traceEnabled : boolean ) : Resolved {
578
+ function realpath ( path : string , host : ModuleResolutionHost , traceEnabled : boolean ) : string {
575
579
if ( ! host . realpath ) {
576
- return resolved ;
580
+ return path ;
577
581
}
578
582
579
- const real = normalizePath ( host . realpath ( resolved . path ) ) ;
583
+ const real = normalizePath ( host . realpath ( path ) ) ;
580
584
if ( traceEnabled ) {
581
- trace ( host , Diagnostics . Resolving_real_path_for_0_result_1 , resolved . path , real ) ;
585
+ trace ( host , Diagnostics . Resolving_real_path_for_0_result_1 , path , real ) ;
582
586
}
583
- return { path : real , extension : resolved . extension } ;
587
+ return real ;
584
588
}
585
589
586
590
function nodeLoadModuleByRelativeName ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState ) : Resolved | undefined {
0 commit comments