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

Vite dev server crashes Remix / React when reloading after finding new dependencies to optimize #10156

Open
astonfuture opened this issue Oct 23, 2024 · 20 comments

Comments

@astonfuture
Copy link

Reproduction

https://github.com/astonfuture/remix-vite-optimize-dependency-crash

  1. Run the dev server and force clear vite's cache:
    npm run dev -- --force or delete node_module/.vite then npm run dev

  2. Navigate to the index http://localhost:5173

  3. Directly navigate to page-two by typing http://localhost:5173/page-two in the address bar and hitting enter

  4. Vite detects the new dependency (lodash-es), runs the optimization and reloads the page which causes it to crash with hydration errors.

System Info

System:
    OS: macOS 14.6.1
    CPU: (12) arm64 Apple M3 Pro
    Memory: 68.77 MB / 18.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 21.7.1 - /opt/homebrew/bin/node
    npm: 10.7.0 - /opt/homebrew/bin/npm
    Watchman: 2024.04.08.00 - /opt/homebrew/bin/watchman
  Browsers:
    Brave Browser: 130.1.71.114
    Chrome: 130.0.6723.60
    Safari: 17.6
  npmPackages:
    @remix-run/cloudflare: ^2.13.1 => 2.13.1 
    @remix-run/dev: ^2.13.1 => 2.13.1 
    @remix-run/react: ^2.13.1 => 2.13.1 
    @remix-run/server-runtime: ^2.13.1 => 2.13.1 
    vite: ^5.4.10 => 5.4.10

Used Package Manager

npm

Expected Behavior

There should not be hydration errors which crash the page as you navigate

Actual Behavior

The reproduction repo above is the official Remix Cloudflare workers template with one extra route added. The new route imports a package (lodash-es) and uses it in the component. When you navigate to that page, vite detects the new package and runs its optimizer which causes a page reload. This causes all manner of errors and the page crashes.

Starting the dev server

> remix vite:dev --force

Forced re-optimization of dependencies
  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help

When navigating to a page with new dependencies:

7:09:40 AM [vite] ✨ new dependencies optimized: lodash-es
7:09:40 AM [vite] ✨ optimized dependencies changed. reloading

Page crashes with a white screen with console errors in the browser such as:

Uncaught TypeError: Cannot read properties of null (reading 'useState')
Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.
Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

Reloading the page after it crashes works fine, leading me to believe this has something to do with the HMR that happens when vite reloads.

@clgeoio
Copy link

clgeoio commented Oct 23, 2024

I have seen a similar thing before, but it was hard to reproduce.
I was able to reproduce the behaviour with the above repo using both Safari and Brave browsers 👍

@rorcores
Copy link

A fix for this would be great please, thank you

@brampono
Copy link

I'm also experiencing this issue! Would love to see a fix 🙏

@joshbuddy
Copy link

From what I understand, its causing a hook error due to two versions of React. But this is sort of beyond my React paygrade to solve.

@clgeoio
Copy link

clgeoio commented Oct 24, 2024

@joshbuddy, I found a similar issue on Github that suggested the same thing about different react versions.
I tried adding dedupe: ['react', 'react-dom'] to the vite.config, as suggested in that issue, however that did not fix.

I'll keep poking around to see what can I do to find where this other version of React is coming from 👀

@joshbuddy
Copy link

My guess at what is happening under the hood is that the two versions of react are coming from two different builds, and both builds are being loaded simultaneously. Conspicuously, if I do a hard refresh, Safari behaves normally again.

@astonfuture
Copy link
Author

I think the hard refresh fix is due to the fact that the new optimized dependency is already loaded in node_modules/.vite and so it's available when you refresh. The error is something to do with the fact that the optimization and reload happens in a HMR-ey way while the page is still loaded.

@joshbode
Copy link

Adding the warmup option to vite.config.ts appears to work around the issue:

  server: {
    warmup: {
      clientFiles: ['app/**/*.tsx'],
    },
  },

@alexfoxy
Copy link

alexfoxy commented Nov 7, 2024

