pmmmwh / react-refresh-webpack-plugin

A Webpack plugin to enable "Fast Refresh" (also previously known as Hot Reloading) for React components.
MIT License
3.13k stars 192 forks source link

No HMR re-render when using react-refresh-webpack-plugin with a react module in a microfrontend architecture #502

Closed nilzona closed 2 years ago

nilzona commented 3 years ago

I have built an example repo to reproduce the issue: https://github.com/nilzona/sspa-hmr

In short the problem occurs when building a react based microfrontend module using the single-spa libraries. When serving that module with webpack@v5, webpack-dev-server@v4 and react-refresh-webpack-plugin@v0.5.0-rc.6 Everything seems to work but a change is not applied to the dom.

Any help would be greatly appreciated.

frehner commented 3 years ago

Just a quick glance, and it appears you're using a local override (which is good!) but also using the production version of React/ReactDOM - and HMR won't work on the production version of React/ReactDOM. If you use the development version of React/ReactDOM, does HMR work then?

nilzona commented 3 years ago

hey @frehner. I enabled the devlibs on import-map-overrides so that it uses dev-versions of react. It still doesn't work.

frehner commented 3 years ago

Another thing to try is to set the webpack public path, as outlined in the docs https://single-spa.js.org/docs/faq/#code-splits

Do you get any errors anywhere? I would test it out, but I don't necessarily want to go through the hassle of setting up a ssl cert.

nilzona commented 2 years ago

hello @frehner .. I noticed that the issue is reproducible with a much simpler setup. Only running locally and no https/ssl certs. I have updated the example repo so that it's really simple to run and reproduce the issue.

The two projects in the example repo is generated with create-single-spa@latest and the react-project is configured with the react-refresh-webpack-plugin to support HMR.

As I understand it the publicpath is handled with the webpack-plugin added by create-single-spa

frehner commented 2 years ago

Your latest example does not have React and React-DOM in the importmap - note the console error you get when you run your app.

Once you add the development version of those, then HMR works correctly. Here's a recording of it working on my machine:

https://user-images.githubusercontent.com/3054066/133125384-63d30c0b-626e-4ca6-a509-35c8d1abd919.mov

I think this can be closed at this point.

nilzona commented 2 years ago

Hey @frehner thank you for looking into this. You're right that the react libraries were not in the import-map. It worked for me because of older import-map-override entries in localStorage. I have now added the react libraries but I still have the issue :( ... I see that your example is working which is great, but did you do anything else than just adding those?

hmr-issue
frehner commented 2 years ago

Nope, all I did was add those libraries and run the project. Not sure what’s going on with your machine

nilzona commented 2 years ago

@frehner .. have you tried to run it with Google Chrome. That's the browser I use.

pmmmwh commented 2 years ago

I think this is working probably due to usage of ReactDevTools ...

See https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/main/docs/TROUBLESHOOTING.md#externalising-react

nilzona commented 2 years ago

@pmmmwh .. that was it! react-refresh needs to be loaded before the react-libraries which is normally done when you webpack bundles, but not in this case. Enabling react-developer-tools extension in chrome will however bring in react-refresh in correct order.

so conclusion is that if react and react-dom is loaded before the module that enables HMR with webpack-dev-server, then react-refresh needs to be loaded before which can be easily achieved with the React Developer Tools plugin for your browser.

yuhubing11 commented 1 year ago

hello! Is this solved?