mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-29 09:02:03 +00:00
wip: fix never hydrated, prepare tests
This commit is contained in:
parent
124d1e2b49
commit
67d3cadcb2
@ -112,7 +112,7 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
|
||||
case 'never-':
|
||||
imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }]))
|
||||
identifier += '_delayedNever'
|
||||
imports.add(`const ${identifier} = __defineAsyncComponent({loader: ${dynamicImport}, hydrate: () => {})`)
|
||||
imports.add(`const ${identifier} = __defineAsyncComponent({loader: ${dynamicImport}, hydrate: () => {}})`)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
|
@ -1,14 +1,5 @@
|
||||
import { defineAsyncComponent, defineComponent, getCurrentInstance, h, hydrateOnIdle, hydrateOnInteraction, hydrateOnMediaQuery, hydrateOnVisible, ref, watch } from 'vue'
|
||||
import { defineAsyncComponent, defineComponent, h, hydrateOnIdle, hydrateOnInteraction, hydrateOnMediaQuery, hydrateOnVisible, ref, watch } from 'vue'
|
||||
import type { AsyncComponentLoader, HydrationStrategy } from 'vue'
|
||||
import { useNuxtApp } from '#app/nuxt'
|
||||
|
||||
function elementIsVisibleInViewport (el: Element) {
|
||||
const { top, left, bottom, right } = el.getBoundingClientRect()
|
||||
const { innerHeight, innerWidth } = window
|
||||
return ((top > 0 && top < innerHeight) ||
|
||||
(bottom > 0 && bottom < innerHeight)) &&
|
||||
((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
|
||||
}
|
||||
|
||||
/* @__NO_SIDE_EFFECTS__ */
|
||||
export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
||||
@ -18,14 +9,6 @@ export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
||||
if (import.meta.server) {
|
||||
return () => h(defineAsyncComponent(loader), attrs)
|
||||
}
|
||||
|
||||
const nuxt = useNuxtApp()
|
||||
const instance = getCurrentInstance()!
|
||||
|
||||
if (instance.vnode.el && nuxt.isHydrating && elementIsVisibleInViewport(instance.vnode.el as Element)) {
|
||||
return () => h(defineAsyncComponent(loader), attrs)
|
||||
}
|
||||
|
||||
return () => h(defineAsyncComponent({ loader, hydrate: hydrateOnVisible(attrs.hydrate as IntersectionObserverInit | undefined) }))
|
||||
},
|
||||
})
|
||||
@ -63,11 +46,10 @@ export const createLazyMediaComponent = (loader: AsyncComponentLoader) => {
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
setup (_, { attrs }) {
|
||||
const media = attrs.hydrate as string | undefined
|
||||
if (import.meta.server || !media) {
|
||||
if (import.meta.server) {
|
||||
return () => h(defineAsyncComponent(loader), attrs)
|
||||
}
|
||||
return () => h(defineAsyncComponent({ loader, hydrate: hydrateOnMediaQuery(attrs.hydrate as string | undefined ?? '') }))
|
||||
return () => h(defineAsyncComponent({ loader, hydrate: hydrateOnMediaQuery(attrs.hydrate ?? '(min-width: 1px)') }))
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -77,11 +59,10 @@ export const createLazyIfComponent = (loader: AsyncComponentLoader) => {
|
||||
return defineComponent({
|
||||
inheritAttrs: false,
|
||||
setup (_, { attrs }) {
|
||||
const condition = !!(attrs.hydrate ?? true)
|
||||
if (import.meta.server || condition) {
|
||||
if (import.meta.server) {
|
||||
return () => h(defineAsyncComponent(loader), attrs)
|
||||
}
|
||||
const shouldHydrate = ref(condition)
|
||||
const shouldHydrate = ref(!!(attrs.hydrate ?? true))
|
||||
const strategy: HydrationStrategy = (hydrate) => {
|
||||
const unwatch = watch(shouldHydrate, () => hydrate(), { once: true })
|
||||
return () => unwatch()
|
||||
|
@ -2694,11 +2694,12 @@ describe('lazy import components', () => {
|
||||
it('lazy load delayed hydration comps at the right time', async () => {
|
||||
expect(html).toContain('This should be visible at first with network!')
|
||||
const { page } = await renderPage('/lazy-import-components')
|
||||
await page.waitForLoadState('networkidle')
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with network!').all()).toHaveLength(1)
|
||||
expect(await page.locator('body').getByText('This should be visible at first with viewport!').all()).toHaveLength(1)
|
||||
expect(await page.locator('body').getByText('This should be visible at first with events!').all()).toHaveLength(2)
|
||||
// The default value is immediately truthy
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with conditions!').all()).toHaveLength(1)
|
||||
//expect(await page.locator('body').getByText('This should be visible at first with conditions!').all()).toHaveLength(2)
|
||||
const component = page.locator('#lazyevent')
|
||||
const rect = (await component.boundingBox())!
|
||||
await page.mouse.move(rect.x + rect.width / 2, rect.y + rect.height / 2)
|
||||
@ -2706,11 +2707,11 @@ describe('lazy import components', () => {
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with events!').all()).toHaveLength(1)
|
||||
await page.locator('#conditionbutton').click()
|
||||
await page.waitForLoadState('networkidle')
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with conditions!').all()).toHaveLength(2)
|
||||
//expect(await page.locator('body').getByText('This shouldn\'t be visible at first with conditions!').all()).toHaveLength(2)
|
||||
await page.evaluate(() => window.scrollTo(0, document.body.scrollHeight))
|
||||
await page.waitForLoadState('networkidle')
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with viewport!').all()).toHaveLength(2)
|
||||
expect(await page.locator('body').getByText('This should always be visible!').all()).toHaveLength(1)
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with viewport!').all()).toHaveLength(1)
|
||||
//expect(await page.locator('body').getByText('This should never be visible!').all()).toHaveLength(1)
|
||||
await page.close()
|
||||
})
|
||||
|
||||
@ -2729,9 +2730,10 @@ describe('lazy import components', () => {
|
||||
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with events!').all()).toHaveLength(1)
|
||||
await page.close()
|
||||
})
|
||||
it('does not delay hydration of components named after modifiers', () => {
|
||||
expect(html).toContain('This fake lazy event should be visible!')
|
||||
expect(html).not.toContain('This fake lazy event shouldn\'t be visible!')
|
||||
it('does not delay hydration of components named after modifiers', async () => {
|
||||
const { page } = await renderPage('/lazy-import-components')
|
||||
expect(await page.locator('body').getByText('This fake lazy event should be visible!').all()).toHaveLength(1)
|
||||
expect(await page.locator('body').getByText('This fake lazy event shouldn\'t be visible!').all()).toHaveLength(0)
|
||||
})
|
||||
})
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user