ngrx/platform

ng add fails in Angular 11 project w/Node 15 due to invalid peer dependency

Closed this issue ยท 28 comments

Minimal reproduction of the bug/regression with instructions:

  • Create a new Angular 11 project
  • ng add @ngrx/store
  • This will install @ngrx/store@1.2.1 ๐Ÿ’ฅ

From what I examined, the reason could be the peer dependency which is set to ^10.0.0: https://github.com/ngrx/platform/blob/master/modules/store/package.json#L24
Angular CLI can find the latest version but fails for the second condition here since the peer dep is unmet: https://github.com/angular/angular-cli/blob/master/packages/angular/cli/commands/add-impl.ts#L115

A possible solution would be to bump up the peer dep to >= 10.0.0, but I don't know how that interferes with your overall plans.

Expected behavior:

It should add the latest version.

Versions of NgRx, Angular, Node, affected browser(s) and operating system(s):

  • @ngrx/store@10.1.1
  • @angular/cli@11.0.2

Other information:

I would be willing to submit a PR to fix this issue

[ ] Yes (Assistance is provided if you need help submitting a pull request)
[ ] No

This is known behavior of the Angular CLI. Use the @latest until v11 is out. For context

#2604

@brandonroberts So obviously the Angular team is not going to change the mechanism in the CLI. Therefore, we should generally consider a hardening of NgRx, shouldn't we?

How about a patch version change of v10 (10.1.2) with a peer dependency that looks like this:

  "peerDependencies": {
    "@angular/core": "^10.0.0 || ^11.0.0",
    "rxjs": "^6.5.3"
  },

Me and @fmalcher would be happy to submit a PR for all affected packages.

@JohannesHoppe I'm not inclined to do that, as we align major versions with Angular, and this only surfaces for the time we're behind the latest major, which is in our normal release cycle. Either ng add @ngrx/store@latest or ng add @ngrx/store@10 should work unless there is some other issue going on until we release version 11 soon-ish.

@brandonroberts I recently started an Angular 11 project and wanted to add ngrx. I just ran ng add @ngrx/store@latest and it fails with:

Package has unmet peer dependencies. Adding the package may not succeed.
Installing packages for tooling via npm.
An unhandled exception occurred: npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! While resolving: tigris@0.0.0
npm ERR! Found: @angular/core@11.0.5
npm ERR! node_modules/@angular/core
npm ERR!   @angular/core@"~11.0.1" from the root project
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/core@"^10.0.0" from @ngrx/store@10.1.1
npm ERR! node_modules/@ngrx/store
npm ERR!   @ngrx/store@"10.1.1" from the root project
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

The "dependencies" in package.json look like:


  "dependencies": {
    "@angular/animations": "~11.0.1",
    "@angular/cdk": "^11.0.2",
    "@angular/common": "~11.0.1",
    "@angular/compiler": "~11.0.1",
    "@angular/core": "~11.0.1",
    "@angular/flex-layout": "^11.0.0-beta.33",
    "@angular/forms": "~11.0.1",
    "@angular/material": "^11.0.0",
    "@angular/platform-browser": "~11.0.1",
    "@angular/platform-browser-dynamic": "~11.0.1",
    "@angular/router": "~11.0.1",
    "rxjs": "~6.6.0",
    "tslib": "^2.0.0",
    "zone.js": "~0.10.2"
  },

I also tried ng add @ngrx/store@10, same errors.

This seems like some new behavior with npm? Does running it with the --legacy-peer-deps option work?

I just tried ng add @ngrx/store@latest --legacy-peer-deps and it failed with the same error. FWIW, I am using node v15.4.0 and npm 7.0.15.

I switched to node v14.15.3 (npm v6.14.9) and this ng add @ngrx/store@latest worked.

@mindscratch Ok. I'm assuming the --force option works with Node v15 also

I just reverted my package*.json files, switched to node 15 and tried ng add @ngrx/store@latest --force and it failed with the same error as it did previously. FWIW, I don't see a --force option with ng add:

ng add --help
arguments:
  collection
    The package to be added.

options:
  --defaults 
    When true, disables interactive input prompts for options with a default.
  --help 
    Shows a help message for this command in the console.
  --interactive 
    When false, disables interactive input prompts.
  --registry 
    The NPM registry to use.
  --verbose 
    Display additional details about internal operations during execution.

Oh I saw the --force and --legacy-peer-deps options from the npm error message. If you use node 15, and npm install @ngrx/store@latest do you get the same error? And does using npm install @ngrx/store@latest --legacy-peer-deps complete successfully?

With node 15, if I run npm install @ngrx/store@latest it fails with the same error as earlier, however, npm install @ngrx/store@latest --legacy-peer-deps does work.

@mindscratch ok, good to know. I'm going to pin this issue until we release version 11 in case others run into the same issue. If you install manually, you can run ng g @ngrx/store:init after to do the equivalent of what ng add does.