I'm running into this issue. Seems to be specific to safari in my case, on iOS and mac. @joshbode your config has somewhat helped but it still seemed to happen on occasion. Very strange - and annoying!

@f5io
Copy link

f5io commented Nov 16, 2024

i'm also running into this issue, thought i was going mad, unfortunately @joshbode's config didnt seem to help. i'm migrating an older remix app to the new vite approach and attempting to get it running on cloudflare workers. a simple page refresh after the error is hit and everything is hunky-dory, but its not a great dev-experience.

@astonfuture
Copy link
Author

i'm also running into this issue, thought i was going mad, unfortunately @joshbode's config didnt seem to help. i'm migrating an older remix app to the new vite approach and attempting to get it running on cloudflare workers. a simple page refresh after the error is hit and everything is hunky-dory, but its not a great dev-experience.

This is exactly the behaviour we're seeing and it's also a migration from an older remix on CF workers to vite.

@halljus
Copy link

halljus commented Nov 20, 2024

I was hoping the combination of #9921 and enabling unstable_optimizeDeps would fix this, but unfortunately that was not the case. 🙁

@sebastien-comeau
Copy link
Contributor

sebastien-comeau commented Nov 22, 2024

Check if this PR #10258 fixes your issue. I have similar issue on Windows for a while and and I decided to debug it. Seems to be related on how Remix build the route's file path into the optimizeDeps.entries Vite config.

@halljus
Copy link

halljus commented Nov 22, 2024

Check if this PR #10258 fixes your issue. I have similar issue on Windows for a while and and I decided to debug it. Seems to be related on how Remix build the route's file path into the optimizeDeps.entries Vite config.

I've only had the chance to test this in one app so far, but it's looking good! I haven't seen the annoying behavior since applying this patch. 🎉 🤞

@sebastien-comeau
Copy link
Contributor

Check if this PR #10258 fixes your issue. I have similar issue on Windows for a while and and I decided to debug it. Seems to be related on how Remix build the route's file path into the optimizeDeps.entries Vite config.

I've only had the chance to test this in one app so far, but it's looking good! I haven't seen the annoying behavior since applying this patch. 🎉 🤞

Nice! The problem is both how Remix generate the optimizeDeps.entries config option and also Vite's using tinyglobby that doesn't convert \ to / on Windows as fast-glob do. Vite switch to tinyglobby in PR #18243. Read my Remix's PR comment.

@sebastien-comeau
Copy link
Contributor

@halljus I've configure the entries path manually using fast-glob pattern based on what Remix is returning. Hopefully I can remove it once Remix or Vite fix it. That way I don't have to patch @remix-run/dev package.

@brophdawg11 Is your team can look at this issue? I suggest to check with Vite and tinyglobby devs to fix this issue all together. Thanks

optimizeDeps: {
  // Configure Remix plugin optimizeDeps entries since is has a bug on Windows
  // TODO: Check if the issue has been fixed
  // @see https://github.com/remix-run/remix/pull/10258
  entries: ['./app/entry.client.tsx', './app/root.tsx', './app/routes/**/*.tsx'],
},

@halljus
Copy link

halljus commented Nov 22, 2024

@sebastien-comeau FWIW, I only patched @remix-run/dev, I did not manually specify entries. Are you say they both work, and you only need one or the other?

@sebastien-comeau
Copy link
Contributor

@halljus Correct, I wish Remix or Vite wouldn't cause that issue but for now I prefer specify it and remove it when it's fixed. I've used patch-package to patch @remix-run/dev version 2.14.0 and had to do it again today since version 2.15.0 was released today. I decided to specify the entries in Vite config instead of patching Remix.

@clgeoio
Copy link

clgeoio commented Nov 26, 2024

Interesting insights @sebastien-comeau, given that OP is running macOS 14.6.1, do you expect to see similar behaviour there given that you've highlighted Windows in your comments?

@sebastien-comeau
Copy link
Contributor

I don't know @clgeoio. @astonfuture would have to test on his side to see if it's related.

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

No branches or pull requests