Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to use useNuxtApp() since @tresjs/[email protected] #33

Closed
5 tasks done
kekkorider opened this issue Aug 29, 2023 · 17 comments · Fixed by #39
Closed
5 tasks done

Unable to use useNuxtApp() since @tresjs/[email protected] #33

kekkorider opened this issue Aug 29, 2023 · 17 comments · Fixed by #39
Assignees
Labels
bug Something isn't working

Comments

@kekkorider
Copy link

kekkorider commented Aug 29, 2023

Describe the bug

I tried upgrading the @tresjs/core package from 3.0.1 to 3.1.x and now every attempt to use the useNuxtApp() composable breaks the application.

Screenshot 2023-08-30 alle 00 45 56

Reproduction

https://stackblitz.com/github/kekkorider/nuxt-tres-starter/tree/tresjs-core-3-1?file=components%2FSampleBox.vue

Steps to reproduce

In /components/SampleBox.vue, comment out line 19, the one where useNuxtApp() is used.
The error will be gone.

System Info

System:
    OS: macOS 13.4.1
    CPU: (8) arm64 Apple M1
    Memory: 280.75 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.16.0 - ~/.nvm/versions/node/v18.16.0/bin/node
    Yarn: 1.22.19 - ~/.yarn/bin/yarn
    npm: 9.5.1 - ~/.nvm/versions/node/v18.16.0/bin/npm
    pnpm: 8.7.0 - /opt/homebrew/bin/pnpm
  Browsers:
    Chrome: 116.0.5845.110
    Edge: 114.0.1823.55
    Safari: 16.5.1

Used Package Manager

pnpm

Code of Conduct

@alvarosabu
Copy link
Member

Hey @kekkorider try the new release, I updated the core here #35

@kekkorider
Copy link
Author

@alvarosabu if you're talking about the 3.1.1 version, the error persists 🥲🔫

@alvarosabu
Copy link
Member

I meant updating the version of the @trejs/nuxt .

@kekkorider
Copy link
Author

Just updated @tresjs/nuxt to 1.1.5 and nothing changed unfortunately 😕

@alvarosabu
Copy link
Member

Hey @danielroe I might need your support here. 😅
nuxtAppInstance = getCurrentInstance()?.appContext.app.$nuxt;

getCurrentInstance() returns null

To fix the devtools, we introduce these changes on @[email protected] https://github.com/Tresjs/tres/pull/375/files#diff-d554b20c605a72c68b2d429ff9915cca4afa8e118026f56ede93382d130382a7

This means we don't longer mount a second app with the Tres renderer, We actually managed to have a "reconciliation" layer inside TresCanvas. I think this is causing the' useNuxtApp' composable to break when used inside of the <TresCanvas /> context.

Any idea if we could potentially fix this?

Appreciate your time 🙏🏻

Copy link
Member

If this is purely client-side, you can access the current Nuxt app instance with window.useNuxtApp (in the latest versions).

@kekkorider
Copy link
Author

kekkorider commented Aug 30, 2023

Just made a quick test 👇

  1. Keep const { $gsap } = useNuxtApp() commented out
  2. Instantiate a let gsap variable
  3. Set the value of the above gsap variable inside the onMounted() hook this way 👉 gsap = window.useNuxtApp().$gsap

This way, it works.


I also tested some other potential solutions, but none of these succeeded 👇

  1. Rename SampleBox.vue to SampleBox.client.vue
  2. Wrap <SampleBox /> with <ClientOnly /> in MyScene.client.vue

Copy link
Member

I'm not entirely sure of the details - maybe a reproduction would help me.

Ideally users wouldn't need to update their code, and should be able to use useNuxtApp as is in their components.

Are all the Nuxt injections missing from the Tres canvas?

@kekkorider
Copy link
Author

@danielroe thanks for the reply!

Have you checked the reproduction link? 👉 https://stackblitz.com/github/kekkorider/nuxt-tres-starter/tree/tresjs-core-3-1?file=components%2FSampleBox.vue

By default the application breaks, but if you follow my instructions you'll see that it works

  1. Keep const { $gsap } = useNuxtApp() commented out
  2. Instantiate a let gsap variable
  3. Set the value of the above gsap variable inside the onMounted() hook this way 👉 gsap = window.useNuxtApp().$gsap

@kekkorider
Copy link
Author

Are all the Nuxt injections missing from the Tres canvas?

I tested a bunch of random composables provided by Nuxt, most of them don't work and trigger the same error.

  1. useRoute()
  2. useRouter()
  3. useSeoMeta()
  4. useFetch()
  5. useState()

Copy link
Member

I think there will be a lot of situations where users expect to be able to access an injection provided by a module's plugin, for example. Might be worth considering how to proxy injections across? Depending on the lifecycle (is the tres app created subsequent to all nuxt plugins?) you might be able to pass the injections across.

@alvarosabu
Copy link
Member

Yeah users should be able to acces those

In the TresCanvas we "mount" the renderer like this:

const mountCustomRenderer = (context: TresContext) => { 
   const InternalComponent = createInternalComponent(context) 
   render(h(InternalComponent), scene.value as unknown as TresObject) 
 }

Being render a method from the customRenderer.

@danielroe to inject them would be at this level or in the nuxt module itself?

@JaimeTorrealba
Copy link
Member

I have the same error here, any fix?

@alvarosabu
Copy link
Member

alvarosabu commented Sep 10, 2023

@danielroe been investigating a little bit and the problem is that when getCurrentInstance is used inside a Tres component (Inside the context of the custom renderer) app is null

Since all this composable on nuxt uses it, they get broken.

Screenshot 2023-09-10 at 18 49 25

Actually, @enpitsuLin helped us out with the custom render, there would be any way to provide the custom renderer the app value of it's parent (the vue app)?

@enpitsuLin
Copy link
Collaborator

It seems that using the custom renderer will create appContext which doesn't contain context from the root Vue App(Like Nuxt provided), I think this is expected

use custom renderer will create separate contexts just like creating different App Instances, whether using the render function or createApp

we need to provide useful context alone as TresJs does

but it's unreasonable, I think proxy the root App's context to the context created by the custom renderer might be a solution, but don't know how to :)

@alvarosabu
Copy link
Member

Hi @enpitsuLin thanks for your insights! I manually proxy the context of the vue wrapper app to the TresJS one, really manual, not sure if it's the best approach but, might fix the issue.

Do you mind to give it a look? Thanks for your support

@alvarosabu alvarosabu self-assigned this Sep 11, 2023
@alvarosabu alvarosabu added the bug Something isn't working label Sep 11, 2023
@kekkorider
Copy link
Author

Confirming that with the 1.1.6 version of @tresjs/nuxt the error is gone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants