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

SSR hydration throws error when slot (fragment) contains a single <transition> whose element's v-if evaluates to false #5352

Closed
AaronBeaudoin opened this issue Feb 1, 2022 · 2 comments
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working scope: ssr

Comments

@AaronBeaudoin
Copy link

AaronBeaudoin commented Feb 1, 2022

Version

3.2.29

Reproduction link

https://github.com/AaronBeaudoin/vite-vue-ssr-bug-repr/tree/transition-mismatch

Steps to reproduce

  1. npm i to install dependencies then npm run dev to run.
  2. In your browser go to http://localhost:3001. Note the error in the console.

What is expected?

Hydration completes without errors.

What is actually happening?

Hydration throws an error.


SEE THE "More Debugging Info" COMMENT BELOW FOR AN EXPLANATION.

@AaronBeaudoin AaronBeaudoin changed the title SSR hydrations throws error in <transition> component (reason unclear; minimal repo provided) SSR hydration throws error in <transition> component (reason unclear; minimal repo provided) Feb 1, 2022
@AaronBeaudoin
Copy link
Author

AaronBeaudoin commented Feb 2, 2022

More Debugging Info

Here is more specifically what is happening with this bug. When the hydrateChildren function is run inside of the hydrateFragment function on line 4283, it expects to get the fragment's end anchor back from hydrateChildren, but in this case it get's null instead.

The reason for this can be seen inside of hydrateChildren. It appears that there are two expected states of node and parentVNode inside this function:

  1. parentVNode (the fragment) has 0 children, so therefore node is the fragment's end anchor, causing the for loop to never run and the end anchor to be returned directly.
  2. parentNode (the fragment) has 1 or more children, so therefore node is the fragment's first child, causing the for loop to run such that on the first iteration the hydrateNode function is called with node and parentVNode.children[0]. As the loop runs parentVNode.children.length times, node is overwritten on each iteration, eventually resulting in the function returning the fragment's end anchor.

Either way, parentVNode is the fragment, and the function's return value is expected to be the end anchor.

In the minimal reproduction above, neither of these things happen, which appears to undefined behavior and causes a bug. In this case, when the hydrateChildren function runs, parentVNode (the fragment) has 1 child (the <transition>), but node is the fragment's end anchor because the transition's element does not render (since its v-if evaluates to false). This results in the hydrateNode function being called with the fragment's end anchor as node but the transition as vnode, which clearly doesn't make sense.

It appears that this state in turn causes the hydrateNode function which runs on the for loop's only iteration to return null, which is then returned from hydrateChildren causing the hydrateFragment function to never get the fragment's end anchor—even though it exists in the server rendered HTML!

This then results in the hydrateFragment function inserting a new comment, which occurs on line 4292. This results in the DOM having 3 comments like:

<div id="app">
  <div>
    <!--[-->
    <!--]-->
    <!--]-->
  </div>
</div>

...and now there is an extra unmatched fragment end anchor in the DOM. So this bug results in a bit of a mess.

@AaronBeaudoin AaronBeaudoin changed the title SSR hydration throws error in <transition> component (reason unclear; minimal repo provided) SSR hydration throws error in <transition> component due to a bug in fragment logic Feb 2, 2022
@AaronBeaudoin AaronBeaudoin changed the title SSR hydration throws error in <transition> component due to a bug in fragment logic SSR hydration throws error when slot (fragment) contains a single <transition> whose element's v-if evaluates to false Feb 2, 2022
@meteorlxy
Copy link
Member

Might be duplicate of #3989 ?

@yyx990803 yyx990803 added 🐞 bug Something isn't working 🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. labels May 17, 2022
@github-actions github-actions bot locked and limited conversation to collaborators Sep 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
🔨 p3-minor-bug Priority 3: this fixes a bug, but is an edge case that only affects very specific usage. 🐞 bug Something isn't working scope: ssr
Projects
None yet
Development

No branches or pull requests

4 participants