]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: test hmr updating
authordaiwei <daiwei521@126.com>
Tue, 25 Mar 2025 09:21:50 +0000 (17:21 +0800)
committerdaiwei <daiwei521@126.com>
Tue, 25 Mar 2025 09:21:50 +0000 (17:21 +0800)
packages/runtime-core/src/hmr.ts
packages/runtime-vapor/__tests__/components/Teleport.spec.ts
packages/runtime-vapor/src/block.ts
packages/runtime-vapor/src/components/Teleport.ts
packages/runtime-vapor/src/hmr.ts

index ed5d8b081a0ff8d9eddc149f21d37938501e9c59..acc9593d1375e36b6620dece1f2419aa9347a55c 100644 (file)
@@ -119,7 +119,7 @@ function reload(id: string, newComp: HMRComponent): void {
   // create a snapshot which avoids the set being mutated during updates
   const instances = [...record.instances]
 
-  if (newComp.vapor) {
+  if (newComp.__vapor) {
     for (const instance of instances) {
       instance.hmrReload!(newComp)
     }
index 27c1682fa4f3d42669719cf1cc02291c0c3afd3d..cae00f75fd7223c2dd7d442b9ea2b59b3883afbd 100644 (file)
@@ -1,7 +1,7 @@
 import {
   type LooseRawProps,
   type VaporComponent,
-  createComponent as originalCreateComponent,
+  createComponent as createComp,
 } from '../../src/component'
 import {
   type VaporDirective,
@@ -12,7 +12,6 @@ import {
   template,
   withVaporDirectives,
 } from '@vue/runtime-vapor'
-
 import { makeRender } from '../_utils'
 import {
   nextTick,
@@ -23,6 +22,10 @@ import {
   shallowRef,
 } from 'vue'
 
+import type { HMRRuntime } from '@vue/runtime-dom'
+declare var __VUE_HMR_RUNTIME__: HMRRuntime
+const { createRecord, rerender, reload } = __VUE_HMR_RUNTIME__
+
 const define = makeRender()
 
 describe('renderer: VaporTeleport', () => {
@@ -33,6 +36,141 @@ describe('renderer: VaporTeleport', () => {
   describe('defer mode', () => {
     runSharedTests(true)
   })
+
+  describe('HMR', () => {
+    test('rerender', async () => {
+      const target = document.createElement('div')
+      const root = document.createElement('div')
+      const childId = 'test1-child'
+      const parentId = 'test1-parent'
+
+      const { component: Child } = define({
+        __hmrId: childId,
+        render() {
+          return template('<div>teleported</div>')()
+        },
+      })
+      createRecord(childId, Child as any)
+
+      const { mount, component: Parent } = define({
+        __hmrId: parentId,
+        render() {
+          const n0 = createComp(
+            VaporTeleport,
+            {
+              to: () => target,
+            },
+            {
+              default: () => createComp(Child),
+            },
+          )
+          const n1 = template('<div>root</div>')()
+          return [n0, n1]
+        },
+      }).create()
+      createRecord(parentId, Parent as any)
+      mount(root)
+
+      expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
+      expect(target.innerHTML).toBe('<div>teleported</div>')
+
+      // rerender child
+      rerender(childId, () => {
+        return template('<div>teleported 2</div>')()
+      })
+
+      expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
+      expect(target.innerHTML).toBe('<div>teleported 2</div>')
+
+      // rerender parent
+      rerender(parentId, () => {
+        const n0 = createComp(
+          VaporTeleport,
+          {
+            to: () => target,
+          },
+          {
+            default: () => createComp(Child),
+          },
+        )
+        const n1 = template('<div>root 2</div>')()
+        return [n0, n1]
+      })
+
+      expect(root.innerHTML).toBe('<!--teleport--><div>root 2</div>')
+      expect(target.innerHTML).toBe('<div>teleported 2</div>')
+    })
+
+    test('reload', async () => {
+      const target = document.createElement('div')
+      const root = document.createElement('div')
+      const childId = 'test2-child'
+      const parentId = 'test2-parent'
+
+      const { component: Child } = define({
+        __hmrId: childId,
+        render() {
+          return template('<div>teleported</div>')()
+        },
+      })
+      createRecord(childId, Child as any)
+
+      const { mount, component: Parent } = define({
+        __hmrId: parentId,
+        render() {
+          const n0 = createComp(
+            VaporTeleport,
+            {
+              to: () => target,
+            },
+            {
+              default: () => createComp(Child),
+            },
+          )
+          const n1 = template('<div>root</div>')()
+          return [n0, n1]
+        },
+      }).create()
+      createRecord(parentId, Parent as any)
+      mount(root)
+
+      expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
+      expect(target.innerHTML).toBe('<div>teleported</div>')
+
+      // reload child
+      reload(childId, {
+        __hmrId: childId,
+        __vapor: true,
+        render() {
+          return template('<div>teleported 2</div>')()
+        },
+      })
+      expect(root.innerHTML).toBe('<!--teleport--><div>root</div>')
+      expect(target.innerHTML).toBe('<div>teleported 2</div>')
+
+      // reload parent
+      reload(parentId, {
+        __hmrId: parentId,
+        __vapor: true,
+        render() {
+          const n0 = createComp(
+            VaporTeleport,
+            {
+              to: () => target,
+            },
+            {
+              default: () => createComp(Child),
+            },
+          )
+          const n1 = template('<div>root 2</div>')()
+          return [n0, n1]
+        },
+      })
+
+      expect(root.innerHTML).toBe('<!--teleport--><div>root 2</div>')
+      expect(target.innerHTML).toBe('<div>teleported 2</div>')
+    })
+  })
 })
 
 function runSharedTests(deferMode: boolean): void {
@@ -45,9 +183,9 @@ function runSharedTests(deferMode: boolean): void {
         if (component === VaporTeleport) {
           rawProps!.defer = () => true
         }
-        return originalCreateComponent(component, rawProps, ...args)
+        return createComp(component, rawProps, ...args)
       }
-    : originalCreateComponent
+    : createComp
 
   test('should work', () => {
     const target = document.createElement('div')
index 6ec62da20d517fbfac9c238922afa996735383d6..17ae7190923bb8315a56f1034cd722c804ed026f 100644 (file)
@@ -184,7 +184,11 @@ export function normalizeBlock(block: Block): Node[] {
   } else if (isVaporComponent(block)) {
     nodes.push(...normalizeBlock(block.block!))
   } else {
-    nodes.push(...normalizeBlock(block.nodes))
+    if ((block as any).getNodes) {
+      nodes.push(...normalizeBlock((block as any).getNodes()))
+    } else {
+      nodes.push(...normalizeBlock(block.nodes))
+    }
     block.anchor && nodes.push(block.anchor)
   }
   return nodes
index 8a036578204adb9a48b21eda4f8f4240310d6ef4..6c0b089bf0048755a12185035132f902bb35d012 100644 (file)
@@ -54,6 +54,13 @@ export const VaporTeleportImpl = {
     })
     resetTracking()
 
+    if (__DEV__) {
+      // TODO
+      ;(frag as any).getNodes = () => {
+        return frag.parent !== frag.currentParent ? [] : frag.nodes
+      }
+    }
+
     return frag
   },
 }
index c960a2610cf8b065e6aba5eee263d8c2645a2de5..5df5d2a469d549b16b04c485453c21d01bf9ce2e 100644 (file)
@@ -54,4 +54,5 @@ export function hmrReload(
   )
   simpleSetCurrentInstance(prev, instance.parent)
   mountComponent(newInstance, parent, anchor)
+  instance.block = newInstance.block
 }