fix(nuxt): ensure we only increment hydrating count once (#22200)

This commit is contained in:
Daniel Roe 2023-07-18 16:21:53 +01:00 committed by GitHub
parent f6b64f6a65
commit 449a01526a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 38 additions and 2 deletions

View File

@ -33,8 +33,9 @@ export default defineComponent({
const layoutRef = ref() const layoutRef = ref()
context.expose({ layoutRef }) context.expose({ layoutRef })
const done = nuxtApp.deferHydration()
return () => { return () => {
const done = nuxtApp.deferHydration()
const hasLayout = layout.value && layout.value in layouts const hasLayout = layout.value && layout.value in layouts
if (process.dev && layout.value && !hasLayout && layout.value !== 'default') { if (process.dev && layout.value && !hasLayout && layout.value !== 'default') {
console.warn(`Invalid layout \`${layout.value}\` selected.`) console.warn(`Invalid layout \`${layout.value}\` selected.`)

View File

@ -46,6 +46,8 @@ export default defineComponent({
const _layoutMeta = inject(LayoutMetaSymbol, null) const _layoutMeta = inject(LayoutMetaSymbol, null)
let vnode: VNode let vnode: VNode
const done = nuxtApp.deferHydration()
return () => { return () => {
return h(RouterView, { name: props.name, route: props.route, ...attrs }, { return h(RouterView, { name: props.name, route: props.route, ...attrs }, {
default: (routeProps: RouterViewSlotProps) => { default: (routeProps: RouterViewSlotProps) => {
@ -76,7 +78,6 @@ export default defineComponent({
} }
const key = generateRouteKey(routeProps, props.pageKey) const key = generateRouteKey(routeProps, props.pageKey)
const done = nuxtApp.deferHydration()
const hasTransition = !!(props.transition ?? routeProps.route.meta.pageTransition ?? defaultPageTransition) const hasTransition = !!(props.transition ?? routeProps.route.meta.pageTransition ?? defaultPageTransition)
const transitionProps = hasTransition && _mergeTransitionProps([ const transitionProps = hasTransition && _mergeTransitionProps([

View File

@ -1034,6 +1034,16 @@ describe('deferred app suspense resolve', () => {
it('should wait for all suspense instance on initial hydration', async () => { it('should wait for all suspense instance on initial hydration', async () => {
await behaviour('/internal-layout/async-parent/child') await behaviour('/internal-layout/async-parent/child')
}) })
it('should fully hydrate even if there is a redirection on a page with `ssr: false`', async () => {
const page = await createPage('/hydration/spa-redirection/start')
await page.waitForLoadState('networkidle')
// Wait for all pending micro ticks to be cleared in case hydration hasn't finished yet.
await page.evaluate(() => new Promise(resolve => setTimeout(resolve, 10)))
const html = await page.getByRole('document').innerHTML()
expect(html).toContain('fully hydrated and ready to go')
})
}) })
describe('nested suspense', () => { describe('nested suspense', () => {

View File

@ -48,6 +48,7 @@ export default defineNuxtConfig({
}, },
routeRules: { routeRules: {
'/route-rules/spa': { ssr: false }, '/route-rules/spa': { ssr: false },
'/hydration/spa-redirection/**': { ssr: false },
'/no-scripts': { experimentalNoScripts: true } '/no-scripts': { experimentalNoScripts: true }
}, },
output: { dir: process.env.NITRO_OUTPUT_DIR }, output: { dir: process.env.NITRO_OUTPUT_DIR },

View File

@ -0,0 +1,12 @@
<script setup lang="ts">
const ready = ref('not yet hydrated')
onNuxtReady(() => {
ready.value = 'fully hydrated and ready to go'
})
</script>
<template>
<div>
{{ ready }}
</div>
</template>

View File

@ -0,0 +1,11 @@
<script setup lang="ts">
definePageMeta({
middleware: () => '/hydration/spa-redirection/end'
})
</script>
<template>
<div>
Tests whether hydration is properly resolved when loading
</div>
</template>