npm / cli

the package manager for JavaScript
https://docs.npmjs.com/cli/
Other
8.46k stars 3.15k forks source link

[BUG] NPM install the wrong peer depedencies with --force #3396

Closed jcompagner closed 2 years ago

jcompagner commented 3 years ago

Is there an existing issue for this?

Current Behavior

tst.zip

first just do

npm install

on the root dir

if you look then in node_modules you don't have an 'uppy' or 'uppy-angular' or '@biacsics' (thats good)

the try

npm install ./child

npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree npm ERR! npm ERR! Found: @angular/common@7.2.16 npm ERR! child/node_modules/@angular/common npm ERR! peer @angular/common@"^7.2.0" from uppy-angular@0.1.4 npm ERR! child/node_modules/uppy-angular npm ERR! uppy-angular@"^0.1.4" from @servoy/servoyextracomponents@4.1.0 npm ERR! child npm ERR! @servoy/servoyextracomponents@4.1.0 npm ERR! node_modules/@servoy/servoyextracomponents npm ERR! @servoy/servoyextracomponents@"file:child" from the root project npm ERR! npm ERR! Could not resolve dependency: npm ERR! peer @angular/common@">=9.0.0" from @biacsics/ng-canvas-gauges@6.0.7 npm ERR! child/node_modules/@biacsics/ng-canvas-gauges npm ERR! @biacsics/ng-canvas-gauges@"^6.0.7" from @servoy/servoyextracomponents@4.1.0 npm ERR! child npm ERR! @servoy/servoyextracomponents@4.1.0 npm ERR! node_modules/@servoy/servoyextracomponents npm ERR! @servoy/servoyextracomponents@"file:child" from the root project npm ERR!

so it wants to have an angular/common@7.x (from the uppy lib)

i am not sure why it also reports then @biacsics/ng-canvas-gauges becaus ethat is a >=9.0 and that should be fine thats not the problem the problem i guess is the root angular itself which is fixed to 12.0.3 (i kind of expect that error the be seen)

if you do then

npm install ./child --force

now in the root module you do have an "uppy" and "@uppy" suddenly there but not the rest what i expect to also have installed there

but if i look into the child i see a node_modules then i see there suddenly @biacsics and uppy-angular why are these 2 there but the other depedencies of those are in the root?

but that is not the the biggest problem

in the childs/node_modules you also see an @angular\core and @angular\common and you kind of expect that because of the error above and because of the --force those are version 7.2.16 but no, what is in there is suddenly the latest angular thats at this time 12.0.4 (root has 12.0.3)

why does that happen in force mode? What i want is that nothing of angular is installed (not a newer or a older version). But i would conceptually understand better if an older version was installed...

but only when i use instead of --force:

npm install .\child --legacy-peer-deps

then everything is working as i expect

everything is installed into the root node_modules and no duplicate peers are installed.

So these scenario's which will happen constantly because of all the npm packages that are out there that are not always actively maintained which can have peer depedencies pointing to older stuff will only be able to work if you use --legacy-peer-deps? But the name "legacy" means its something that will be depricated, shouldn't be used.. But its kind of crucial to work with a lot of packages. or i have to form them all and make sure to update all the peers constantly...

Expected Behavior

the expected behavior is kind of the --legacy-peer-deps thats how i want it to work or need it to work For me it can never install 2 angulars because that will cause many problems in angular apps

But i guess you could say that at least the expected behavior that it would have installed angular 7.x not the latest 12.x

But that wouldn't really give me the solution i want, and that is that it never installs a conflicting peer dependency, if there is one the main package.json file is always leading

Steps To Reproduce

see the above steps and the attached zip.

Environment

jcompagner commented 3 years ago

i like that peer depedencies are installed that are not there yet. But i think the resolvement of the version needs to be smarter somehow.

Some examples how i thought it should work

Main LibA -> LibC v1 LibB -> LibC v2

if you just install this you get a error, that there is a version conflict If you use --force then v2 of LibC is installed (its the highest values of all of the version found) and a warning is given.

Main LibC -> v1 LibA -> LibC v1 LibB -> LibC v2

Main has LibC itself and with version v1 now force is not needed, LibC v1 is installed and a warning is given that LibB wants a higher version..

Main LibC -> v3 LibA -> LibC v1 LibB -> LibC v2

Now Main has again LibC itself with version v3 now force is not needed, LibC v3 is installed and a warning is given that LibA and LibB wants another version..

So i think there are just 2 rules

if main doesn't include it, then the highest version is installed of all the dependency versions found for that lib over all depedencies. (and a --force is needed) if main does include it then that is always leading and a warning is given.

wraithgar commented 2 years ago

If you want to use --legacy-peer-deps then that's the flag to use. peer dependencies is a tricky problem to solve and there is no single solution that resolves every tree.