diff --git a/packages/runtime-core/__tests__/hydration.spec.ts b/packages/runtime-core/__tests__/hydration.spec.ts index 1c27f321ec8..20519cf997f 100644 --- a/packages/runtime-core/__tests__/hydration.spec.ts +++ b/packages/runtime-core/__tests__/hydration.spec.ts @@ -1880,6 +1880,26 @@ describe('SSR hydration', () => { expect(root.innerHTML).toBe('
bar
') }) + test('hmr root reload', async () => { + const appId = 'test-app-id' + const App = { + __hmrId: appId, + template: `
foo
`, + } + + const root = document.createElement('div') + root.innerHTML = await renderToString(h(App)) + createSSRApp(App).mount(root) + expect(root.innerHTML).toBe('
foo
') + + reload(appId, { + __hmrId: appId, + template: `
bar
`, + }) + await nextTick() + expect(root.innerHTML).toBe('
bar
') + }) + describe('mismatch handling', () => { test('text node', () => { const { container } = mountWithHydration(`foo`, () => 'bar') diff --git a/packages/runtime-core/src/apiCreateApp.ts b/packages/runtime-core/src/apiCreateApp.ts index 748de866f75..cba5e4ede02 100644 --- a/packages/runtime-core/src/apiCreateApp.ts +++ b/packages/runtime-core/src/apiCreateApp.ts @@ -383,13 +383,12 @@ export function createAppAPI( // 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) } }