Upgrading to npm7 but too many library breaks

Viewed 781

Been using NPM version of 6.14.7 and decided to move on with NPM version 7.20.1 for my react-native project. Soonest as I try npm install, most of my libraries break with the error of Could not resolve dependency:

Example(s)

// example 1
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.8" from @react-native-community/async-storage@1.12.1

// example 2
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.0" from @react-native-community/picker@1.8.1

// More Example(s)
..
...
.....

FYI, am aware the breaking change of peer dependencies announcement made by NPM team. Need some guidance here, how can I upgrade my npm version seamlessly?

Automatically installing peer dependencies is an exciting new feature introduced in npm 7. In previous versions of npm (4-6), peer dependencies conflicts presented a warning that versions were not compatible, but would still install dependencies without an error. npm 7 will block installations if an upstream dependency conflict is present that cannot be automatically resolved.

Of course, I'm aware with the following options. If I were to execute npm install --legacy-peer-deps, isn't this the same as if Im using NPM 6? Since it's only by passing the auto installation peer dependencies.

You have the option to retry with --force to bypass the conflict or --legacy-peer-deps command to ignore peer dependencies entirely (this behavior is similar to versions 4-6).

Decision

Just to share my thoughts, hopefully to help others.

After more read up (link1, link2)over NPM7 and comments shared by @Dan Macák and @M. Erim Tuzcuoglu, I've decided to stay with NPM6 for the moment.

Mainly I think the efforts and risk is way higher than the rewards by upgrading to NPM7? I anyway don't need the new features shipped in NPM7

I have also tried using NVM suggested by @M. Erim Tuzcuoglu, then switch using different NVM + NPM eventually hitting 1 issue from xcode (Command PhaseScriptExecution failed with a nonzero exit code). I think the reason was nvm is not compatible with the "PREFIX" Many has faced this issue and came up with some solutions, but I've decided not to go further as it seems complicating the project further (other team members would need to do the same settings of NVM)

3 Answers

I am afraid there is no easy way for your project to switch to npm 7. NPM decided to make our lives easier (a bit ironic given your issue) by installing peerDependencies automatically, which involves dealing with invalid dependency trees; and while this is a good thing which might prevent hard-to-find bugs (eg. due to plugins expecting different version of React than which you are using in your project and failing as a result) in case one ignores installation warnings (who doesn't miss them sometimes?), it can be a pain to do the switch.

So while NPM should take care of many dependency discrepancies itself (from https://github.blog/2021-02-02-npm-7-is-now-generally-available/):

Since many packages in the ecosystem have come to rely on loose peer dependencies resolutions, npm 7 will print a warning and work around most peer conflicts that exist deep within the package tree, since you can’t fix those anyway.

you are still required to take manual action where it fails to resolve your dependencies. You have couple options here if you still want to use npm 7:

  1. You update your dependencies in such a way that doesn't break the peer dependency requirements. So in your case you update your dependencies to use and expect the same range of versions of React. This option is of course tedious and requires retesting the affected code. But it deals with potential problems resulting from a broken dependency tree. So if running npm ls doesn't run successfully, you should give this option a thought. Unfortunately, it might prove difficult with certain packages which have very narrow peerDependencies requirements, and library authors should be very careful when specifying it.
  2. Use the --legacy-peer-deps to ignore all peerDependencies during npm i.

FWIW, if you don't have time for the former and don't want to change your workflow due to the latter, and don't need npm 7's changes really, it's perfectly fine to stay with version 6 for the moment.

I have the same issue and when I investigated it further I found that some packages have been moved that's why resolving the dependency is failing for example

@react-native-community/async-storage >> @react-native-async-storage/async-storage

I know the question is more philosophical than a problem needs a solution but I agree with npm to fix dependencies black hole and let's move on

Related