Parcourir la source

fix(hmr): avoid hydration for hmr root reload (#12450)

close vitejs/vite-plugin-vue#146
close vitejs/vite-plugin-vue#477
edison il y a 11 mois
Parent
commit
1f98a9c493

+ 20 - 0
packages/runtime-core/__tests__/hydration.spec.ts

@@ -1880,6 +1880,26 @@ describe('SSR hydration', () => {
     expect(root.innerHTML).toBe('<div><div>bar</div></div>')
   })
 
+  test('hmr root reload', async () => {
+    const appId = 'test-app-id'
+    const App = {
+      __hmrId: appId,
+      template: `<div>foo</div>`,
+    }
+
+    const root = document.createElement('div')
+    root.innerHTML = await renderToString(h(App))
+    createSSRApp(App).mount(root)
+    expect(root.innerHTML).toBe('<div>foo</div>')
+
+    reload(appId, {
+      __hmrId: appId,
+      template: `<div>bar</div>`,
+    })
+    await nextTick()
+    expect(root.innerHTML).toBe('<div>bar</div>')
+  })
+
   describe('mismatch handling', () => {
     test('text node', () => {
       const { container } = mountWithHydration(`foo`, () => 'bar')

+ 4 - 5
packages/runtime-core/src/apiCreateApp.ts

@@ -383,13 +383,12 @@ export function createAppAPI<HostElement>(
           // HMR root reload
           if (__DEV__) {
             context.reload = () => {
+              const cloned = cloneVNode(vnode)
+              // avoid hydration for hmr updating
+              cloned.el = null
               // casting to ElementNamespace because TS doesn't guarantee type narrowing
               // over function boundaries
-              render(
-                cloneVNode(vnode),
-                rootContainer,
-                namespace as ElementNamespace,
-              )
+              render(cloned, rootContainer, namespace as ElementNamespace)
             }
           }