]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix: correctly resolve types from relative paths on Windows (#9446)
authorHaoqun Jiang <haoqunjiang@gmail.com>
Sat, 21 Oct 2023 02:35:16 +0000 (10:35 +0800)
committerGitHub <noreply@github.com>
Sat, 21 Oct 2023 02:35:16 +0000 (10:35 +0800)
close #8671
close https://github.com/vuejs/vue-loader/issues/2048

packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
packages/compiler-sfc/src/script/resolveType.ts

index 607654a952bbf2e9778358be47896aa828db9fc7..fc600f1a51873e296ec63561bf8c56b0ad1298f6 100644 (file)
@@ -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<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
     test('utility type in external file', () => {
       const files = {
@@ -898,19 +926,20 @@ describe('resolveType', () => {
 function resolve(
   code: 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>`, {
-    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
index 78581432366559e7cf7fdce55f3b017083ad7c48..215081dc0b76477e50c218855f83dfa346116100 100644 (file)
@@ -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