Skip to content

Commit e44574b

Browse files
fix(hydration): log hydration error even when using async components
1 parent 2857a59 commit e44574b

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

packages/runtime-core/src/hydration.ts

+31-12
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,19 @@ const enum DOMNodeTypes {
3636
COMMENT = 8
3737
}
3838

39-
let hasMismatch = false
39+
// This log function is built this way to guarantee it's only triggered once.
40+
const logMismatchError = (function () {
41+
let alreadyLogged = false
42+
43+
return () => {
44+
if(alreadyLogged) {
45+
return
46+
}
47+
48+
console.error('Hydration completed but contains mismatches.')
49+
alreadyLogged = true
50+
}
51+
})()
4052

4153
const isSVGContainer = (container: Element) =>
4254
/svg/.test(container.namespaceURI!) && container.tagName !== 'foreignObject'
@@ -78,14 +90,10 @@ export function createHydrationFunctions(
7890
container._vnode = vnode
7991
return
8092
}
81-
hasMismatch = false
93+
8294
hydrateNode(container.firstChild!, vnode, null, null, null)
8395
flushPostFlushCbs()
8496
container._vnode = vnode
85-
if (hasMismatch && !__TEST__) {
86-
// this error should show up in production
87-
console.error(`Hydration completed but contains mismatches.`)
88-
}
8997
}
9098

9199
const hydrateNode = (
@@ -130,7 +138,6 @@ export function createHydrationFunctions(
130138
}
131139
} else {
132140
if ((node as Text).data !== vnode.children) {
133-
hasMismatch = true
134141
__DEV__ &&
135142
warn(
136143
`Hydration text mismatch:` +
@@ -139,6 +146,9 @@ export function createHydrationFunctions(
139146
)}` +
140147
`\n- Client rendered: ${JSON.stringify(vnode.children)}`
141148
)
149+
150+
!__TEST__ && logMismatchError()
151+
142152
;(node as Text).data = vnode.children as string
143153
}
144154
nextNode = nextSibling(node)
@@ -387,22 +397,23 @@ export function createHydrationFunctions(
387397
)
388398
let hasWarned = false
389399
while (next) {
390-
hasMismatch = true
391400
if (__DEV__ && !hasWarned) {
392401
warn(
393402
`Hydration children mismatch in <${vnode.type as string}>: ` +
394403
`server rendered element contains more child nodes than client vdom.`
395404
)
396405
hasWarned = true
397406
}
407+
408+
!__TEST__ && logMismatchError()
409+
398410
// The SSRed DOM contains more nodes than it should. Remove them.
399411
const cur = next
400412
next = next.nextSibling
401413
remove(cur)
402414
}
403415
} else if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
404416
if (el.textContent !== vnode.children) {
405-
hasMismatch = true
406417
__DEV__ &&
407418
warn(
408419
`Hydration text content mismatch in <${
@@ -411,6 +422,9 @@ export function createHydrationFunctions(
411422
`- Server rendered: ${el.textContent}\n` +
412423
`- Client rendered: ${vnode.children as string}`
413424
)
425+
426+
!__TEST__ && logMismatchError()
427+
414428
el.textContent = vnode.children as string
415429
}
416430
}
@@ -447,14 +461,16 @@ export function createHydrationFunctions(
447461
} else if (vnode.type === Text && !vnode.children) {
448462
continue
449463
} else {
450-
hasMismatch = true
451464
if (__DEV__ && !hasWarned) {
452465
warn(
453466
`Hydration children mismatch in <${container.tagName.toLowerCase()}>: ` +
454467
`server rendered element contains fewer child nodes than client vdom.`
455468
)
456469
hasWarned = true
457470
}
471+
472+
!__TEST__ && logMismatchError()
473+
458474
// the SSRed DOM didn't contain enough nodes. Mount the missing ones.
459475
patch(
460476
null,
@@ -501,7 +517,8 @@ export function createHydrationFunctions(
501517
} else {
502518
// fragment didn't hydrate successfully, since we didn't get a end anchor
503519
// back. This should have led to node/children mismatch warnings.
504-
hasMismatch = true
520+
!__TEST__ && logMismatchError()
521+
505522
// since the anchor is missing, we need to create one and insert it
506523
insert((vnode.anchor = createComment(`]`)), container, next)
507524
return next
@@ -516,7 +533,6 @@ export function createHydrationFunctions(
516533
slotScopeIds: string[] | null,
517534
isFragment: boolean
518535
): Node | null => {
519-
hasMismatch = true
520536
__DEV__ &&
521537
warn(
522538
`Hydration node mismatch:\n- Client vnode:`,
@@ -529,6 +545,9 @@ export function createHydrationFunctions(
529545
? `(start of fragment)`
530546
: ``
531547
)
548+
549+
!__TEST__ && logMismatchError()
550+
532551
vnode.el = null
533552

534553
if (isFragment) {

0 commit comments

Comments
 (0)