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

HMR not working when using react -> @preact/compat override in package.json #76

Open
bhallstein opened this issue Jun 5, 2023 · 2 comments

Comments

@bhallstein
Copy link

bhallstein commented Jun 5, 2023

Edit: I initially thought it was a dynamic backend that was causing this issue, this turned out to be wrong. Skip to my next comment as what I wrote here turned out to be a red herring.

Our project uses a dynamic backend. I'm trying to switch it to use preact and @preact/preset-vite is looking like almost a drop-in replacement, which is fairly amazing.

However, HMR isn't working. On https://vitejs.dev/guide/backend-integration.html for HMR with react we have this:


<!-- if development -->
<script type="module" src="http://localhost:5173/@vite/client"></script>
<script type="module" src="http://localhost:5173/main.js"></script>
...

Note if you are using React with @vitejs/plugin-react, you'll also need to add this before the above scripts, since the plugin is not able to modify the HTML you are serving:

html
<script type="module">
  import RefreshRuntime from 'http://localhost:5173/@react-refresh'
  RefreshRuntime.injectIntoGlobalHook(window)
  window.$RefreshReg$ = () => {}
  window.$RefreshSig$ = () => (type) => type
  window.__vite_plugin_react_preamble_installed__ = true
</script>

(When the above is included in our served HTML with this preset in use and react removed, it errors in the browser console, so I assume it is not to be included when using this preset, though I'm not entirely confident in that.)

This leads me to wonder if there is an equivalent piece of code that is missing from our dynamically served backend when using this preset?

@marvinhagemeister
Copy link
Member

marvinhagemeister commented Jun 6, 2023

Thanks for filing an issue. Can you share code or the steps with which we can reproduce the issue? Happy to look into it.

@bhallstein
Copy link
Author

bhallstein commented Jun 6, 2023

Thanks so much for your reply. I tried to reproduce, found I couldn't, then spent a few hours looking into this.

Rather, it turned out that:

  1. I had used overrides in package.json to get around the react-in-peer-deps issue:
"overrides": {
  "react": "npm:@preact/compat@17.1.2",
  "react-dom": "npm:@preact/compat@17.1.2"
}
  1. Because I was converting a previously-react codebase, our top-level jsx file had import {render} from 'react'. 'react' was being resolved by vite to /node_modules/react-dom, which returned a copy of @preact/compat, which had been installed in that folder due to the use of the overrides above.

  2. Changing the import to import {render} from 'preact' caused hmr to start working 🎉

  3. Strangely, before making this change, hmr would work, but only in the top-level file, not in any files imported by it.

I'm not sure how to explain all the above. I suspect that when importing render from react, resolving to @preact/compat due to package.overrides, this contained a slightly different code path compared to when it is imported from preact; and that this was for some reason affecting the top level file and every other file in different ways. I'm noting that this preset aliases react-dom to preact/compat (without the @), it seems the overrides npm option as above interacts badly with this.

That's a bit vague for my liking but I'm not sure I can pin it down any further with only limited knowledge about preact, @preact/compat, preset-vite, and vite itself.

This also leaves me unsure if using overrides as above is a bad approach to have preact installed (and also prevent react being installed) in any other respect. I don't know if there's a recommended way, if so I wonder if it could be that the readme for this plugin could mention?

(I've updated the title and description in this issue to make clear it turned out not to have anything to do with the presence of a dynamic backend.)

Edit: Just removing overrides from package.json and using npm install --legacy-peer-deps did the trick — feel free to close issue.

@bhallstein bhallstein changed the title HMR not working with dynamic backend HMR not working when using react -> @preact/compat override in package.json Jun 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants