fix(server-renderer): Fix call to serverPrefetch in server renderer with an async setup (#10893)

This commit is contained in:
Matt Garrett 2024-09-03 02:43:52 -07:00 committed by GitHub
parent 7b5b6e0275
commit 6039e25e04
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 13 deletions

View File

@ -873,6 +873,26 @@ function testRender(type: string, render: typeof renderToString) {
expect(html).toBe(`<div>hello</div>`) expect(html).toBe(`<div>hello</div>`)
}) })
test('serverPrefetch w/ async setup', async () => {
const msg = Promise.resolve('hello')
const app = createApp({
data() {
return {
msg: '',
}
},
async serverPrefetch() {
this.msg = await msg
},
render() {
return h('div', this.msg)
},
async setup() {},
})
const html = await render(app)
expect(html).toBe(`<div>hello</div>`)
})
// #2763 // #2763
test('error handling w/ async setup', async () => { test('error handling w/ async setup', async () => {
const fn = vi.fn() const fn = vi.fn()

View File

@ -94,21 +94,20 @@ export function renderComponentVNode(
const instance = createComponentInstance(vnode, parentComponent, null) const instance = createComponentInstance(vnode, parentComponent, null)
const res = setupComponent(instance, true /* isSSR */) const res = setupComponent(instance, true /* isSSR */)
const hasAsyncSetup = isPromise(res) const hasAsyncSetup = isPromise(res)
const prefetches = instance.sp /* LifecycleHooks.SERVER_PREFETCH */ let prefetches = instance.sp /* LifecycleHooks.SERVER_PREFETCH */
if (hasAsyncSetup || prefetches) { if (hasAsyncSetup || prefetches) {
let p: Promise<unknown> = hasAsyncSetup const p: Promise<unknown> = Promise.resolve(res as Promise<void>)
? (res as Promise<void>) .then(() => {
: Promise.resolve() // instance.sp may be null until an async setup resolves, so evaluate it here
if (prefetches) { if (hasAsyncSetup) prefetches = instance.sp
p = p if (prefetches) {
.then(() => return Promise.all(
Promise.all(
prefetches.map(prefetch => prefetch.call(instance.proxy)), prefetches.map(prefetch => prefetch.call(instance.proxy)),
), )
) }
// Note: error display is already done by the wrapped lifecycle hook function. })
.catch(NOOP) // Note: error display is already done by the wrapped lifecycle hook function.
} .catch(NOOP)
return p.then(() => renderComponentSubTree(instance, slotScopeId)) return p.then(() => renderComponentSubTree(instance, slotScopeId))
} else { } else {
return renderComponentSubTree(instance, slotScopeId) return renderComponentSubTree(instance, slotScopeId)