Why are certain conflicting peer dependencies resolved when you remove the package-lock.json and node modules - npm

Context
I joined a new project where I was asked to upgrade React from version 17 to 18. After upgrading react and react-dom and some other dependencies I got some warnings, which had to do with dependencies.
npm install react#latest react-dom#latest
Some of them I was able to resolve easily, by updating some packages. This was until I tried resolving the following warning:
npm WARN Conflicting peer dependency: react#17.0.2
npm WARN node_modules/react
npm WARN peer react#"^16.3.0 || ^17.0.0" from react-side-effect#2.1.1
npm WARN node_modules/react-helmet/node_modules/react-side-effect
npm WARN react-side-effect#"^2.1.0" from react-helmet#6.1.0
npm WARN node_modules/react-helmet
Already I am a bit surprised by the react#17.0.2. Apparently there is another version of React still in dependencies, that is required by another package.
Package that requires React 17.0.2
"<CUSTOM PACKAGE MADE BY SOMEONE ELSE>": {
"version": "0.3.0",
"resolved": <LINK>,
"integrity": "sha1-Ah72HLxApcdcSPGRIE/L7wjy8Ec=",
"dependencies": {
<CUSTOM PACKAGE MADE THE SAME PERSON 2>: "^0.1.6",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0"
}
},
The actual dependency
"react": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz",
"integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==",
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
Ancillary Question
Would having 2 versions of React in your package-lock.json not cause problems? I can't imagine these two version be used simultaneously. My guess would be that in this case this should be a peer dependency, am I correct to assume that?
Attempts
At first I thought that I could not update React yet, until react-helmet would be patched. I let my colleagues know, and they all said that another project also used react-helmet and they were able to update React. What?! Great impression on new colleagues 😄.
Indeed opening the other project and installing the new React version there did not cause the same warning.
Question
As an experiment I decided to remove the package-lock.json entirely. This resulted in the same errors. Removing the package-lock.json and the node_modules resolved it however! Why is this the case? The package that requires React 17.0.2 is still there as is the dependency for React version 17.0.2. Yet somehow, it is no longer a problem.
Any help to understand why this would resolve the situation would be greatly appreciated.
Note
react-helmet seems to be unmaintained, so will need to be removed eventually. This is not what my question is about.

Apparently removing the node_modules and package-lock.json did not help at all. Removing both does not trigger the warning the first install. Once you run npm install again, the same warning will show.
So it seems the warnings do not show up at the first 'clean' install. This also seems to be true at the other project, however there is something more going on there.
In this case it will probably mean that we will need to replace react-helmet with react-helmet-async and update the version of the custom package.

Related

Why did npm update axios fail to update but npm uninstall then install can?

