From 089d36d167dc7834065b03ca689f9b6a44eead8a Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Sat, 21 Oct 2023 10:35:16 +0800 Subject: [PATCH] fix: correctly resolve types from relative paths on Windows (#9446) close #8671 close https://github.com/vuejs/vue-loader/issues/2048 --- .../compileScript/resolveType.spec.ts | 37 +++++++++++++++++-- .../compiler-sfc/src/script/resolveType.ts | 2 +- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts index 607654a952b..fc600f1a518 100644 --- a/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts +++ b/packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts @@ -1,3 +1,4 @@ +import { normalize } from 'node:path' import { Identifier } from '@babel/types' import { SFCScriptCompileOptions, parse } from '../../src' import { ScriptCompileContext } from '../../src/script/context' @@ -478,6 +479,33 @@ describe('resolveType', () => { 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

() + `, + files, + {}, + 'C:\\Test\\Test.vue' + ) + expect(props).toStrictEqual({ + foo: ['Number'], + bar: ['String'] + }) + expect(deps && [...deps].map(normalize)).toStrictEqual( + Object.keys(files).map(normalize) + ) + }) + // #8244 test('utility type in external file', () => { const files = { @@ -898,19 +926,20 @@ describe('resolveType', () => { function resolve( code: string, files: Record = {}, - options?: Partial + options?: Partial, + sourceFileName: string = '/Test.vue' ) { const { descriptor } = parse(``, { - filename: '/Test.vue' + filename: sourceFileName }) const ctx = new ScriptCompileContext(descriptor, { id: 'test', fs: { fileExists(file) { - return !!files[file] + return !!(files[file] ?? files[normalize(file)]) }, readFile(file) { - return files[file] + return files[file] ?? files[normalize(file)] } }, ...options diff --git a/packages/compiler-sfc/src/script/resolveType.ts b/packages/compiler-sfc/src/script/resolveType.ts index 78581432366..215081dc0b7 100644 --- a/packages/compiler-sfc/src/script/resolveType.ts +++ b/packages/compiler-sfc/src/script/resolveType.ts @@ -778,7 +778,7 @@ function importSourceToScope( if (!resolved) { if (source.startsWith('.')) { // relative import - fast path - const filename = joinPaths(scope.filename, '..', source) + const filename = joinPaths(dirname(scope.filename), source) resolved = resolveExt(filename, fs) } else { // module or aliased import - use full TS resolution, only supported in Node