mindplay-dk / php-vite

a lightweight PHP-backend integration package for Vite
Mozilla Public License 2.0
30 stars 2 forks source link

Whole page reloads when JavaScript file changed #2

Closed NateWr closed 3 weeks ago

NateWr commented 1 month ago

This is great, thanks! I've got it set up and working. When I change a .css file, the HMR works correctly. But when I modify a JavaScript file, the whole page reloads. I noticed the same behaviour in your example app.

Is this a known limitation or is it possible to get module-level refresh for the JavaScript? Thanks!

mindplay-dk commented 4 weeks ago

I'm pretty sure it worked at the time when it was published.

Apparently this is a common issue:

https://stackoverflow.com/questions/70996320/enable-hot-reload-for-vite-react-project-instead-of-page-reload

I tried every suggestion in the replies and it still reloads the page instead of hot reloading the module.

Are you in WSL2 as well? It seems many people have problems with HMR on WSL2.

If you figure it out, please let me know.

NateWr commented 4 weeks ago

I'm on Ubuntu so not in WSL2. I'll let you know if I stumble on anything, thanks.

mindplay-dk commented 4 weeks ago

You didn't find a solution, did you? I'm going to keep this open for the sake of transparency.

mindplay-dk commented 3 weeks ago

Okay, so I think I have an answer for you. 🙂

By now, you've probably realized your own project behaves the exact same way?

I went and asked about this on the Vite discord:

https://discord.com/channels/804011606160703521/1290963623954616362/1290963623954616362

Someone pointed me to this very long article, which I don't recommend reading at length - it's mostly directed at framework authors:

https://bjornlu.com/blog/hot-module-replacement-is-easy

TL;DR & TIL: HMR does not work the way I assumed it did. 😅

I always assumed there was some magical source transform happening by default - there is not. State preservation has to be explicitly handled using the HMR APIs, and frameworks that support HMR do similar things under the hood. For example, HMR implementations for React and Vue handle things like storing/restoring component state, re-rendering with preserved state, cleaning up effects, etc.

In short, hot reloading doesn't normally work with vanilla JS/TS modules.

I wanted to prove this to myself, so I migrated my example to Preact, and yes, it works:

https://github.com/mindplay-dk/php-vite-mpa/compare/preact-hmr-in-example

So as long as you have either a plugin or a module that explicitly handles HMR, it'll work. 🙂

Question is, should I merge the Preact example to the demo repository? Would that help set expectations and make things easier to understand? I wanted to keep the example as simple as possible, but I guess most people aren't going to build without a framework, so maybe it's better to demo something with working HMR to avoid confusion? 🤔

NateWr commented 3 weeks ago

Ahh, that makes total sense. The demo is probably useful as an example, if it's not much work for you to maintain.

For my use case, selective HMR is not that important because we aren't (typically) using a JS framework in theme projects.