@@ -25,7 +25,10 @@ import {
25
25
cleanUrl ,
26
26
slash ,
27
27
nestedResolveFrom ,
28
- isFileReadable
28
+ isFileReadable ,
29
+ isTsRequest ,
30
+ isPossibleTsOutput ,
31
+ getTsSrcPath
29
32
} from '../utils'
30
33
import { ViteDevServer , SSROptions } from '..'
31
34
import { createFilter } from '@rollup/pluginutils'
@@ -65,6 +68,11 @@ export interface InternalResolveOptions extends ResolveOptions {
65
68
skipPackageJson ?: boolean
66
69
preferRelative ?: boolean
67
70
isRequire ?: boolean
71
+ // #3040
72
+ // when the importer is a ts module,
73
+ // if the specifier requests a non-existent `.js/jsx/mjs/cjs` file,
74
+ // should also try import from `.ts/tsx/mts/cts` source file as fallback,
75
+ isFromTsImporter ?: boolean
68
76
}
69
77
70
78
export function resolvePlugin ( baseOptions : InternalResolveOptions ) : Plugin {
@@ -75,10 +83,6 @@ export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin {
75
83
ssrConfig,
76
84
preferRelative = false
77
85
} = baseOptions
78
- const requireOptions : InternalResolveOptions = {
79
- ...baseOptions ,
80
- isRequire : true
81
- }
82
86
let server : ViteDevServer | undefined
83
87
84
88
const { target : ssrTarget , noExternal : ssrNoExternal } = ssrConfig ?? { }
@@ -104,13 +108,19 @@ export function resolvePlugin(baseOptions: InternalResolveOptions): Plugin {
104
108
const targetWeb = ! ssr || ssrTarget === 'webworker'
105
109
106
110
// this is passed by @rollup /plugin-commonjs
107
- const isRequire =
111
+ const isRequire = ! ! (
108
112
resolveOpts &&
109
113
resolveOpts . custom &&
110
114
resolveOpts . custom [ 'node-resolve' ] &&
111
115
resolveOpts . custom [ 'node-resolve' ] . isRequire
116
+ )
112
117
113
- const options = isRequire ? requireOptions : baseOptions
118
+ const options : InternalResolveOptions = {
119
+ ...baseOptions ,
120
+
121
+ isRequire,
122
+ isFromTsImporter : isTsRequest ( importer ?? '' )
123
+ }
114
124
115
125
const preserveSymlinks = ! ! server ?. config . resolve . preserveSymlinks
116
126
@@ -450,6 +460,22 @@ function tryResolveFile(
450
460
if ( index ) return index + postfix
451
461
}
452
462
}
463
+
464
+ const tryTsExtension = options . isFromTsImporter && isPossibleTsOutput ( file )
465
+ if ( tryTsExtension ) {
466
+ const tsSrcPath = getTsSrcPath ( file )
467
+ return tryResolveFile (
468
+ tsSrcPath ,
469
+ postfix ,
470
+ options ,
471
+ tryIndex ,
472
+ targetWeb ,
473
+ preserveSymlinks ,
474
+ tryPrefix ,
475
+ skipPackageJson
476
+ )
477
+ }
478
+
453
479
if ( tryPrefix ) {
454
480
const prefixed = `${ path . dirname ( file ) } /${ tryPrefix } ${ path . basename ( file ) } `
455
481
return tryResolveFile (
0 commit comments