Skip to content

Commit 5afc76c

Browse files
fix(hydration): log hydration error even when using async components (#9403)
close #9369
1 parent aa156ed commit 5afc76c

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

packages/runtime-core/src/hydration.ts

+22-13
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,15 @@ enum DOMNodeTypes {
5050
COMMENT = 8,
5151
}
5252

53-
let hasMismatch = false
53+
let hasLoggedMismatchError = false
54+
const logMismatchError = () => {
55+
if (__TEST__ || hasLoggedMismatchError) {
56+
return
57+
}
58+
// this error should show up in production
59+
console.error('Hydration completed but contains mismatches.')
60+
hasLoggedMismatchError = true
61+
}
5462

5563
const isSVGContainer = (container: Element) =>
5664
container.namespaceURI!.includes('svg') &&
@@ -102,14 +110,10 @@ export function createHydrationFunctions(
102110
container._vnode = vnode
103111
return
104112
}
105-
hasMismatch = false
113+
106114
hydrateNode(container.firstChild!, vnode, null, null, null)
107115
flushPostFlushCbs()
108116
container._vnode = vnode
109-
if (hasMismatch && !__TEST__) {
110-
// this error should show up in production
111-
console.error(`Hydration completed but contains mismatches.`)
112-
}
113117
}
114118

115119
const hydrateNode = (
@@ -170,7 +174,6 @@ export function createHydrationFunctions(
170174
}
171175
} else {
172176
if ((node as Text).data !== vnode.children) {
173-
hasMismatch = true
174177
;(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
175178
warn(
176179
`Hydration text mismatch in`,
@@ -180,6 +183,7 @@ export function createHydrationFunctions(
180183
)}` +
181184
`\n - expected on client: ${JSON.stringify(vnode.children)}`,
182185
)
186+
logMismatchError()
183187
;(node as Text).data = vnode.children as string
184188
}
185189
nextNode = nextSibling(node)
@@ -409,7 +413,6 @@ export function createHydrationFunctions(
409413
)
410414
let hasWarned = false
411415
while (next) {
412-
hasMismatch = true
413416
if (
414417
(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
415418
!hasWarned
@@ -421,21 +424,24 @@ export function createHydrationFunctions(
421424
)
422425
hasWarned = true
423426
}
427+
logMismatchError()
428+
424429
// The SSRed DOM contains more nodes than it should. Remove them.
425430
const cur = next
426431
next = next.nextSibling
427432
remove(cur)
428433
}
429434
} else if (shapeFlag & ShapeFlags.TEXT_CHILDREN) {
430435
if (el.textContent !== vnode.children) {
431-
hasMismatch = true
432436
;(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
433437
warn(
434438
`Hydration text content mismatch on`,
435439
el,
436440
`\n - rendered on server: ${el.textContent}` +
437441
`\n - expected on client: ${vnode.children as string}`,
438442
)
443+
logMismatchError()
444+
439445
el.textContent = vnode.children as string
440446
}
441447
}
@@ -455,7 +461,7 @@ export function createHydrationFunctions(
455461
(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
456462
propHasMismatch(el, key, props[key], vnode, parentComponent)
457463
) {
458-
hasMismatch = true
464+
logMismatchError()
459465
}
460466
if (
461467
(forcePatch &&
@@ -545,7 +551,6 @@ export function createHydrationFunctions(
545551
// because server rendered HTML won't contain a text node
546552
insert((vnode.el = createText('')), container)
547553
} else {
548-
hasMismatch = true
549554
if (
550555
(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
551556
!hasWarned
@@ -557,6 +562,8 @@ export function createHydrationFunctions(
557562
)
558563
hasWarned = true
559564
}
565+
logMismatchError()
566+
560567
// the SSRed DOM didn't contain enough nodes. Mount the missing ones.
561568
patch(
562569
null,
@@ -603,7 +610,8 @@ export function createHydrationFunctions(
603610
} else {
604611
// fragment didn't hydrate successfully, since we didn't get a end anchor
605612
// back. This should have led to node/children mismatch warnings.
606-
hasMismatch = true
613+
logMismatchError()
614+
607615
// since the anchor is missing, we need to create one and insert it
608616
insert((vnode.anchor = createComment(`]`)), container, next)
609617
return next
@@ -618,7 +626,6 @@ export function createHydrationFunctions(
618626
slotScopeIds: string[] | null,
619627
isFragment: boolean,
620628
): Node | null => {
621-
hasMismatch = true
622629
;(__DEV__ || __FEATURE_PROD_HYDRATION_MISMATCH_DETAILS__) &&
623630
warn(
624631
`Hydration node mismatch:\n- rendered on server:`,
@@ -631,6 +638,8 @@ export function createHydrationFunctions(
631638
`\n- expected on client:`,
632639
vnode.type,
633640
)
641+
logMismatchError()
642+
634643
vnode.el = null
635644

636645
if (isFragment) {

0 commit comments

Comments
 (0)