I used "axios": "^0.19.2", running npm i gave the warning "npm WARN deprecated axios#0.19.2: Critical security vulnerability fixed in v0.21.1." so I run npm update -S axios to update it. But it failed to update axios. I run yarn upgrade axios but it failed too.
I had thought there maybe a module required 0.19.2 so I checked package-lock.json and I found the only module in my project that requires axios is pm2 but it requires "axios": "^0.21.0",
"#pm2/js-api": {
"version": "0.6.7",
"resolved": "https://registry.npmjs.org/#pm2/js-api/-/js-api-0.6.7.tgz",
"integrity": "sha512-xxxxxxxx",
"requires": {
"async": "^2.6.3",
"axios": "^0.21.0",
"debug": "~4.3.1",
"eventemitter2": "^6.3.1",
"ws": "^7.0.0"
},
I have no idea why npm update failed to update axios. I then run npm uninstall axios, npm install -S axios then "axios": "^0.27.2" is installed.
But why ?
--- update ---
To verify whether I can reproduce this issue or not I create a project at https://github.com/qiulang/npm-update-error-demo
It shows that even I only have one dependency axios, npm update axios still failed to update. BTW I use npm 8.x (try both 8.5 & latest 8.11)
When I run npm update -S axios --loglevel verbose with npm 6 I got the result
npm verb outdated not updating axios because it's currently at the
maximum version that matches its specified semver range
If I run with npm 8 I even got 404 error
npm verb audit error HttpErrorGeneral: 404 Not Found - POST
https://registry.npmmirror.com/-/npm/v1/security/audits/quick
So I had thought could this be npm bug ? Suddenly I realize this was caused by Caret Ranges ^ I used because normally ^ means patch and minor updates (most people are familiar with that) but it only means for the patch updates for versions 0.X >=0.1.0 as npm document says
Many authors treat a 0.x version as if the x were the major
"breaking-change" indicator.
Caret ranges are ideal when an author may make breaking changes
between 0.2.4 and 0.3.0 releases, which is a common practice.
...
^0.2.3 := >=0.2.3 <0.3.0
BTW because many answers were given to What's the difference between tilde(~) and caret(^) in package.json? so the answer about patch only for ^0.x was buried in them.

Webpack Peer Dependency Error in NPM When Webpack Is Installed

I'm getting this error when running webpack-dev-server in npm:
webpack-dev-middleware#3.7.2 requires a peer of webpack#^4.0.0 but none is installed. You must install peer dependencies yourself.
However, I already installed webpack. Here is my package.json. What am I missing?
{
...
"scripts": {
"watch": "webpack-dev-server --progress --https"
},
...
"devDependencies": {
"webpack": "^5.4.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
}
}
You have webpack#5 installed but the peer dependency warning is asking for webpack#4. There is a bug filed in the webpack-dev-server issue tracker about the incompatibility with webpack#5. As of a few days ago, they're working on it.
So one option is to be patient and watch that issue. When a version compatible webpack#5 is released, upgrade to it.
Another option is to downgrade your current project to webpack#4. I don't know how big the breaking changes between webpack#4 and webpack#5 are, but it's an option to try. Given that webpack#5.0.0 was released only a month ago, this may be an OK option. The latest version of webpack#4.x is webpack#4.44.2 and (as of this writing) is only 2 months old.

npm:confirm the behavior of npm install for this case? Why there is no nested dependency?

In application, I come across some issue when installing npm packages.
the package.json goes as following:
"dependencies": {
"#angular/cdk": "7.2.1",
"privateLib": "19.0.0",
}
I only show the critical part and hide other things. The privateLib is one private package you can ignore the name.
And after npm install, it reports the following warn message:
npm WARN privateLib#19.0.0 requires a peer of #angular/cdk#7.3.7 but none is installed. You must install peer dependencies yourself.
And I checked the installed #angular/cdk is version 7.2.1.
The confusing points is that, inside the privateLib, its own package.json config goes like this:
"dependencies": {
"#angular/cdk": "7.3.7",
}
I checked there is no #angular/cdk package inside privateLib. So why it doesn't install its own dependency of version 7.3.7 in a nested way. This behavior is not same as the npm3 document: https://npm.github.io/how-npm-works-docs/npm3/how-npm3-works.html
I'm using npm v6.
Indeed, per https://blog.npmjs.org/post/110924823920/npm-weekly-5:
We will also be changing the behavior of peerDependencies in npm#3. We won’t be automatically downloading the peer dependency anymore. Instead, we’ll warn you if the peer dependency isn’t already installed. This requires you to resolve peerDependency conflicts yourself, manually, but in the long run this should make it less likely that you’ll end up in a tricky spot with your packages’ dependencies.
Try https://github.com/spatie/npm-install-peers to facilitate.

React Native Peer Dependency issue in Expo

What is the best way to deal with solving a peer dependency issue in React Native when using Expo? I am stuck with a peer dependency error. I didn’t install any new packages to cause a new peer dependency, what happened is I got a node modules error (as does happen in RN sometimes) and I had to blow away and reinstall all my node modules.
I think that something got out of sync when this I re-instantiated my node modules. Any ideas on how to get around it? I have tried making my package.json specifically versioned but I haven’t found the right setup. FWIT Expo is throwing me this warning:
“Warning: ‘firebase’ peer depencency missing”
When I run
npm install OR npm ls
I get the following messages:
FWIT: my package.json looks like this
{
"name": "RN-expo",
"version": "0.0.0",
"description": "Hello Expo!",
"author": null,
"private": true,
"main": "main.js",
"dependencies": {
"expo": "17.0.0",
"firebase": "4.1.2",
"geofire": "^4.1.2",
"lodash": "^4.17.4",
"moment": "^2.18.1",
"react": "16.0.0-alpha.6",
"react-native": "https://github.com/expo/react-native/archive/sdk-17.0.0.tar.gz",
"react-native-gifted-chat": "^0.1.4",
"react-native-modal-dropdown": "^0.4.4",
"react-native-multislider": "0.0.14",
"react-native-vector-icons": "^4.2.0",
"react-navigation": "git+https://github.com/react-community/react-navigation.git"
},
"devDependencies": {
"standard": "^10.0.2"
}
}
These errors are not occurring on anyone else's computers on my team, so I think it has something to do with the node dependencies on my computer. I have completely uninstalled all node / npm related material on my computer and attempted to reinstall it to see if it solved the issue.
While scrolling through the npm ls I see the the "UNMET PEER DEPENDENCIES" are:
UNMET PEER DEPENDENCY firebase#4.1.2
UNMET PEER DEPENDENCY react#>=15.3.1
Any suggestions on how to go about solving this?
From what I can see in your package.json, I'd expect your teammates also to encounter the same warnings.
The warning between geofire and firebase is because you're using firebase#4.1.2 but geofire wants firebase 3.x. Often (but also often not) libraries like geofire will work with newer versions of their peer dependencies, so I recommend asking the authors of geofire if it'd work with firebase#4.x.
The other warnings between React Native packages and React are spurious. For example, react-native-maps says it accepts react >= 15.4.0 and you're using react#16.0.0-alpha.6, which is clearly greater than 15.4.0. This has been addressed by Yarn, which detects that react#16.0.0-alpha.6 satisfies the requirement of react >= 15.4.0.
All this is to say that I'd expect you to see the warnings that you're seeing, and that the firebase one is legitimate and you can ignore the react one.

npm issues with UNMET PEER DEPENDENCY, related to react-native

I think I'm confused as to how npm manages dependencies. I see this:
npm list react-native
project#0.0.1 /Users/me/workspace/project
└── UNMET PEER DEPENDENCY react-native#0.15.0
npm ERR! peer dep missing: react-native#^0.13.2, required by react-native-dialogs#0.0.5
npm ERR! code 1
So I try... but I get:
npm install react-native#0.15.0
....
project#0.0.1 /Users/me/workspace/project
└─┬ UNMET PEER DEPENDENCY react-native#0.15.0
└── react-tools#0.14.0-beta1 (git+https://github.com/facebook/react.git#b4e74e38e43ac53af8acd62c78c9213be0194245)
npm WARN EPEERINVALID react-native-dialogs#0.0.5 requires a peer of react-native#^0.13.2 but none was installed.
npm ERR! code 1
My package.json:
{
"name": "project",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "react-native start"
},
"dependencies": {
"apsl-react-native-button": "^2.1.0",
"base-64": "^0.1.0",
"es6-react-mixins": "^0.2.1",
"fifo": "^2.3.0",
"money-math": "^2.2.0",
"react-native": "^0.15.0",
"react-native-dropdown-android": "0.0.4",
"react-native-lightbox": "^0.5.0",
"react-native-mail": "^0.2.4",
"react-native-router-flux": "^0.3.4",
"react-native-simpledialog-android": "^1.0.2",
"react-native-swiper": "^1.3.0",
"superagent": "^1.4.0",
"tcomb-form-native": "^0.3.0",
"utf8": "^2.1.1",
"react-native-facebook-login": "^1.0.0"
}
}
I know it's an old question, but a response can still be useful for others seeing this in the future.
Explanation of the issue
In your package.json, you are installing the dependency react-native-dialogs#0.0.5 which is as well expecting as a peerDependency the module: react-native#^0.13.2. Since that project is public, it can be verified in their package.json file:
"peerDependencies": {
"react-native": "^0.13.2"
}
The first part of this statement, is the module name, and the second part, the supported version range.
This means that the root module should provide such dependency and in such version range, in order for the installation to succeed with no errors. In this case, it's stating react-native dependency, and in the ^0.13.2 version range.
Now, in your package.json, you are listing the dependency:
"react-native": "^0.15.0",
So why is it not working? The ^ (caret) in version range should include all patch and minor versions in the same major, right? (ie. in "^X.Y.Z" range, all X.*.* should work, right?). Well, turns out this isn't true for pre-1.x ranges. For 0.x ranges, the ^ caret only covers patch versions inside the range (source: NPM docs).
Therefore, per this rule, "^0.15.0" is not in the range of "^0.13.2", so this is why you get the UNMET PEER DEPENDENCY error.
Possible solutions
You have a few options here.
Provide the expected peer dependency
The most straightforward one, is providing the expected peer dependency in a version that is in the expected version range.
So you could use the same version range, in this case: "^0.13.2". Or specify an exact version as well, for example: "0.13.2".
Tip: you can check all versions that match the requested range for a given package, using this utility https://semver.npmjs.com/.
For this case, the only version that exists and matches the range is "0.13.2", but there could've been more (ie. "0.13.3" could've been fine as well, if it existed. But "0.14.0" or "0.12.0" won't work, as explained above)
Update your module dependency
In many cases the original module gets upgraded, and changes may include supporting different or more broad peerDependencies packages/versions.
As of today, I can see in the package.json on the project master branch, that the current module version is 1.1.1 and the peerDependencies have been removed, so upgrading your "react-native-dialogs" dependency version ^0.0.5 -> ^1.1.1 will do the job for this scenario.
But, what if this didn't happen, or if you didn't want to upgrade to the latest version?Let's explore more options.
Change the module itself that you want to depend on
In case that providing the dependency version requested as a peerDependency by a module you use conflicts with your requirements, and upgrading this dependency to a newer version that removes this constraint doesn't work for you.
The allowed range "^0.13.2" might be quite limited, ie. it won't support version 0.14.0 and onwards. The reasoning behind this, could be based on compatibilty issues, or maybe just a lack of awareness in allowing/supporting for more versions. There could happen to exist other versions that can work fine, but the original developer did not take the extra steps to include them.
So you just want to continue using this exact module as is, but allow a newer react-native version.
Imagining the original scenario, that 0.0.5 was the current latest version in the master branch, it could make sense raising this as an issue to the original module repo, and/or submit them a PR proposing a broader supported range. For example:
"peerDependencies": {
"react-native": "< 1.0.0"
}
The range "< 1.0.0" would now allow the "^0.15.2" version range.
What if you didn't want to allow all the 0.x versions? Then you could use a more narrow range, such as: "> 0.4.0 < 1.0.0". Take a look at NPM semver docs for syntax, a lot more possibilities are allowed too.
Don't use that module at all / Build your own
It can happen that the original module can be abandoned, have bugs, or just not work for your all of your requirements. In this case, you can look for a some alternative available in the community, or even build one yourself.
Since this module is public you can even fork the project and upload a new package version yourself with the changes you want (you'll have to use a different package name of course).
Try the "--save" argument for "npm install" command, like:
npm install react-native#0.15.0 --save