]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(ssr): fix hydration mismatch when entire multi-root template is stringified
authorEvan You <yyx990803@gmail.com>
Wed, 28 Sep 2022 01:33:17 +0000 (09:33 +0800)
committerEvan You <yyx990803@gmail.com>
Wed, 28 Sep 2022 01:33:17 +0000 (09:33 +0800)
fix #6637

packages/runtime-core/__tests__/hydration.spec.ts
packages/runtime-core/src/hydration.ts

index 17ffbb40092bb82c21b0beafc1fda116c65ab978..493405b8ab8247befd52dc083bf994cb5d2eadff 100644 (file)
@@ -982,6 +982,14 @@ describe('SSR hydration', () => {
     expect((container as any)._vnode).toBe(null)
   })
 
+  // #6637
+  test('stringified root fragment', () => {
+    mountWithHydration(`<!--[--><div></div><!--]-->`, () =>
+      createStaticVNode(`<div></div>`, 1)
+    )
+    expect(`mismatch`).not.toHaveBeenWarned()
+  })
+
   describe('mismatch handling', () => {
     test('text node', () => {
       const { container } = mountWithHydration(`foo`, () => 'bar')
index 8ada97b166be8166c69139b5dc22725a15975db2..2170a9192cfa4d290ce50be37e49f49b333fdf3e 100644 (file)
@@ -108,7 +108,7 @@ export function createHydrationFunctions(
       )
 
     const { type, ref, shapeFlag, patchFlag } = vnode
-    const domType = node.nodeType
+    let domType = node.nodeType
     vnode.el = node
 
     if (patchFlag === PatchFlags.BAIL) {
@@ -150,9 +150,12 @@ export function createHydrationFunctions(
         }
         break
       case Static:
-        if (domType !== DOMNodeTypes.ELEMENT && domType !== DOMNodeTypes.TEXT) {
-          nextNode = onMismatch()
-        } else {
+        if (isFragmentStart) {
+          // entire template is static but SSRed as a fragment
+          node = nextSibling(node)!
+          domType = node.nodeType
+        }
+        if (domType === DOMNodeTypes.ELEMENT || domType === DOMNodeTypes.TEXT) {
           // determine anchor, adopt content
           nextNode = node
           // if the static vnode has its content stripped during build,
@@ -169,7 +172,9 @@ export function createHydrationFunctions(
             }
             nextNode = nextSibling(nextNode)!
           }
-          return nextNode
+          return isFragmentStart ? nextSibling(nextNode) : nextNode
+        } else {
+          onMismatch()
         }
         break
       case Fragment: