yarn icon indicating copy to clipboard operation
yarn copied to clipboard

yarn link uses peerDependencies from wrong node_modules

Open Wunsz opened this issue 4 years ago • 7 comments

Bug description

Yarn link/install follows devDependencies of linked package in linked package modules. Same happens for file if not pointed to the compiled dependency.

Command

yarn link
yarn install

What is the current behavior? When you create two projects, say, a react library react-lib, and in the same repo you want to use it in other react application react-app, and link the react-lib to react-app, yarn somehow uses packages specified in peerDependencies from devDependencies of react-lib to components from react-libs instead of the packages from react-app.

Furthermore, packages from react-app correctly use their own dependencies.

This does not happen, if i use file and point to the dist directory instead of link. However, then I loose ability to work on the library without running yarn install --force each time i make a change in the library.

It does not matter if one uses:

cd react-lib
yarn link
cd ../react-app
yarn link react-lib

or adds entry in package.json:

    "react-lib": "link:../react-lib",

What is the expected behavior? devDependencies should not be linked/exported, peerDependencies should be loaded from react-app node_modules.

Steps to Reproduce Clone this repo: https://github.com/Wunsz/yarn-link-problem

Run:

cd yarn-link-problem/react-lib
yarn install
yarn start

after that, in the other terminal

cd yarn-link-problem/react-app
yarn install
yarn start

You will see a blue Material UI button. However, in react-app, a theme is specified that should make this button green. If one changes link:../react-lib to 'file:../react-lib/dist` and reruns above process, the button will be green.

Note that one has to specify the compiled dist directory! Otherwise same as above happens an the button is blue.

Furthermore, Material UI Core module in react-lib and react-app are different.

Note

This applies to every package specified in peerDependencies and devDependencies. For react, the workaround was to remove react and react-dom and add @types/react and @types/react-dom. If this is not done, react will throw errors about multiple versions of react.

Environment

  • Node Version: 14.0.0
  • Yarn v1 Version: 1.22.4
  • OS and version: Ubuntu 18.04

Wunsz avatar May 07 '20 09:05 Wunsz

for those wondering; I ran into the same issue and used yalc to fix my problem.

driescroons avatar May 04 '21 18:05 driescroons

This is an issue that seems like it will continue to get worse over time as native module loading becomes the norm. FWIW — you can have some success using moduleNameMapper to force jest to perform explicit lookups, but ultimately you end up being responsible for dependency hell.

I think @driescroons suggestion to use a tool like yalc that actually hard-copies your linked dependencies is currently the only viable solution for large/mid scale projects

justin-schroeder avatar Jan 25 '22 21:01 justin-schroeder

I think I'm restating what's already been said here but here's my take on what I'm experiencing I'm working on an app and I have a package that I'm yarn linking in to the app.

  • run yarn link in myPackage
  • run yarn link "myPackage" in myApp...
  • myPackage specifies somePackage as a peerDependency in myPackage/package.json - so somePackage will not be installed by myPackage because it expects it to be installed by its parent (myApp in this case).
  • myApp specifies somePackage as a dependency in myApp/package.json

The dependency in myApp should satisfy the peerDependency in myPackage but instead the module is not found. Presumably, as is originally stated in this issue, because it's referencing the devDependencies in myPackage/node_modules instead of myApp/nodeModules

That seems broken 🤔 I shouldn't have to install somePackage as a dependency in myApp, right?

update: yalc worked for me 🙂. Thanks @driescroons

gpspake avatar Feb 15 '22 23:02 gpspake

I had a similar issue where adding a package via yarn link to a project would break unrelated things (whereas the two projects worked fine on their own, or if I'd use the package without yarn link).

I think it's because the linked package's dependencies will take priority (this issue) and they used different versions than my main app's dependencies. I.e. I had "typescript": "^4.2.3" in my main app but "typescript": "^4.6.3" in the linked package. The ^ would allow my main app to resolve this dependency to the version in the linked package, breaking typescript in the main app. This was confusing because there was no change in the main project's yarn.lock that would indicate that the typescript version changed.

I got around this by having exact dependencies in the main project. I.e. "typescript": "4.2.3". I don't think this solves the root cause but it makes sure I know exactly which dependency is loaded, in which case I don't care where it is loaded from.

thisismydesign avatar Aug 16 '22 14:08 thisismydesign

I encountered the same problem today, when updating to React 18 (probably was there before, just hadn't notice). I have a component library with peer dependencies and an example app in the same repo. The package.json in the subfolder called example references the component library like this: component-library: "../".

I get errors saying the example app uses multiple versions of React and styled-components, even thou they are only peer (and dev) dependencies in the library. If I delete node_modules in the library, the example app stops working, with error messages pointing to the library's deleted node_modules.

I had react and react-dom in devDependencies (for some reason), I removed them (keeping @types/react(-dom)) and now it works. However, I still need styled-components as the typings are included in the bundle in that case.

Not sure if there is something I'm doing wrong, but I would expect the example app to resolve modules from the local node_modules instead of the library's node_modules.

tengl avatar Oct 19 '23 08:10 tengl

I'm not sure how much of yarn is built on top of npm, but I reported a similar NPM issue today: https://github.com/npm/cli/issues/7171

DanKaplanSES avatar Jan 23 '24 02:01 DanKaplanSES

As a vite user that also hit this problem, I've had some success using dedupe in the vite.config.js (e.g. resolve: { dedupe: [ 'dependency-name', ...] }) to workaround it. It forces the build to use the dependency from top-level app's node_modules.

woodcoder avatar Jun 04 '24 16:06 woodcoder