npm install @ngrx/store@latest --legacy-peer-deps
ng g @ngrx/store:init

@brandonroberts I just ran ng update @angular/cli @angular/core @angular/cdk @ngrx/store and it failed horribily :(

Package "@ngrx/effects" has an incompatible peer dependency to "@angular/core" (requires "^10.0.0", would install "11.0.5")
Package "@ngrx/router-store" has an incompatible peer dependency to "@angular/common" (requires "^10.0.0", would install "11.0.5")
Package "@ngrx/router-store" has an incompatible peer dependency to "@angular/core" (requires "^10.0.0", would install "11.0.5")
Package "@ngrx/router-store" has an incompatible peer dependency to "@angular/router" (requires "^10.0.0", would install "11.0.5")
Package "@ngrx/store" has an incompatible peer dependency to "@angular/core" (requires "^10.0.0", would install "11.0.5")
โœ– Migration failed: Incompatible peer dependencies found.

The major versions should be synced or updated to not need --force, this is kinda bad UX :(

@matheo this project is open source and done by contributors in our free time. We guarantee the major versions are synced but not according to your timeline request. Thanks and version 11 will be out soon.

@brandonroberts just want to say thanks for all the work you (and others) have put into NgRX and the responsiveness towards issues, it's really appreciated. I just signed up for PluralSight and started watching "Learn NgRX from the creators of NgRX"...very good, hopefully you all get $ from that :)

@mindscratch ok, good to know. I'm going to pin this issue until we release version 11 in case others run into the same issue. If you install manually, you can run ng g @ngrx/store:init after to do the equivalent of what ng add does.

npm install @ngrx/store@latest --legacy-peer-deps
ng g @ngrx/store:init

@brandonroberts Do we also have to do this ng g @ngrx/store:init for the Effects and DevTools modules as well?
e.g:

ng g @ngrx/effects:init
ng g @ngrx/store-devtools:init

@whoiscarlo yes, that's correct.

@brandonroberts alright cool. Thanks for the quick reply!

Just for clarity, this is the fix for the time being for those who run into this:

npm i -โ€”save @ngrx/store@latest @ngrx/effects@latest @ngrx/store-devtools@latest --legacy-peer-deps

ng g @ngrx/store:init
ng g @ngrx/effects:init
ng g @ngrx/store-devtools:init

@brandonroberts wrote:

@JohannesHoppe I'm not inclined to do that, as we align major versions with Angular, and this only surfaces for the time we're behind the latest major, which is in our normal release cycle. Either ng add @ngrx/store@latest or ng add @ngrx/store@10 should work unless there is some other issue going on until we release version 11 soon-ish.

Can you help me understand why adding something like the following:

   "peerDependencies": {
     "@angular/core": "^10.0.0 || ^11.0.0"
   },

is incompatible with aligning major versions with Angular, if ngrx version 10 works on Angular 11 (as appears to be the case)?

The next major version of ngrx could still be aligned with Angular 11, but updating the peer dependencies of ngrx 10 to reflect the actual dependencies makes the upgrade path a bit more gentle. We could upgrade to Angular 11, then move on to upgrading to ngrx 11, all without having to override the stated peer dependencies. It would also allow new users of ngrx to come into the system at any time, without having read the github issues to find out the best way to install, if they happen to fall between the Angular release and the ngrx release.

@karptonite it may seem like a trivial change in your opinion, but its added support required for us, not for you. We will try to be quicker about having the next major out when Angular releases its next major, but either way we're not doing it for this release.

@brandonroberts I didnโ€™t mean to imply that it was a trivial change. I literally didnโ€™t understand why that change was incompatible with the goal of aligning major versions.

Now I understand that it is related to support requirements, which makes sense. My understanding was that ngrx 10 was already well known to work fine with Angular 11 (hence the suggestions to install with @latest), but I understand that that isnโ€™t the same as committing to supporting incompatibilities should they be discovered.

Closing this one again as version 11 is out. We'll plan better for the next major to be more closely aligned.

@brandonroberts it seems that this won't be a minor issue anymore with npm 7
as peerDependency desync may cause this error:

npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree

npm ERR! Found: @angular/core@11.1.2
npm ERR! Could not resolve dependency:
npm ERR! peer @angular/core@"^10.0.0" from @ngrx/effects@10.1.2

the dependency maintenance should be improved
or just define the minor version required and we don't bother to get open source updates ;)

@matheo what command did you run to get this?

My colleague @undsoft reports that it was a simple npm i after he upgraded to npm v7
(on a website not updated to ngrx v11 which package-lock file was created with npm 6)

You can set the peer deps before running the ng add command.

npm config set legacy-peer-deps true

Then you can run ng add @ngrx/store

As an addition to the solution from @pubkey : if you do not want this behavior globally, just create a file .npmrc next to your package.json with content

legacy-peer-deps=true

This is just the same, but done for this particular project only