fix: correctly resolve types from relative paths on Windows (#9446)

close #8671
close https://github.com/vuejs/vue-loader/issues/2048
This commit is contained in:
Haoqun Jiang 2023-10-21 10:35:16 +08:00 committed by GitHub
parent e9e2778e9e
commit 089d36d167
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 34 additions and 5 deletions

View File

@ -1,3 +1,4 @@
import { normalize } from 'node:path'
import { Identifier } from '@babel/types' import { Identifier } from '@babel/types'
import { SFCScriptCompileOptions, parse } from '../../src' import { SFCScriptCompileOptions, parse } from '../../src'
import { ScriptCompileContext } from '../../src/script/context' import { ScriptCompileContext } from '../../src/script/context'
@ -478,6 +479,33 @@ describe('resolveType', () => {
expect(deps && [...deps]).toStrictEqual(Object.keys(files)) expect(deps && [...deps]).toStrictEqual(Object.keys(files))
}) })
test.runIf(process.platform === 'win32')('relative ts on Windows', () => {
const files = {
'C:\\Test\\foo.ts': 'export type P = { foo: number }',
'C:\\Test\\bar.d.ts':
'type X = { bar: string }; export { X as Y };' +
// verify that we can parse syntax that is only valid in d.ts
'export const baz: boolean'
}
const { props, deps } = resolve(
`
import { P } from './foo'
import { Y as PP } from './bar'
defineProps<P & PP>()
`,
files,
{},
'C:\\Test\\Test.vue'
)
expect(props).toStrictEqual({
foo: ['Number'],
bar: ['String']
})
expect(deps && [...deps].map(normalize)).toStrictEqual(
Object.keys(files).map(normalize)
)
})
// #8244 // #8244
test('utility type in external file', () => { test('utility type in external file', () => {
const files = { const files = {
@ -898,19 +926,20 @@ describe('resolveType', () => {
function resolve( function resolve(
code: string, code: string,
files: Record<string, string> = {}, files: Record<string, string> = {},
options?: Partial<SFCScriptCompileOptions> options?: Partial<SFCScriptCompileOptions>,
sourceFileName: string = '/Test.vue'
) { ) {
const { descriptor } = parse(`<script setup lang="ts">\n${code}\n</script>`, { const { descriptor } = parse(`<script setup lang="ts">\n${code}\n</script>`, {
filename: '/Test.vue' filename: sourceFileName
}) })
const ctx = new ScriptCompileContext(descriptor, { const ctx = new ScriptCompileContext(descriptor, {
id: 'test', id: 'test',
fs: { fs: {
fileExists(file) { fileExists(file) {
return !!files[file] return !!(files[file] ?? files[normalize(file)])
}, },
readFile(file) { readFile(file) {
return files[file] return files[file] ?? files[normalize(file)]
} }
}, },
...options ...options

View File

@ -778,7 +778,7 @@ function importSourceToScope(
if (!resolved) { if (!resolved) {
if (source.startsWith('.')) { if (source.startsWith('.')) {
// relative import - fast path // relative import - fast path
const filename = joinPaths(scope.filename, '..', source) const filename = joinPaths(dirname(scope.filename), source)
resolved = resolveExt(filename, fs) resolved = resolveExt(filename, fs)
} else { } else {
// module or aliased import - use full TS resolution, only supported in Node // module or aliased import - use full TS resolution, only supported in Node