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

[BUG] using a workspace instead of a separate repo leads to having 2 react versions instead of 1 #4557

Closed
2 tasks done
Ognian opened this issue Mar 12, 2022 · 10 comments
Closed
2 tasks done
Labels
Bug thing that needs fixing Documentation documentation related issue Priority 2 secondary priority issue Release 8.x work is associated with a specific npm 8 release

Comments

@Ognian
Copy link

Ognian commented Mar 12, 2022

Is there an existing issue for this?

  • I have searched the existing issues

This issue exists in the latest npm version

  • I am using the latest npm

Current Behavior

  1. new empty directory
  2. npm init -y
  3. npm i react@16
  4. npm init -w packages/a -y
  5. cd packages/a
  6. npm i react@17
  7. npm i @emotion/react
  8. npm ls react

and we see here 2 versions of react wich is wrong
image

Expected Behavior

I would expect the same behavior as if it would be without a workspace

  1. new empty directory
  2. npm init -y
  3. npm i react@17
  4. npm i @emotion/react
  5. npm ls react

image

This is a reduced test case. The actual problem is more complex, there are 2 workspaces with different react versions and no react dependency in the root. Other workspaces no react but they are dependencies of the react ones (so I need workspaces).

Steps To Reproduce

see above

Environment

  • npm: 8.5.4
  • Node.js: 17.6.0
  • OS Name: macOS
  • System Model Name: MBP
  • npm config:
; "user" config from /Users/ogi/.npmrc

@ogi-it:registry = "http://localhost:4873/" 
//localhost:4873/:_authToken = (protected) 
//registry.npmjs.org/:_authToken = (protected) 
scripts-prepend-node-path = true 

; node bin location = /usr/local/bin/node
; cwd = /Users/ogi/Repositories/junk/doubreact
; HOME = /Users/ogi
; Run `npm config ls -l` to show all defaults.
@Ognian Ognian added Bug thing that needs fixing Needs Triage needs review for next steps Release 8.x work is associated with a specific npm 8 release labels Mar 12, 2022
@Ognian
Copy link
Author

Ognian commented Mar 12, 2022

from this #2924 i learned that there is a --global-style option when installing.
This helped with the reduced test case.
In the real repo I hit #3847 when doing the npm i --global-style in the packages/xxx directory.
I tried npm i --global-style in the project root and this time it worked.

So please, please, please, could someone knowing what is going on here document this in the official documentation?

@wraithgar wraithgar added Documentation documentation related issue Priority 2 secondary priority issue and removed Needs Triage needs review for next steps labels Mar 14, 2022
@wraithgar
Copy link
Member

The reason this is happening is because @emotion/react is hoisted to the root project. And since it lists react": ">=16.8.0 for its peerDependencies, the already present react@16 in the root suffices, and nothing more is installed.

@Ognian
Copy link
Author

Ognian commented Mar 17, 2022

@wraithgar thanks for your answer.
The actual reason why I migrated to workspaces was the following:

I have a monorepo where some of the packages are react component libraries.
So these packages have peer dependencies to react and dev dependencies to react also, since they have small test programs for the react component they provide.

There are other packages in this monorepo using these components they have a specific react version they use and have the react component packages as dependencies. BUT how to include the component packages here? Deploying to a local repo and using them in a specific version is not practical solution (every small change requires publishing a version ), linking to them via file: has the big disadvantage, that the dev dependencies are also installed (since it is a link to the node_modules of the react component in dev mode) wich leads again to 2 versions of react...

From your answer I understand that workspaces and plain npm install doesn't work either.

npm install --global-style worked in my case BUT I'm not sure if this always will work or if this was just a lucky coincidence...

For me it looks like we desperately need 3 subfolders under node_modules, dependencies, devDependencies and peerDependencies and the file: protocol links only to the node_modules/dependencies folder ...

Or is there anything else I have missed?

Thanks
Ognian

@wraithgar
Copy link
Member

Are you trying to make sure everything gets the same version of react, or everything gets the same copy of react?

There isn't any real way to guarantee that every module in your tree is getting the same identical copy of a dependency they require as the other modules. The nature of hoisting and deduping makes this so. Relying on this is bound to have issues.

If you need everything to have the exact same version of react, perhaps overrides could be a path forward for you.

@Ognian
Copy link
Author

Ognian commented Mar 19, 2022

As far as I understand, npm should "only" ensure the same version of react as a dependency of all packages, webpack assures then, that there is only a single instance of react in the app.

Some more info is here. Looks like "yarn resolutions" is the same like "npm overrides" (and I have somehow missed that...)

I'll try now to switch to overrides and report back.

Thanks
Ognian

@Ognian
Copy link
Author

Ognian commented Mar 25, 2022

I switched back from workspaces to the default behavior. I tried overrides for one of the packages but they don't help, since monorepo dependencies are linked, and linked means directory link. And if some sub-dependency is installed (no matter if normal or dev dependency) then it is there.
At the moment my app's are again working, but this is based solely on the fact that I removed some problematic packages und updated some others with newer versions...
I would still suggest to subdivide node_modules in 3 directories, dependencies, devDependencies and peerDependencies, and install them in this directories accordingly. Then linking a monorepo package can link to the dependencies subdirectory only.

@wraithgar
Copy link
Member

That would be a pretty significant change to how workspaces work and would need to go through the rfc process. Closing this now as it things are currently working as designed, and changing it would mean changing the design.

@daksh-sagar
Copy link

Hey @Ognian
i'm also facing a similar issue in my project (using turborepo with npm workspaces) and i also see multiple versions of react when running npm ls react.
I've tried overrides as well (but that doesn't work as intended in workspaces)
Did you manage to solve this issue ?

@Ognian
Copy link
Author

Ognian commented Mar 21, 2023

@daksh-sagar as mentioned in my previous comment I'm not using workspaces anymore, and by reducing package dependencies my apps work now. I don't think that there will be any other solution for this problem.

@daksh-sagar
Copy link

cool
thanks @Ognian :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug thing that needs fixing Documentation documentation related issue Priority 2 secondary priority issue Release 8.x work is associated with a specific npm 8 release
Projects
None yet
Development

No branches or pull requests

3 participants