I’ve been working on a project with Vite & React, using
@vitejs/plugin-react. I would’ve expected that if we’re able to leverage the standard Vite React plugin, we could benefit from HMR, but it doesn’t seem to be the case. The tiniest changes, eg. a change to a
className, causes a full page reload.
Is there something about
vite-plugin-rescript that conflicts with React HMR, or is there something I need to configure correctly?
I did a bit more research on this, and hit upon this caveat about React HMR:
The reason why it doesn’t work is that the additional export is not considered as a component (well,
CamelCase functions/classes). If a file contains any exports that is not a component, the transform will not mark the component as side-effects free. This is important because anything else other than a component is generally not guaranteed to be side-effects free, but if there are side-effects, to have HMR work properly someone would need to work on cleaning up the side-effect, which is not possible cause what effect it is firing is unknown.
The way I understand this comment, the React plugin will mark modules with non-component exports as impure, and thus disables HMR when those files change. And to count as a component an export has to be both PascalCased and a function.
Could it be that fundamentally the compiled
.bs.js subverts HMR by exporting either modules (a PascalCased object containing a
make function), or a
make function by itself (not PascalCased)? Do we then need to build in a Rescript-specific version of React HMR into
For what it’s worth, have you tried to create interface files (
*.resi) for each (
*.res) file? Fast Refresh* requires you to only export React components.
*: Fast Refresh is enabled in development in
I have now tried making a
.resi file for my main component (
Game.res). It doesn’t seem to help: when I make an edit, even to a single className, state is reset.
.resi file in place, the output
.bs.js file ends with:
var make = Game;
/* Form Not a pure module */
As I already noted, I worry that
make isn’t recognised as a component export because it isn’t PascalCased. Though I did experiment with editing the
.bs.js file directly to export
Game directly. That didn’t seem to help either.
I’m curious what the “not a pure module” comment is all about at the end. I don’t suppose it has any bearing on this issue?
Have you experienced Fast Refresh working in your own projects? Should I expect it to work, if I set things up right?
It’s definitely working with my setup but I remember there were some gotchas like correctly setting up include, that’s why I even created a small repo for a working setup.
Could you try to downgrade
v4.0.1 and see if it helps?
I delved into the issue a bit, I believe the Fast Refresh stops working after you upgrade to @email@example.com or above.
edited: Or, you could try to upgrade to
v4.1.0 which includes the fix.
Sorry it’s taken me a while to get back to this, but it seems you’re right that
4.0.2 is the problem version. Downgrading to
4.0.1 but also upgrading to
4.1.0 works! (As long as I also lock down all my component files with