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

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.

Related

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

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.

NPM: Link peer dependency to package alias

Assume I have legacy codebase working with some old packages:
"mobx": "5.15.4",
"mobx-react": "6.1.8",
While developing some new experimental feature, I wanna use newer versions of these packages, but also have to leave legacy in a working state. So, I'm aliasing newer versions of packages so I can use them alongside with the old ones:
"#new/mobx": "npm:mobx#^6.3.13"
"#new/mobx-react": "npm:mobx-react#^7.2.1"
But mobx-react using mobx as a peer dependency. Obviously, the problem is that #new/mobx-react is watching old mobx version and expectedly says that there should be mobx of version 6+.
Is there any way to manually resolve peer dependency of #new/mobx-react, so it will watch #new/mobx and not just mobx? Or, maybe there is a way to implicitly install peer deps for #new/mobx-react in a way it will not override old mobx version?
You can easily do that
set NODE_ENV=development
npm install mobx#5.15.4 --save
npm install mobx-react#6.1.8 --save
npm install #new/mobx#npm:mobx#^6.3.13 --save
npm install #new/mobx-react#npm:mobx-react#^7.2.1 --save
then you must manually install dependencies for your #new/mobx-react like as follows:
cd ./node_modules/#new/mobx-react
npm install --ignore-scripts
that will lead to mobx of version 6.3.14 be in node_modules of your #new/mobx-react
node.js (starting from npm version 3) at first tries to load dependency from internal node_modules of package, then from node_modules of project see : documentation

How can I make npm install package and ignore one (or all) peer dependencies?

I have vuex#4.0.2 installed. I want to install vuex-module-decorators#latest, which has a peerDependency of vuex 3 (not >=3). I have a feeling this will work fine with vuex 4. Is there a way for me to tell npm to install this new package, without crashing due to not being able to resolve the peer dependency (since 4 != 3)? Or do I need to just create my own fork of vuex-module-decorators with an updated package.json that allows vuex >=3?
Using --legacy-peer-deps will usually allow you to install the package without meeting the peer dependency requirements. (This was the default using npm#6 so I assume you are using npm#7 if you are seeing a problem.) If that doesn't work, --force will install without regard to peer dependencies.
simply try this command
npm install --legacy-peer-deps
If you want peer dependencies to be automatically installed, add "auto-install-peers=true" to an .npmrc file at the root of your project

Do published packages take priority over workspaces when running npm install?

I have a monorepo project and I'm migrating to npm#7. Before npm workspaces, I had to publish packages to a private feed and then consume them in my app (I didn't bother with npm link shenanigans). Not ideal, but I made do.
Then npm introduced workspaces, and now I'm trying to migrate. While resolving peer dependency conflicts, I noticed that when I made changes to any package.json files, npm install would return the same errors unless I updated package versions to something that hadn't been published yet. I wasn't expecting this kind of behavior.
So how does npm determine where to search for a package first? Does npm install download packages from the registry before looking at workspaces? Is this intentional, and if so, why?

Making sure NPM dev dependencies match corresponding peer dependencies

I pretty much always end up adding my NPM modules peer dependencies to dev dependencies as well because I need the peer dependencies installed so I can run automated tests before building the package. This creates the problem that I might accidentally use different version number for peer and dev. I find it odd that npm and yarn do not install the peer dependencies automatically when I run npm install or the yarn command. In some cases I have found that yarn even tries to prevent me from adding the same dependency as both peer and dev dependency. I think I'm doing something wrong but I haven't been able to figure out the intended workflow. Can someone explain to me how this is supposed to work?