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

watch-effect behaves differently with dev-server vs. production build. #5707

Closed
SvenSchoene opened this issue Apr 12, 2022 · 5 comments
Closed

Comments

@SvenSchoene
Copy link

SvenSchoene commented Apr 12, 2022

Version

3.2.31

Reproduction link

github.com

Steps to reproduce

Run the minimal reproduction (main branch) twice: Once with the dev-server ( npm run serve) and once with a production build (npm run build).

(A) Setup:

  1. Navigate to the project in a browser.
  2. You will see three things:
    2.1 The output of the variable isWorking being set to false.
    2.2 A button titled "Set isWorking to true and change it back after 5 seconds".
    2.3 A button titled "Trigger WatchEffect".
  3. Open the browser console.

(B) Click the buttons and observe the browser console for the first time:

  1. Click the left button. This will change isWorking to true for 5 seconds, and change it back afterwards.
  2. While isWorking is still true, click the right button now.
  3. This will trigger the following console.log: "[is-working-watch-effect@startWatchEffect@watchEffect][1] Is currently working"
  4. When isWorking is changing back to false, the following console.log will be triggered: "[is-working-watch-effect@startWatchEffect][2] Is not working anymore"

(C) Click the buttons and observe the browser console for the second time:

  1. Click the left button again.
  2. While isWorking is still true, click the right button now again.
  3. This will trigger the following console.log again: "[is-working-watch-effect@startWatchEffect@watchEffect][1] Is currently working"
  4. Point of divergence:
    4.1 [DEV-SERVER] When isWorking is changing back to false, the following console.log will be triggered: "[is-working-watch-effect@startWatchEffect][2] Is not working anymore". This only happens on the DEV-SERVER-build.
    4.2 [PRODUCTION BUILD] When isWorking is changing back to false, no further console.log will be printed. This will actually not work again until the page is refreshed.

What is expected?

  1. It is expected that a Dev-Server-build and a Production-build work the same way.

  2. It is expected that watchEffect works the same every time (both lines are printed, instead of just the first).

What is actually happening?

  1. The Dev-Server build always prints both lines for watchEffect. The Production-build only prints both lines for watchEffect once. After that it will always only ever print the first line.

  2. In the Production-build watchEffect is only printing both lines once (the first time).


I spent a lot of time debugging this. Here are a few additional notes:

(I admit that it might be considered weird to stop the watchEffect from within itself. For a particular feature (=waiting until saving is done in our application) this does seem to be a sensible implementation to me.
Even if you might disagree that this is a sensible implementation, I'm sure you agree that this should behave the same in all cases.)

  • I recorded two videos of this behavior:

(A) This is a video from the Dev-Server. This is working as intended:

vue-bug-watch-effect-working-correctly.mp4

(B) This is a video from the Production-Build. This is broken / inconsistent / not working as expected / intended:

vue-bug-watch-effect-not-working.mp4

Our biggest issue is that this discrepancy is undermining the trust that we have in Vue's reactivity. We have an application with ~50 Vuex stores, hundreds of components and lots and lots of reactivity.

There have been other weird reactivity issues since upgrading to the newest version. We haven't been able to reproduce those as concisely as this one yet.

It is obviously really really important for us that our developers can come across reactivity issues in their Dev-Server builds, before it's caught later on a Staging or Live build.

@yyx990803 yyx990803 added scope: reactivity ❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. 🔩 p2-edge-case and removed ❗ p4-important Priority 4: this fixes bugs that violate documented behavior, or significantly improves perf. labels Apr 13, 2022
@SvenSchoene
Copy link
Author

I appreciate the quick fix. It looks good, can't wait to test it out!

Is there any insight on why there would be a difference between a Dev-Server and a Production-build on this matter?

Again, we wouldn't have been able to catch this issue during development-time, and that is a bit concerning.

@SvenSchoene
Copy link
Author

I wonder if this is related to this, or something like this: #5655 (comment)

@mStirner
Copy link

I have still the issue in v3.2.45.
Confirmed in v3.2.31, upgraded to v3.2.45 and the bug is still present.

@mrspartak
Copy link

Can confirm, but is there on 3.2.45

@olfek
Copy link

olfek commented Feb 10, 2023

I'm seeing the exact same issue with watch() on 3.2.45 as does @mStirner , can someone reopen this please. @yyx990803 ?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

5 participants