react-native-universal-monorepo: Dependencies, that have `react-native` as a `peerDependency`, resolve to the wrong version of `react-native`

Thanks for such a great monorepo setup

It works great out of the box, but as soon as i started to add dependencies, that use react-native, it stopped working for me.

  • mobile(depends on react-native@0.65.1)/reanimated/react-native => resolves to react-native@0.65.1
  • tv(depends on react-native-tvos@0.64.2)/reanimated/react-native => resolves to react-native@0.65.1 instead of react-native-tvos@0.64.2

I tried all combination of nohoist and resolutions, but i was not able to set version of nested react-native dependency of dependencies of platforms. Any hints?

About this issue

  • Original URL
  • State: open
  • Created 3 years ago
  • Reactions: 2
  • Comments: 21 (7 by maintainers)

Most upvoted comments

Thanks for reporting all, these info are super helpful 👍

I’m gonna give it a try soon.

Just FYI, @todorone :

but it’s relevant to any dependency that depends on react-native and needs to be nohoisted)

Unless something changed in yarn or in the new react-native version, I’m pretty sure this is something that can be solved with some tweaking. It’s not happening on all libs that depend on react-native (see @react-native-async-storage, for example, which is part of this repo). I’m wondering if the libraries you’re using depend on other native libraries as well, which sometimes break yarn resolution algorithm — this happened a few times to me in the past and I solved it by adding the nested libraries to the nohoist as well (e.g., with **/react-native-reanimated, **/react-native-reanimated/**).

Also, just to clarify: react-native-monorepo-tools (currently) doesn’t update/move packages around, so this would be something happening at the yarn level.

I’ll give it a try soon and get back to you.

Share my experience with yarn v3. It works great, everything is smooth, even consuming native dependencies. Until today I was very happy.

But today I tried to patch native dependency which uses JSI C++ code https://github.com/ospfranco/react-native-quick-sqlite and it’s completely broken.

Native dependencies require exact package location (since they require native parts in C++ using “…/…/react-native/…” paths). Symlinking them makes packages broken (they can’t find react-native using these paths since packages are symlinked). And Yarn v3 gives no control on how to fix this.

https://github.com/ospfranco/react-native-quick-sqlite/blob/e736497166481bbb14a6a9da1df6691ccbee1204/android/CMakeLists.txt#L37

But the story is even worse 😢 I can’t even switch back to yarn classic for the exact repository. Even if I directly clone yarn@1.22.10 by npm pack and run node ./yarn.js -- --version it gives incorrect (globally installed) version 3.0.2. So yarn v3 completely broke everything in that regard. Of course, neither I can easily switch back to yarn classic completely 😠 (since using yarn v3 features).

I just can’t now develop native code (the happy part it’s not mandatory for me).

@serge-sky , yeah, seems similar to the fix I mentioned above 👍 PRs to the monorepo tools are welcome!

I completely agree with @mmazzarolo that the best option is to do the best to maintain compatibility with Yarn classic if it’s possible. There is a reason why Yarn 2+ has low adoption - there was a pretty heated discussion between the community(including Facebook and some other companies employees) and the current Yarn maintainer, which did not want to follow propositions of maintaining compatibility with the classic Yarn.

In the case it’s not possible at all, switching to the new Yarn is also the way, but there will be serious friction about it…

From my research the only symlinks I have under node_modules in example application are my monorepo packages. Снимок экрана от 2021-10-23 22-21-50

So the question is do we need to keep all these nohoist things (since they only now used by metro.config.js)? Since all these nohoist packages are already directly copied to node_modules/ by yarn v3 automatically.

I think we can remove most of metro.config.js changes if not all. For my setup we only need to resolve symlinked monorepo packages (and it’s dependencies?)

For the original article (where different RN are used) I think only shared example-app need to be resolved.

@mmazzarolo Sorry for the delay, i put the simple repro - https://github.com/todorone/react-native-universal-monorepo with one simple commit of adding react-native-reanimated(but it’s relevant to any dependency that depends on react-native and needs to be nohoisted)

Result of running yarn: mobile/node_modules/react-native-reanimated/node_modules/react-native/package.json // 0.65.1 - is ok tv/node_modules/react-native-reanimated/node_modules/react-native/package.json // 0.65.1 - is not ok, as we use a custom fork of RN 0.64.2 so it breaks Metro bundler

Please let me know if any further clarification is needed and thanks again for working on such a cool monorepo setup.