[npm] ERESOLVE unable to resolve dependency treeを解決する

# はじめに
Angularのアップデートを行った際にnpm isntallを実行したところ`ERESOLVE unable to resolve dependency tree`が発生しました。
エラーメッセージの内容を理解して解決するまでに時間がかかったので、備忘として残します。
# この記事で伝えたいこと
エラーメッセージが何を意味しているかを解説
解消する方法を紹介
# 参考記事
https://zenn.dev/minamiso/articles/78b22716f3338d
https://qiita.com/masato_makino/items/20d4fcfc9c05bd3907da
https://qiita.com/cognitom/items/acc3ffcbca4c56cf2b95
# 環境
`ng version`を実行して環境を確認
```
Angular CLI: 18.0.5
Angular: 18.0.4
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, platform-server
... router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1800.5
@angular-devkit/build-angular   18.0.5
@angular-devkit/core            18.0.5
@angular-devkit/schematics      18.0.5
@angular/cli                    18.0.5
@angular/ssr                    18.0.5
@schematics/angular             18.0.5
rxjs                            7.8.1
typescript                      5.4.5
zone.js                         0.14.7

Angular: 18.0.4
```
# エラーを発生させる
Angular18のプロジェクトに[datetime-picker](https://www.npmjs.com/package/@angular-material-components/datetime-picker)をインストールしようとしてみます。
datetime-pickerの現在の対応バージョンはangular16となっているので依存関係のエラーが発生するはずです。
`npm i @angular-material-components/datetime-picker`を実行
```
1  npm ERR! code ERESOLVE
2  npm ERR! ERESOLVE unable to resolve dependency tree
3  npm ERR! While resolving: my-app@0.0.0
4  npm ERR! node_modules/@angular/common
5  npm ERR!
6  npm ERR! Could not resolve dependency:
7  npm ERR! peer @angular/common@"^16.0.0 || ^17.0.0" from @angular/cdk@16.2.14
8  npm ERR! node_modules/@angular/cdk
9  npm ERR!   peer @angular/cdk@"^16.0.0" from @angular-material-components/datetime-picker@16.0.1
10 npm ERR!   node_modules/@angular-material-components/datetime-picker
11 npm ERR!     @angular-material-components/datetime-picker@"*" from the root project
12 npm ERR!
13 npm ERR! Fix the upstream dependency conflict, or retry
14 npm ERR! this command with --force or --legacy-peer-deps
15 npm ERR! to accept an incorrect (and potentially broken) dependency resolution.
16 npm ERR!
17 npm ERR!
18 npm ERR! For a full report see: 
19 npm ERR! A complete log of this run can be found in: 
```
エラーが発生しインストールに失敗しました。

まず11行目を見てみます。
npm installを行ったためroot projectが@angular-material-components/datetime-pickerの最新バージョンを要求。

次に9行目、datetime-pickerの最新バージョンは16.0.1です。
datetime-picker@16.0.1はangular/cdk@^16.0.0を利用しているため、該当するバージョンを要求。
(^16.0.0は16.0.0以上、17.0.0未満のバージョンであればどれでも良いという意味です。)

次に7行目、@angular/cdkの16.2.14をインストールしようとします。
@angular/cdk@16.2.14は@angular/commonの^16.0.0 || ^17.0.0(16系もしくは17系)を要求。
ここで依存関係のエラーが発生しています。

# 依存関係を確認
package.jsonを確認
```
1  "dependencies": {
2    "@angular/animations": "^18.0.0",
3    "@angular/common": "^18.0.0",
~~~
```
3行目からわかるようにroot projectが要求する@angular/commonのバージョンは^18.0.0(18系)です。
先ほどの@angular/cdk@16.2.14は@angular/commonの^16.0.0 || ^17.0.0(16系もしくは17系)を要求していました。
上記の要求を同時に満たすバージョンが存在しないため、datetime-pickerのインストールは失敗します。

# 解決策
datetime-pickerがAngular18に対応するのを待つ。
もしくはAngularのバージョンを16に落とす。

# 退避策 --force, --legacy-peer-deps
--forceもしくは--legacy-peer-depsは依存関係のエラーを無視してパッケージをインストールするオプションです。
`ng serve`でアプリケーション実行時に予期せぬ動作が発生する可能性があります。

依存関係のエラーは残り続けるため、その後`npm update`などを行った際には無視したエラーが再度発生し、updateの実行を停止します。

では、試しに`npm i @angular-material-components/datetime-picker --force`を実行します。
依存関係の警告が多数出力され、インストールに成功します。
```
npm WARN using --force Recommended protections disabled.
npm WARN ERESOLVE overriding peer dependency
npm WARN While resolving: @angular-material-components/datetime-picker@16.0.1
npm WARN Found: @angular/common@18.0.4
npm WARN node_modules/@angular/common
npm WARN   peer @angular/common@"18.0.4" from @angular/forms@18.0.4
npm WARN   node_modules/@angular/forms
npm WARN     @angular/forms@"^18.0.0" from the root project
npm WARN   6 more (@angular/platform-browser, ...)
npm WARN
npm WARN Could not resolve dependency:
npm WARN peer @angular/common@"^16.0.0" from @angular-material-components/datetime-picker@16.0.1
npm WARN node_modules/@angular-material-components/datetime-picker
npm WARN   @angular-material-components/datetime-picker@"*" from the root project
~~~
```
その後`npm update`を行うと上記の警告の一部がエラーとして出力されてupdateは停止します。
## overrideについて
package.jsonを以下のように書き換えることで警告を抑止することが可能です。
```
  "dependencies": {
    "@angular-material-components/datetime-picker": "^16.0.1",
    "@angular/animations": "^18.0.0",
    "@angular/common": "^18.0.0",
~~~
    "zone.js": "~0.14.3"
  },
  // ここから
  "overrides": {
    "@angular-material-components/datetime-picker": {
      "@angular/common": "^18.0.0",
      "@angular/core": "^18.0.0",
      "@angular/forms": "^18.0.0",
      "@angular/animations": "^18.0.0",
      "@angular/platform-browser": "^18.0.0"
    }
  },
  // ここまで
```
これはdatetime-pickerが依存しているパッケージのバージョンを上書きするオプションです。
警告を抑止しているだけでdatetime-picker@16をAngular18の環境で動かしていることは変わらないため予期せぬ動作が発生する可能性があります。