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

deno install with incorrect peer dependencies installs incompatible React versions #26841

Open
alexgleason opened this issue Nov 12, 2024 · 3 comments
Labels
bug Something isn't working correctly install

Comments

@alexgleason
Copy link
Contributor

alexgleason commented Nov 12, 2024

Version: Deno 2.0.6

So... I am migrating a legacy React Vite project from Node+Yarn to Deno.

When I run deno install followed by deno run -A npm:vite serve, the page crashes in the browser with a runtime error from React:

Error: 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:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

I have narrowed this problem down to multiple incompatible React versions being installed by deno install. It installs 3 different versions of React:

Screenshot from 2024-11-12 13-15-26

The problem is actually that I have incorrect peer dependencies in my project. When I run yarn normally, it's full of peer dependency warnings. I understand this is a problem with my project, but it's not easy to fix. It's caused by some of my libraries having a peer-dependency on React 16 or 17, while my project has been upgraded to React 18 (which yarn allowed me to do).

image

If I use yarn to set up node_modules, and then use deno run -A npm:vite serve, it all works perfectly. So the problem is related to the behavior of deno install and not the Deno runtime itself.

As for the solution, I think Deno should at least warn about peer dependencies. I am not sure if there's a standard expected behavior among package managers about what to do in this scenario, or if there are any workarounds besides replacing these unmaintained packages with forks. (EDIT: I tried specifying overrides to react 18 in package.json and it had no effect.)

For reference, this is the project: https://gitlab.com/soapbox-pub/soapbox

(I feel bad that Deno is burdened by this legacy Node crap, but I thought you would rather know than not know. 🥲)

@nathanwhit
Copy link
Member

Hmm I think this falls out of the way that we autoinstall peer dependencies. Maybe we shouldn't do the autoinstall if the user has a version of the peer dep already installed at the top level, and instead warn if the version is wrong (like yarn/pnpm does)

@alexgleason
Copy link
Contributor Author

I think that's a good idea @nathanwhit

To be sure, I re-read the definition of peerDependencies:

Trying to install another plugin with a conflicting requirement may cause an error if the tree cannot be resolved correctly.

Thinking about this logically, it suggests to me that only one version of the package is meant to be installed. Whether to throw an error (or warn and take one of the versions) is an implementation detail of the package manager.

In fact, I tried npm install of the very same project and it does indeed throw an error!

image

But to get around it, I can use npm install --force, which works. It does the same thing as yarn and installs only the version specified in my package.json (React 18 in this case).

I think either of these solutions would be good. I have a slight preference towards the way yarn does it, to warn instead of requiring a --force flag. But I am biased because my project is already broken. 😅

Now that I understand fully, I realized this issue is mostly a duplicate of #26145

#20614 #17286 are also related.

@bartlomieju bartlomieju added bug Something isn't working correctly install labels Nov 22, 2024
@KyleJune
Copy link
Contributor

KyleJune commented Jan 1, 2025

I encountered this when trying to fix an issue with esbuild_deno_loader. Here is a link to that issue. After applying the fix of it not my deno.json file when calling deno's info command, I found my react project was still not working.

The issue can be reproduced by trying to use react-error-boundary@5.0.0 with react@18. Here is the package.json showing it depends on react@19.

This was making it difficult to migrate to react 19 which was recently released. The reason it complicates it is that there are many packages that have not been updated to depend on react 19, but are compatible with react 19. If we were able to override the version, we could successfully migrate to react 19. Without it, we have to stay on react 18 and make sure we are using a version of each dependency that is still using react@18, otherwise, we will end up with 2 versions of react.

If you use multiple versions of react, your application will get unexpected application errors like the one shown below.

image

The workaround for this is to use older versions of dependencies to ensure all dependencies are using the same version of react.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working correctly install
Projects
None yet
Development

No branches or pull requests

4 participants