mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 23:22:02 +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-':
|
case 'never-':
|
||||||
imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }]))
|
imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }]))
|
||||||
identifier += '_delayedNever'
|
identifier += '_delayedNever'
|
||||||
imports.add(`const ${identifier} = __defineAsyncComponent({loader: ${dynamicImport}, hydrate: () => {})`)
|
imports.add(`const ${identifier} = __defineAsyncComponent({loader: ${dynamicImport}, hydrate: () => {}})`)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} else {
|
} 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 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__ */
|
/* @__NO_SIDE_EFFECTS__ */
|
||||||
export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
||||||
@ -18,14 +9,6 @@ export const createLazyIOComponent = (loader: AsyncComponentLoader) => {
|
|||||||
if (import.meta.server) {
|
if (import.meta.server) {
|
||||||
return () => h(defineAsyncComponent(loader), attrs)
|
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) }))
|
return () => h(defineAsyncComponent({ loader, hydrate: hydrateOnVisible(attrs.hydrate as IntersectionObserverInit | undefined) }))
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -63,11 +46,10 @@ export const createLazyMediaComponent = (loader: AsyncComponentLoader) => {
|
|||||||
return defineComponent({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
setup (_, { attrs }) {
|
||||||
const media = attrs.hydrate as string | undefined
|
if (import.meta.server) {
|
||||||
if (import.meta.server || !media) {
|
|
||||||
return () => h(defineAsyncComponent(loader), attrs)
|
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({
|
return defineComponent({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
setup (_, { attrs }) {
|
setup (_, { attrs }) {
|
||||||
const condition = !!(attrs.hydrate ?? true)
|
if (import.meta.server) {
|
||||||
if (import.meta.server || condition) {
|
|
||||||
return () => h(defineAsyncComponent(loader), attrs)
|
return () => h(defineAsyncComponent(loader), attrs)
|
||||||
}
|
}
|
||||||
const shouldHydrate = ref(condition)
|
const shouldHydrate = ref(!!(attrs.hydrate ?? true))
|
||||||
const strategy: HydrationStrategy = (hydrate) => {
|
const strategy: HydrationStrategy = (hydrate) => {
|
||||||
const unwatch = watch(shouldHydrate, () => hydrate(), { once: true })
|
const unwatch = watch(shouldHydrate, () => hydrate(), { once: true })
|
||||||
return () => unwatch()
|
return () => unwatch()
|
||||||
|
@ -2694,11 +2694,12 @@ describe('lazy import components', () => {
|
|||||||
it('lazy load delayed hydration comps at the right time', async () => {
|
it('lazy load delayed hydration comps at the right time', async () => {
|
||||||
expect(html).toContain('This should be visible at first with network!')
|
expect(html).toContain('This should be visible at first with network!')
|
||||||
const { page } = await renderPage('/lazy-import-components')
|
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 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 viewport!').all()).toHaveLength(1)
|
||||||
expect(await page.locator('body').getByText('This should be visible at first with events!').all()).toHaveLength(2)
|
expect(await page.locator('body').getByText('This should be visible at first with events!').all()).toHaveLength(2)
|
||||||
// The default value is immediately truthy
|
// 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 component = page.locator('#lazyevent')
|
||||||
const rect = (await component.boundingBox())!
|
const rect = (await component.boundingBox())!
|
||||||
await page.mouse.move(rect.x + rect.width / 2, rect.y + rect.height / 2)
|
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)
|
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.locator('#conditionbutton').click()
|
||||||
await page.waitForLoadState('networkidle')
|
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.evaluate(() => window.scrollTo(0, document.body.scrollHeight))
|
||||||
await page.waitForLoadState('networkidle')
|
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 shouldn\'t be visible at first with viewport!').all()).toHaveLength(1)
|
||||||
expect(await page.locator('body').getByText('This should always be visible!').all()).toHaveLength(1)
|
//expect(await page.locator('body').getByText('This should never be visible!').all()).toHaveLength(1)
|
||||||
await page.close()
|
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)
|
expect(await page.locator('body').getByText('This shouldn\'t be visible at first with events!').all()).toHaveLength(1)
|
||||||
await page.close()
|
await page.close()
|
||||||
})
|
})
|
||||||
it('does not delay hydration of components named after modifiers', () => {
|
it('does not delay hydration of components named after modifiers', async () => {
|
||||||
expect(html).toContain('This fake lazy event should be visible!')
|
const { page } = await renderPage('/lazy-import-components')
|
||||||
expect(html).not.toContain('This fake lazy event shouldn\'t be visible!')
|
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