@@ -67,40 +67,32 @@ namespace ts {
67
67
}
68
68
69
69
/** Reads from "main" or "types"/"typings" depending on `extensions`. */
70
- function tryReadPackageJsonMainOrTypes ( extensions : Extensions , packageJsonPath : string , baseDirectory : string , state : ModuleResolutionState ) : string {
70
+ function tryReadPackageJsonFields ( ts : boolean , packageJsonPath : string , baseDirectory : string , state : ModuleResolutionState ) : string | undefined {
71
71
const jsonContent = readJson ( packageJsonPath , state . host ) ;
72
+ const file = ts ? tryReadFromField ( "typings" ) || tryReadFromField ( "types" ) : tryReadFromField ( "main" ) ;
73
+ if ( ! file && state . traceEnabled ) {
74
+ trace ( state . host , Diagnostics . package_json_does_not_have_a_0_field , ts ? "types" : "main" ) ;
75
+ }
76
+ return file ;
72
77
73
- switch ( extensions ) {
74
- case Extensions . DtsOnly :
75
- case Extensions . TypeScript :
76
- return tryReadFromField ( "typings" ) || tryReadFromField ( "types" ) ;
78
+ function tryReadFromField ( fieldName : "typings" | "types" | "main" ) : string | undefined {
79
+ if ( ! hasProperty ( jsonContent , fieldName ) ) {
80
+ return ;
81
+ }
77
82
78
- case Extensions . JavaScript :
79
- if ( typeof jsonContent . main === "string" ) {
80
- if ( state . traceEnabled ) {
81
- trace ( state . host , Diagnostics . No_types_specified_in_package_json_so_returning_main_value_of_0 , jsonContent . main ) ;
82
- }
83
- return normalizePath ( combinePaths ( baseDirectory , jsonContent . main ) ) ;
83
+ const fileName = jsonContent [ fieldName ] ;
84
+ if ( typeof fileName !== "string" ) {
85
+ if ( state . traceEnabled ) {
86
+ trace ( state . host , Diagnostics . Expected_type_of_0_field_in_package_json_to_be_string_got_1 , fieldName , typeof fileName ) ;
84
87
}
85
- return undefined ;
86
- }
88
+ return ;
89
+ }
87
90
88
- function tryReadFromField ( fieldName : string ) {
89
- if ( hasProperty ( jsonContent , fieldName ) ) {
90
- const typesFile = ( < any > jsonContent ) [ fieldName ] ;
91
- if ( typeof typesFile === "string" ) {
92
- const typesFilePath = normalizePath ( combinePaths ( baseDirectory , typesFile ) ) ;
93
- if ( state . traceEnabled ) {
94
- trace ( state . host , Diagnostics . package_json_has_0_field_1_that_references_2 , fieldName , typesFile , typesFilePath ) ;
95
- }
96
- return typesFilePath ;
97
- }
98
- else {
99
- if ( state . traceEnabled ) {
100
- trace ( state . host , Diagnostics . Expected_type_of_0_field_in_package_json_to_be_string_got_1 , fieldName , typeof typesFile ) ;
101
- }
102
- }
91
+ const path = normalizePath ( combinePaths ( baseDirectory , fileName ) ) ;
92
+ if ( state . traceEnabled ) {
93
+ trace ( state . host , Diagnostics . package_json_has_0_field_1_that_references_2 , fieldName , fileName , path ) ;
103
94
}
95
+ return path ;
104
96
}
105
97
}
106
98
@@ -731,7 +723,7 @@ namespace ts {
731
723
return real ;
732
724
}
733
725
734
- function nodeLoadModuleByRelativeName ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState ) : Resolved | undefined {
726
+ function nodeLoadModuleByRelativeName ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , considerPackageJson = true ) : Resolved | undefined {
735
727
if ( state . traceEnabled ) {
736
728
trace ( state . host , Diagnostics . Loading_module_as_file_Slash_folder_candidate_module_location_0_target_file_type_1 , candidate , Extensions [ extensions ] ) ;
737
729
}
@@ -759,7 +751,7 @@ namespace ts {
759
751
onlyRecordFailures = true ;
760
752
}
761
753
}
762
- return loadNodeModuleFromDirectory ( extensions , candidate , failedLookupLocations , onlyRecordFailures , state ) ;
754
+ return loadNodeModuleFromDirectory ( extensions , candidate , failedLookupLocations , onlyRecordFailures , state , considerPackageJson ) ;
763
755
}
764
756
765
757
/* @internal */
@@ -835,48 +827,56 @@ namespace ts {
835
827
return undefined ;
836
828
}
837
829
838
- function loadNodeModuleFromDirectory ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState ) : Resolved | undefined {
839
- const packageJsonPath = pathToPackageJson ( candidate ) ;
830
+ function loadNodeModuleFromDirectory ( extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , onlyRecordFailures : boolean , state : ModuleResolutionState , considerPackageJson = true ) : Resolved | undefined {
840
831
const directoryExists = ! onlyRecordFailures && directoryProbablyExists ( candidate , state . host ) ;
841
832
842
- if ( directoryExists && state . host . fileExists ( packageJsonPath ) ) {
843
- if ( state . traceEnabled ) {
844
- trace ( state . host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
845
- }
846
- const mainOrTypesFile = tryReadPackageJsonMainOrTypes ( extensions , packageJsonPath , candidate , state ) ;
847
- if ( mainOrTypesFile ) {
848
- const onlyRecordFailures = ! directoryProbablyExists ( getDirectoryPath ( mainOrTypesFile ) , state . host ) ;
849
- // A package.json "typings" may specify an exact filename, or may choose to omit an extension.
850
- const fromExactFile = tryFile ( mainOrTypesFile , failedLookupLocations , onlyRecordFailures , state ) ;
851
- if ( fromExactFile ) {
852
- const resolved = fromExactFile && resolvedIfExtensionMatches ( extensions , fromExactFile ) ;
853
- if ( resolved ) {
854
- return resolved ;
855
- }
856
- if ( state . traceEnabled ) {
857
- trace ( state . host , Diagnostics . File_0_has_an_unsupported_extension_so_skipping_it , fromExactFile ) ;
858
- }
859
- }
860
- const resolved = tryAddingExtensions ( mainOrTypesFile , Extensions . TypeScript , failedLookupLocations , onlyRecordFailures , state ) ;
861
- if ( resolved ) {
862
- return resolved ;
833
+ if ( considerPackageJson ) {
834
+ const packageJsonPath = pathToPackageJson ( candidate ) ;
835
+ if ( directoryExists && state . host . fileExists ( packageJsonPath ) ) {
836
+ const fromPackageJson = loadModuleFromPackageJson ( packageJsonPath , extensions , candidate , failedLookupLocations , state ) ;
837
+ if ( fromPackageJson ) {
838
+ return fromPackageJson ;
863
839
}
864
840
}
865
841
else {
866
- if ( state . traceEnabled ) {
867
- trace ( state . host , Diagnostics . package_json_does_not_have_a_types_or_main_field ) ;
842
+ if ( directoryExists && state . traceEnabled ) {
843
+ trace ( state . host , Diagnostics . File_0_does_not_exist , packageJsonPath ) ;
868
844
}
845
+ // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
846
+ failedLookupLocations . push ( packageJsonPath ) ;
869
847
}
870
848
}
871
- else {
872
- if ( directoryExists && state . traceEnabled ) {
873
- trace ( state . host , Diagnostics . File_0_does_not_exist , packageJsonPath ) ;
849
+
850
+ return loadModuleFromFile ( extensions , combinePaths ( candidate , "index" ) , failedLookupLocations , ! directoryExists , state ) ;
851
+ }
852
+
853
+ function loadModuleFromPackageJson ( packageJsonPath : string , extensions : Extensions , candidate : string , failedLookupLocations : Push < string > , state : ModuleResolutionState ) : Resolved | undefined {
854
+ if ( state . traceEnabled ) {
855
+ trace ( state . host , Diagnostics . Found_package_json_at_0 , packageJsonPath ) ;
856
+ }
857
+
858
+ const ts = extensions !== Extensions . JavaScript ;
859
+ const file = tryReadPackageJsonFields ( ts , packageJsonPath , candidate , state ) ;
860
+ if ( ! file ) {
861
+ return undefined ;
862
+ }
863
+
864
+ const onlyRecordFailures = ! directoryProbablyExists ( getDirectoryPath ( file ) , state . host ) ;
865
+ const fromFile = tryFile ( file , failedLookupLocations , onlyRecordFailures , state ) ;
866
+ if ( fromFile ) {
867
+ const resolved = fromFile && resolvedIfExtensionMatches ( extensions , fromFile ) ;
868
+ if ( resolved ) {
869
+ return resolved ;
870
+ }
871
+ if ( state . traceEnabled ) {
872
+ trace ( state . host , Diagnostics . File_0_has_an_unsupported_extension_so_skipping_it , fromFile ) ;
874
873
}
875
- // record package json as one of failed lookup locations - in the future if this file will appear it will invalidate resolution results
876
- failedLookupLocations . push ( packageJsonPath ) ;
877
874
}
878
875
879
- return loadModuleFromFile ( extensions , combinePaths ( candidate , "index" ) , failedLookupLocations , ! directoryExists , state ) ;
876
+ // Even if extensions is DtsOnly, we can still look up a .ts file as a result of package.json "types"
877
+ const nextExtensions = extensions === Extensions . DtsOnly ? Extensions . TypeScript : extensions ;
878
+ // Don't do package.json lookup recursively, because Node.js' package lookup doesn't.
879
+ return nodeLoadModuleByRelativeName ( nextExtensions , file , failedLookupLocations , onlyRecordFailures , state , /*considerPackageJson*/ false ) ;
880
880
}
881
881
882
882
/** Resolve from an arbitrarily specified file. Return `undefined` if it has an unsupported extension. */
@@ -1040,7 +1040,6 @@ namespace ts {
1040
1040
return value !== undefined ? { value } : undefined ;
1041
1041
}
1042
1042
1043
-
1044
1043
/** Calls `callback` on `directory` and every ancestor directory it has, returning the first defined result. */
1045
1044
function forEachAncestorDirectory < T > ( directory : string , callback : ( directory : string ) => SearchResult < T > ) : SearchResult < T > {
1046
1045
while ( true ) {
0 commit comments