@@ -13,9 +13,11 @@ import { logger } from './logger'
1313
1414import type { InternalResolverOptions , Matcher } from './types'
1515import type { Resolver } from 'enhanced-resolve'
16+ import type { TsConfigResult } from 'get-tsconfig'
1617import type { Version } from 'is-bun-module'
1718
18- const fileTsConfigCache = new Map ( )
19+ const fileTsJsConfigCache : Map < string , TsConfigResult > = new Map ( )
20+ const possiblePathsBySpecifier : Map < { specifier : string ; configPath : TsConfigResult [ 'path' ] } , string [ ] > = new Map ( )
1921
2022/**
2123 * Resolve an import specifier to a path
@@ -122,68 +124,74 @@ function getMappedPath(
122124
123125 extensions = [ '' , ...extensions ]
124126
125- let paths : string [ ] = [ ]
126-
127127 if ( RELATIVE_PATH_PATTERN . test ( specifier ) ) {
128128 const resolved = path . resolve ( path . dirname ( file ) , specifier )
129129 if ( isFile ( resolved ) ) {
130- paths = [ resolved ]
130+ return resolved
131131 }
132- } else {
133- let projectConfig
134- const isJsconfig = currentMatchersOfCwd . every ( ( mapper ) => mapper . path . includes ( 'jsconfig' ) )
132+ }
135133
136- const fromCache = fileTsConfigCache . get ( file )
134+ let paths : string [ ] = [ ]
137135
138- if ( fromCache ) {
139- projectConfig = fromCache
140- } else {
141- projectConfig = getTsconfig ( file , isJsconfig ? 'jsconfig.json' : 'tsconfig.json' )
142- }
136+ let projectConfig : TsConfigResult | null = null
143137
144- if ( projectConfig ) logger ( 'project config by file path:' , projectConfig ?. path )
138+ const { ext } = path . parse ( file )
145139
146- const closestMapper = currentMatchersOfCwd ?. find ( ( mapper ) => {
147- return mapper . path === projectConfig ?. path
148- } )
140+ const fromCache = fileTsJsConfigCache . get ( file )
149141
150- if ( closestMapper ) {
151- logger ( 'found closest mapper by config path:' , closestMapper . path )
152- }
142+ if ( fromCache ) {
143+ projectConfig = fromCache
144+ } else {
145+ projectConfig = getTsconfig ( file , ext . includes ( 'js' ) ? 'jsconfig.json' : 'tsconfig.json' )
146+ if ( projectConfig ) fileTsJsConfigCache . set ( file , projectConfig )
147+ }
153148
154- const possiblePaths = (
155- closestMapper
156- ? closestMapper . matcher ( specifier )
157- : currentMatchersOfCwd . map ( ( mapper ) => mapper ?. matcher ( specifier ) ) . flat ( )
158- )
159- . map ( ( item ) => [
160- ...extensions . map ( ( ext ) => `${ item } ${ ext } ` ) ,
161- ...originalExtensions . map ( ( ext ) => `${ item } /index${ ext } ` ) ,
162- ] )
163- . flat ( )
164-
165- logger ( 'possible paths:' , possiblePaths )
166-
167- paths = possiblePaths . filter ( ( mappedPath ) => {
168- try {
169- const stat = fs . statSync ( mappedPath , { throwIfNoEntry : false } )
170- if ( stat === undefined ) return false
171- if ( stat . isFile ( ) ) return true
172- if ( stat . isDirectory ( ) ) {
173- return isModule ( mappedPath )
174- }
175- } catch {
176- return false
177- }
149+ if ( projectConfig ) logger ( 'project config by file path:' , projectConfig ?. path )
178150
179- return false
180- } )
151+ const closestMapper = currentMatchersOfCwd ?. find ( ( mapper ) => {
152+ return mapper . path === projectConfig ?. path
153+ } )
181154
182- logger ( 'paths' , paths )
155+ if ( closestMapper ) {
156+ logger ( 'found closest mapper by config path:' , closestMapper . path )
183157 }
184158
159+ const possiblePaths = (
160+ closestMapper
161+ ? closestMapper . matcher ( specifier )
162+ : currentMatchersOfCwd . map ( ( mapper ) => mapper ?. matcher ( specifier ) ) . flat ( )
163+ )
164+ . map ( ( item ) => [
165+ ...extensions . map ( ( ext ) => `${ item } ${ ext } ` ) ,
166+ ...originalExtensions . map ( ( ext ) => `${ item } /index${ ext } ` ) ,
167+ ] )
168+ . flat ( )
169+
170+ logger ( 'possible paths:' , possiblePaths )
171+
172+ paths = projectConfig ?. path
173+ ? ( possiblePathsBySpecifier . get ( { specifier, configPath : projectConfig . path } ) ?? [ ] )
174+ : possiblePaths . filter ( ( mappedPath ) => {
175+ try {
176+ const stat = fs . statSync ( mappedPath , { throwIfNoEntry : false } )
177+ if ( stat === undefined ) return false
178+ if ( stat . isFile ( ) ) return true
179+ if ( stat . isDirectory ( ) ) {
180+ return isModule ( mappedPath )
181+ }
182+ } catch {
183+ return false
184+ }
185+
186+ return false
187+ } )
188+
189+ if ( projectConfig ?. path ) possiblePathsBySpecifier . set ( { specifier, configPath : projectConfig . path } , paths )
190+
185191 if ( paths . length > 1 ) {
186- logger ( 'found multiple matching ts paths:' , paths )
192+ logger ( 'found multiple matching paths:' , paths )
193+ } else {
194+ logger ( 'found matching paths:' , paths )
187195 }
188196
189197 return paths [ 0 ]
0 commit comments