]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-sfc): expose type import deps on compiled script block
authorEvan You <yyx990803@gmail.com>
Sat, 15 Apr 2023 10:06:48 +0000 (18:06 +0800)
committerEvan You <yyx990803@gmail.com>
Sat, 15 Apr 2023 14:08:39 +0000 (22:08 +0800)
packages/compiler-sfc/__tests__/compileScript/resolveType.spec.ts
packages/compiler-sfc/src/compileScript.ts
packages/compiler-sfc/src/script/context.ts
packages/compiler-sfc/src/script/resolveType.ts

index 6f07cfcfab4e38ecd04bb0aa617ae13343fbc784..a6aad1ea197109d9d32f31e83888e04f53730db5 100644 (file)
@@ -264,81 +264,85 @@ describe('resolveType', () => {
   })
 
   describe('external type imports', () => {
+    const files = {
+      '/foo.ts': 'export type P = { foo: number }',
+      '/bar.d.ts': 'type X = { bar: string }; export { X as Y }'
+    }
     test('relative ts', () => {
-      expect(
-        resolve(
-          `
+      const { props, deps } = resolve(
+        `
         import { P } from './foo'
         import { Y as PP } from './bar'
         defineProps<P & PP>()
-        `,
-          {
-            '/foo.ts': 'export type P = { foo: number }',
-            '/bar.d.ts': 'type X = { bar: string }; export { X as Y }'
-          }
-        ).props
-      ).toStrictEqual({
+      `,
+        files
+      )
+      expect(props).toStrictEqual({
         foo: ['Number'],
         bar: ['String']
       })
+      expect(deps && [...deps]).toStrictEqual(Object.keys(files))
     })
 
     test('relative vue', () => {
-      expect(
-        resolve(
-          `
+      const files = {
+        '/foo.vue':
+          '<script lang="ts">export type P = { foo: number }</script>',
+        '/bar.vue':
+          '<script setup lang="tsx">export type P = { bar: string }</script>'
+      }
+      const { props, deps } = resolve(
+        `
         import { P } from './foo.vue'
         import { P as PP } from './bar.vue'
         defineProps<P & PP>()
-        `,
-          {
-            '/foo.vue':
-              '<script lang="ts">export type P = { foo: number }</script>',
-            '/bar.vue':
-              '<script setup lang="tsx">export type P = { bar: string }</script>'
-          }
-        ).props
-      ).toStrictEqual({
+      `,
+        files
+      )
+      expect(props).toStrictEqual({
         foo: ['Number'],
         bar: ['String']
       })
+      expect(deps && [...deps]).toStrictEqual(Object.keys(files))
     })
 
     test('relative (chained)', () => {
-      expect(
-        resolve(
-          `
+      const files = {
+        '/foo.ts': `import type { P as PP } from './nested/bar.vue'
+          export type P = { foo: number } & PP`,
+        '/nested/bar.vue':
+          '<script setup lang="ts">export type P = { bar: string }</script>'
+      }
+      const { props, deps } = resolve(
+        `
         import { P } from './foo'
         defineProps<P>()
-        `,
-          {
-            '/foo.ts': `import type { P as PP } from './nested/bar.vue'
-              export type P = { foo: number } & PP`,
-            '/nested/bar.vue':
-              '<script setup lang="ts">export type P = { bar: string }</script>'
-          }
-        ).props
-      ).toStrictEqual({
+      `,
+        files
+      )
+      expect(props).toStrictEqual({
         foo: ['Number'],
         bar: ['String']
       })
+      expect(deps && [...deps]).toStrictEqual(Object.keys(files))
     })
 
     test('relative (chained, re-export)', () => {
-      expect(
-        resolve(
-          `
+      const files = {
+        '/foo.ts': `export { P as PP } from './bar'`,
+        '/bar.ts': 'export type P = { bar: string }'
+      }
+      const { props, deps } = resolve(
+        `
         import { PP as P } from './foo'
         defineProps<P>()
-        `,
-          {
-            '/foo.ts': `export { P as PP } from './bar'`,
-            '/bar.ts': 'export type P = { bar: string }'
-          }
-        ).props
-      ).toStrictEqual({
+      `,
+        files
+      )
+      expect(props).toStrictEqual({
         bar: ['String']
       })
+      expect(deps && [...deps]).toStrictEqual(Object.keys(files))
     })
 
     test('ts module resolve', () => {
@@ -357,7 +361,7 @@ describe('resolveType', () => {
         '/pp.ts': 'export type PP = { bar: string }'
       }
 
-      const { props } = resolve(
+      const { props, deps } = resolve(
         `
         import { P } from 'foo'
         import { PP } from 'bar'
@@ -370,6 +374,10 @@ describe('resolveType', () => {
         foo: ['Number'],
         bar: ['String']
       })
+      expect(deps && [...deps]).toStrictEqual([
+        '/node_modules/foo/index.d.ts',
+        '/pp.ts'
+      ])
     })
   })
 
@@ -447,6 +455,6 @@ function resolve(code: string, files: Record<string, string> = {}) {
   return {
     props,
     calls: raw.calls,
-    raw
+    deps: ctx.deps
   }
 }
index c561a77a49d556e7272e9f9f9fb6a094fe40863e..e5e1bea4fd1acfa4f9b234dd1834f10cfea51c33 100644 (file)
@@ -1035,7 +1035,8 @@ export function compileScript(
           }) as unknown as RawSourceMap)
         : undefined,
     scriptAst: scriptAst?.body,
-    scriptSetupAst: scriptSetupAst?.body
+    scriptSetupAst: scriptSetupAst?.body,
+    deps: ctx.deps ? [...ctx.deps] : undefined
   }
 }
 
index 1f96584507b4cba564dad2c959ad8cb8cac30a15..9141b95c572b255ec76714d8c6414613ff98d37a 100644 (file)
@@ -65,7 +65,7 @@ export class ScriptCompileContext {
   /**
    * to be exposed on compiled script block for HMR cache busting
    */
-  deps?: string[]
+  deps?: Set<string>
 
   constructor(
     public descriptor: SFCDescriptor,
index bbbbd4c5bc0ba667f37223e1b94aab9a512592a7..d5661c871aa09be0382dc8ad397351ef3fdaaf70 100644 (file)
@@ -547,7 +547,9 @@ function resolveTypeFromImport(
   }
 
   if (resolved) {
-    // TODO (hmr) register dependency file on ctx
+    // (hmr) register dependency file on ctx
+    ;(ctx.deps || (ctx.deps = new Set())).add(resolved)
+
     return resolveTypeReference(
       ctx,
       node,