wip: fix never hydrated, prepare tests

This commit is contained in:
tbitw2549 2024-08-29 11:58:48 +03:00
parent 124d1e2b49
commit 67d3cadcb2
3 changed files with 15 additions and 32 deletions

View File

@ -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 {

View File

@ -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()

View File

@ -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)
})
})