Skip to content

Commit

Permalink
fix(resolve): try .tsx extension for .js import from typescript module (
Browse files Browse the repository at this point in the history
#7005)

Co-authored-by: Alec Larson <1925840+aleclarson@users.noreply.github.com>
  • Loading branch information
leebeydoun and aleclarson committed Mar 2, 2022
1 parent 5c8d98e commit 72b8cb6
Show file tree
Hide file tree
Showing 7 changed files with 82 additions and 15 deletions.
17 changes: 17 additions & 0 deletions packages/playground/resolve/index.html
Expand Up @@ -41,6 +41,17 @@ <h2>
</h2>
<p class="ts-extension">fail</p>

<h2>
A ts module can import another tsx module using its corresponding jsx file
name
</h2>
<p class="jsx-extension">fail</p>

<h2>
A ts module can import another tsx module using its corresponding js file name
</h2>
<p class="tsx-extension">fail</p>

<h2>Resolve file name containing dot</h2>
<p class="dot">fail</p>

Expand Down Expand Up @@ -137,6 +148,12 @@ <h2>resolve package that contains # in path</h2>
import { msg as tsExtensionMsg } from './ts-extension'
text('.ts-extension', tsExtensionMsg)

import { msgJsx as tsJsxExtensionMsg } from './ts-extension'
text('.jsx-extension', tsJsxExtensionMsg)

import { msgTsx as tsTsxExtensionMsg } from './ts-extension'
text('.tsx-extension', tsTsxExtensionMsg)

// filename with dot
import { bar } from './util/bar.util'
text('.dot', bar())
Expand Down
1 change: 1 addition & 0 deletions packages/playground/resolve/ts-extension/hellojsx.tsx
@@ -0,0 +1 @@
export const msgJsx = '[success] use .jsx extension to import a tsx module'
1 change: 1 addition & 0 deletions packages/playground/resolve/ts-extension/hellotsx.tsx
@@ -0,0 +1 @@
export const msgTsx = '[success] use .js extension to import a tsx module'
4 changes: 3 additions & 1 deletion packages/playground/resolve/ts-extension/index.ts
@@ -1,3 +1,5 @@
import { msg } from './hello.js'
import { msgJsx } from './hellojsx.jsx'
import { msgTsx } from './hellotsx.js'

export { msg }
export { msg, msgJsx, msgTsx }
38 changes: 37 additions & 1 deletion packages/vite/src/node/__tests__/utils.spec.ts
@@ -1,4 +1,4 @@
import { injectQuery, isWindows } from '../utils'
import { getPotentialTsSrcPaths, injectQuery, isWindows } from '../utils'

if (isWindows) {
// this test will work incorrectly on unix systems
Expand Down Expand Up @@ -38,3 +38,39 @@ test('path with unicode, space, and %', () => {
'/usr/vite/東京 %20 hello?direct'
)
})

test('ts import of file with .js extension', () => {
expect(getPotentialTsSrcPaths('test-file.js')).toEqual([
'test-file.ts',
'test-file.tsx'
])
})

test('ts import of file with .jsx extension', () => {
expect(getPotentialTsSrcPaths('test-file.jsx')).toEqual(['test-file.tsx'])
})

test('ts import of file .mjs,.cjs extension', () => {
expect(getPotentialTsSrcPaths('test-file.cjs')).toEqual([
'test-file.cts',
'test-file.ctsx'
])
expect(getPotentialTsSrcPaths('test-file.mjs')).toEqual([
'test-file.mts',
'test-file.mtsx'
])
})

test('ts import of file with .js before extension', () => {
expect(getPotentialTsSrcPaths('test-file.js.js')).toEqual([
'test-file.js.ts',
'test-file.js.tsx'
])
})

test('ts import of file with .js and query param', () => {
expect(getPotentialTsSrcPaths('test-file.js.js?lee=123')).toEqual([
'test-file.js.ts?lee=123',
'test-file.js.tsx?lee=123'
])
})
26 changes: 15 additions & 11 deletions packages/vite/src/node/plugins/resolve.ts
Expand Up @@ -27,7 +27,7 @@ import {
isFileReadable,
isTsRequest,
isPossibleTsOutput,
getTsSrcPath
getPotentialTsSrcPaths
} from '../utils'
import type { ViteDevServer, SSROptions } from '..'
import type { PartialResolvedId } from 'rollup'
Expand Down Expand Up @@ -436,16 +436,20 @@ function tryResolveFile(

const tryTsExtension = options.isFromTsImporter && isPossibleTsOutput(file)
if (tryTsExtension) {
const tsSrcPath = getTsSrcPath(file)
return tryResolveFile(
tsSrcPath,
postfix,
options,
tryIndex,
targetWeb,
tryPrefix,
skipPackageJson
)
const tsSrcPaths = getPotentialTsSrcPaths(file)
for (const srcPath of tsSrcPaths) {
const res = tryResolveFile(
srcPath,
postfix,
options,
tryIndex,
targetWeb,
tryPrefix,
skipPackageJson
)
if (res) return res
}
return
}

if (tryPrefix) {
Expand Down
10 changes: 8 additions & 2 deletions packages/vite/src/node/utils.ts
Expand Up @@ -189,8 +189,14 @@ const knownTsOutputRE = /\.(js|mjs|cjs|jsx)$/
export const isTsRequest = (url: string) => knownTsRE.test(cleanUrl(url))
export const isPossibleTsOutput = (url: string) =>
knownTsOutputRE.test(cleanUrl(url))
export const getTsSrcPath = (filename: string) =>
filename.replace(/\.([cm])?(js)(x?)(\?|$)/, '.$1ts$3')
export function getPotentialTsSrcPaths(filePath: string) {
const [name, type, query = ''] = filePath.split(/(\.(?:[cm]?js|jsx))(\?.*)?$/)
const paths = [name + type.replace('js', 'ts') + query]
if (!type.endsWith('x')) {
paths.push(name + type.replace('js', 'tsx') + query)
}
return paths
}

const importQueryRE = /(\?|&)import=?(?:&|$)/
const internalPrefixes = [
Expand Down

0 comments on commit 72b8cb6

Please sign in to comment.