@@ -36,7 +36,19 @@ const enum DOMNodeTypes {
36
36
COMMENT = 8
37
37
}
38
38
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
+ } ) ( )
40
52
41
53
const isSVGContainer = ( container : Element ) =>
42
54
/ s v g / . test ( container . namespaceURI ! ) && container . tagName !== 'foreignObject'
@@ -78,14 +90,10 @@ export function createHydrationFunctions(
78
90
container . _vnode = vnode
79
91
return
80
92
}
81
- hasMismatch = false
93
+
82
94
hydrateNode ( container . firstChild ! , vnode , null , null , null )
83
95
flushPostFlushCbs ( )
84
96
container . _vnode = vnode
85
- if ( hasMismatch && ! __TEST__ ) {
86
- // this error should show up in production
87
- console . error ( `Hydration completed but contains mismatches.` )
88
- }
89
97
}
90
98
91
99
const hydrateNode = (
@@ -130,7 +138,6 @@ export function createHydrationFunctions(
130
138
}
131
139
} else {
132
140
if ( ( node as Text ) . data !== vnode . children ) {
133
- hasMismatch = true
134
141
__DEV__ &&
135
142
warn (
136
143
`Hydration text mismatch:` +
@@ -139,6 +146,9 @@ export function createHydrationFunctions(
139
146
) } ` +
140
147
`\n- Client rendered: ${ JSON . stringify ( vnode . children ) } `
141
148
)
149
+
150
+ ! __TEST__ && logMismatchError ( )
151
+
142
152
; ( node as Text ) . data = vnode . children as string
143
153
}
144
154
nextNode = nextSibling ( node )
@@ -387,22 +397,23 @@ export function createHydrationFunctions(
387
397
)
388
398
let hasWarned = false
389
399
while ( next ) {
390
- hasMismatch = true
391
400
if ( __DEV__ && ! hasWarned ) {
392
401
warn (
393
402
`Hydration children mismatch in <${ vnode . type as string } >: ` +
394
403
`server rendered element contains more child nodes than client vdom.`
395
404
)
396
405
hasWarned = true
397
406
}
407
+
408
+ ! __TEST__ && logMismatchError ( )
409
+
398
410
// The SSRed DOM contains more nodes than it should. Remove them.
399
411
const cur = next
400
412
next = next . nextSibling
401
413
remove ( cur )
402
414
}
403
415
} else if ( shapeFlag & ShapeFlags . TEXT_CHILDREN ) {
404
416
if ( el . textContent !== vnode . children ) {
405
- hasMismatch = true
406
417
__DEV__ &&
407
418
warn (
408
419
`Hydration text content mismatch in <${
@@ -411,6 +422,9 @@ export function createHydrationFunctions(
411
422
`- Server rendered: ${ el . textContent } \n` +
412
423
`- Client rendered: ${ vnode . children as string } `
413
424
)
425
+
426
+ ! __TEST__ && logMismatchError ( )
427
+
414
428
el . textContent = vnode . children as string
415
429
}
416
430
}
@@ -447,14 +461,16 @@ export function createHydrationFunctions(
447
461
} else if ( vnode . type === Text && ! vnode . children ) {
448
462
continue
449
463
} else {
450
- hasMismatch = true
451
464
if ( __DEV__ && ! hasWarned ) {
452
465
warn (
453
466
`Hydration children mismatch in <${ container . tagName . toLowerCase ( ) } >: ` +
454
467
`server rendered element contains fewer child nodes than client vdom.`
455
468
)
456
469
hasWarned = true
457
470
}
471
+
472
+ ! __TEST__ && logMismatchError ( )
473
+
458
474
// the SSRed DOM didn't contain enough nodes. Mount the missing ones.
459
475
patch (
460
476
null ,
@@ -501,7 +517,8 @@ export function createHydrationFunctions(
501
517
} else {
502
518
// fragment didn't hydrate successfully, since we didn't get a end anchor
503
519
// back. This should have led to node/children mismatch warnings.
504
- hasMismatch = true
520
+ ! __TEST__ && logMismatchError ( )
521
+
505
522
// since the anchor is missing, we need to create one and insert it
506
523
insert ( ( vnode . anchor = createComment ( `]` ) ) , container , next )
507
524
return next
@@ -516,7 +533,6 @@ export function createHydrationFunctions(
516
533
slotScopeIds : string [ ] | null ,
517
534
isFragment : boolean
518
535
) : Node | null => {
519
- hasMismatch = true
520
536
__DEV__ &&
521
537
warn (
522
538
`Hydration node mismatch:\n- Client vnode:` ,
@@ -529,6 +545,9 @@ export function createHydrationFunctions(
529
545
? `(start of fragment)`
530
546
: ``
531
547
)
548
+
549
+ ! __TEST__ && logMismatchError ( )
550
+
532
551
vnode . el = null
533
552
534
553
if ( isFragment ) {
0 commit comments