]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(server-renderer): Fix call to serverPrefetch in server renderer with an async...
authorMatt Garrett <mattga@gmail.com>
Tue, 3 Sep 2024 09:43:52 +0000 (02:43 -0700)
committerGitHub <noreply@github.com>
Tue, 3 Sep 2024 09:43:52 +0000 (17:43 +0800)
packages/server-renderer/__tests__/render.spec.ts
packages/server-renderer/src/render.ts

index 705cb2a8b6f31bc78c03a2a36a715a52e21e5b3b..1b1d6256e8c97cd4868d3f71655d1d93d7cbf0d4 100644 (file)
@@ -873,6 +873,26 @@ function testRender(type: string, render: typeof renderToString) {
       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
     test('error handling w/ async setup', async () => {
       const fn = vi.fn()
index 4744940e827eb26df5b1d7dbd1725a7cbc3b3318..97179526456d663472ddac84cd66b9951536fceb 100644 (file)
@@ -94,21 +94,20 @@ export function renderComponentVNode(
   const instance = createComponentInstance(vnode, parentComponent, null)
   const res = setupComponent(instance, true /* isSSR */)
   const hasAsyncSetup = isPromise(res)
-  const prefetches = instance.sp /* LifecycleHooks.SERVER_PREFETCH */
+  let prefetches = instance.sp /* LifecycleHooks.SERVER_PREFETCH */
   if (hasAsyncSetup || prefetches) {
-    let p: Promise<unknown> = hasAsyncSetup
-      ? (res as Promise<void>)
-      : Promise.resolve()
-    if (prefetches) {
-      p = p
-        .then(() =>
-          Promise.all(
+    const p: Promise<unknown> = Promise.resolve(res as Promise<void>)
+      .then(() => {
+        // instance.sp may be null until an async setup resolves, so evaluate it here
+        if (hasAsyncSetup) prefetches = instance.sp
+        if (prefetches) {
+          return Promise.all(
             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))
   } else {
     return renderComponentSubTree(instance, slotScopeId)