@@ -89,11 +89,9 @@ namespace ts.moduleSpecifiers {
89
89
}
90
90
91
91
const importRelativeToBaseUrl = removeExtensionAndIndexPostFix ( relativeToBaseUrl , moduleResolutionKind , addJsExtension ) ;
92
- if ( paths ) {
93
- const fromPaths = tryGetModuleNameFromPaths ( removeFileExtension ( relativeToBaseUrl ) , importRelativeToBaseUrl , paths ) ;
94
- if ( fromPaths ) {
95
- return [ fromPaths ] ;
96
- }
92
+ const fromPaths = paths && tryGetModuleNameFromPaths ( removeFileExtension ( relativeToBaseUrl ) , importRelativeToBaseUrl , paths ) ;
93
+ if ( fromPaths ) {
94
+ return [ fromPaths ] ;
97
95
}
98
96
99
97
if ( preferences . importModuleSpecifierPreference === "non-relative" ) {
@@ -106,38 +104,19 @@ namespace ts.moduleSpecifiers {
106
104
return [ relativePath ] ;
107
105
}
108
106
109
- /*
110
- Prefer a relative import over a baseUrl import if it doesn't traverse up to baseUrl.
111
-
112
- Suppose we have:
113
- baseUrl = /base
114
- sourceDirectory = /base/a/b
115
- moduleFileName = /base/foo/bar
116
- Then:
117
- relativePath = ../../foo/bar
118
- getRelativePathNParents(relativePath) = 2
119
- pathFromSourceToBaseUrl = ../../
120
- getRelativePathNParents(pathFromSourceToBaseUrl) = 2
121
- 2 < 2 = false
122
- In this case we should prefer using the baseUrl path "/a/b" instead of the relative path "../../foo/bar".
123
-
124
- Suppose we have:
125
- baseUrl = /base
126
- sourceDirectory = /base/foo/a
127
- moduleFileName = /base/foo/bar
128
- Then:
129
- relativePath = ../a
130
- getRelativePathNParents(relativePath) = 1
131
- pathFromSourceToBaseUrl = ../../
132
- getRelativePathNParents(pathFromSourceToBaseUrl) = 2
133
- 1 < 2 = true
134
- In this case we should prefer using the relative path "../a" instead of the baseUrl path "foo/a".
135
- */
136
- const pathFromSourceToBaseUrl = ensurePathIsNonModuleName ( getRelativePathFromDirectory ( sourceDirectory , baseUrl , getCanonicalFileName ) ) ;
137
- const relativeFirst = getRelativePathNParents ( relativePath ) < getRelativePathNParents ( pathFromSourceToBaseUrl ) ;
107
+ // Prefer a relative import over a baseUrl import if it has fewer components.
108
+ const relativeFirst = countPathComponents ( relativePath ) < countPathComponents ( importRelativeToBaseUrl ) ;
138
109
return relativeFirst ? [ relativePath , importRelativeToBaseUrl ] : [ importRelativeToBaseUrl , relativePath ] ;
139
110
}
140
111
112
+ function countPathComponents ( path : string ) : number {
113
+ let count = 0 ;
114
+ for ( let i = startsWith ( path , "./" ) ? 2 : 0 ; i < path . length ; i ++ ) {
115
+ if ( path . charCodeAt ( i ) === CharacterCodes . slash ) count ++ ;
116
+ }
117
+ return count ;
118
+ }
119
+
141
120
function usesJsExtensionOnImports ( { imports } : SourceFile ) : boolean {
142
121
return firstDefined ( imports , ( { text } ) => pathIsRelative ( text ) ? fileExtensionIs ( text , Extension . Js ) : undefined ) || false ;
143
122
}
@@ -197,15 +176,6 @@ namespace ts.moduleSpecifiers {
197
176
return symlinks . length === 0 ? getAllModulePathsUsingIndirectSymlinks ( files , getNormalizedAbsolutePath ( importedFileName , host . getCurrentDirectory ? host . getCurrentDirectory ( ) : "" ) , getCanonicalFileName , host ) : symlinks ;
198
177
}
199
178
200
- function getRelativePathNParents ( relativePath : string ) : number {
201
- const components = getPathComponents ( relativePath ) ;
202
- if ( components [ 0 ] || components . length === 1 ) return 0 ;
203
- for ( let i = 1 ; i < components . length ; i ++ ) {
204
- if ( components [ i ] !== ".." ) return i - 1 ;
205
- }
206
- return components . length - 1 ;
207
- }
208
-
209
179
function tryGetModuleNameFromAmbientModule ( moduleSymbol : Symbol ) : string | undefined {
210
180
const decl = moduleSymbol . valueDeclaration ;
211
181
if ( isModuleDeclaration ( decl ) && isStringLiteral ( decl . name ) ) {
0 commit comments