nuxt / nuxt

The Intuitive Vue Framework.
https://nuxt.com
MIT License
54k stars 4.94k forks source link

Multiple `useLazyAsyncData` within a composable becomes non lazy #25033

Open huang-julien opened 8 months ago

huang-julien commented 8 months ago

Environment


Reproduction

https://stackblitz.com/edit/nuxt-starter-t7zx5g?file=composables%2Ftest.ts

Describe the bug

Using 2 useLazyAsyncData make the page change blocking

Additional context

No response

Logs

No response

stackblitz[bot] commented 8 months ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

gibkigonzo commented 7 months ago

it looks like getCurrentInstance doesn't exist for second useLazyAsyncData. So instead of going here https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/asyncData.ts#L359-L362 it goes to https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/app/composables/asyncData.ts#L363-L365

jamesdawsonWD commented 6 months ago

I believe that this is working correctly and that the issue lies with how it is documented. The example you provided @huang-julien uses await on useLazyAsyncData but these composables are not async and I think the awaits are causing the problem.

I believe the awaits make the vue component instance become undefined for any sequential await calls (ref: https://nuxt.com/docs/api/composables/use-nuxt-app ). And since instance is undefined, lazyAsyncData has to revert to just asyncData which blocks the route change because it can't call instance._nuxtOnBeforeMountCbs.push(initialFetch). This is also why one useLazyAsyncData with await works fine because the component instance is there on the first call.

Playground with working multiple useLazyAsyncData: https://stackblitz.com/edit/nuxt-starter-3ojz7s?file=pages%2Findex.vue

If this is correct, I suggest we make a simple doc change to remove the superfluous await. https://nuxt.com/docs/api/composables/use-lazy-async-data

huang-julien commented 6 months ago

Didn't had the time to investigate yet, but it can be a unctx issue

jamesdawsonWD commented 6 months ago

Ah, if removing await can cause a vulnerability then I will continue investigating. I am very new to this codebase, but it seems like nuxtApp.runWithContext isn't ensuring that vue component instance is available - but maybe that is not it's function? I will look into ways to ensure that the component ctx is available

felix-dolderer commented 1 week ago

Ah, if removing await can cause a vulnerability then I will continue investigating. I am very new to this codebase, but it seems like nuxtApp.runWithContext isn't ensuring that vue component instance is available - but maybe that is not it's function? I will look into ways to ensure that the component ctx is available

The issue is actually even one step before that. The entire nuxtApp is undefined in this case. As the docs state: async context only works with <script setup>, defineNuxtPlugin and defineNuxtRouteMiddleware but not in composables.

Text from Docs

Vue currently only supports async context restoration for Githubissues.

  • Githubissues is a development platform for aggregating issues.