🩹 失敗談・トラブル解決 2026.07.26 更新

npmのERESOLVEエラーを直す|依存関係の競合を安全に解消する手順

npm installでERESOLVEが出たときに、競合パッケージと要求バージョンを読み、package.jsonとlockfileを最小限の変更でそろえる手順を解説します。

npm installERESOLVE unable to resolve dependency treeと表示されたら、強制オプションを付ける前に立ち止まります。読むべきは「どのパッケージが、どの版を要求しているか」です。多くの場合、直接使うパッケージと、プラグインなどのpeerDependencies(一緒に使う相手の対応版)の範囲が重ならない競合です。

この記事では、エラーの読み方、対応版の選び方、lockfile(依存の記録ファイル)の更新、テストまでを順番に進めます。例に出す名前と版は説明用です。挙動の確認対象はnpm CLI v11の公式資料です。npmの挙動はメジャー版(大きな版)や設定で変わることがあるので、実際の対応版はその時点の公式案内で確認してください。

ERESOLVEは「互換性の競合を見つけた」合図

ERESOLVEは、npmが「全員の要求を同時に満たす依存ツリー(パッケージの組み合わせ)を決められなかった」ことを示すエラーです。何かが壊れたのではなく、矛盾を先に見つけて止まってくれた状態です。

npm公式のpackage.json資料によると、peerDependenciesは「プラグインが、どの版のホスト(土台のライブラリ)と一緒に動けるか」を表す欄です。npm v7以降は、このpeerDependenciesも既定でインストールされます。そのため、要求が矛盾するプラグインを追加すると、npmは依存ツリーを解決できずエラーを出すことがあります。

たとえば、プロジェクトがui-library@5を使っているのに、追加したプラグインがui-library@^4.0.0(4系だけ)を要求している状態です。

さらに、npm公式の実装済みRFC(仕様の決定文書)には、競合の扱い方が3つ書かれています。

  • strictモード: peer競合をERESOLVEとして止める
  • forceモード: 警告だけ出して競合を上書きする
  • 既定モード: プロジェクト直下の直接依存は厳しく止め、深い階層の依存は警告して上書きする

つまり「自分のpackage.jsonに書いたパッケージ同士の競合」は既定でエラーになりやすく、「奥の方の間接的な競合」は警告で通ることがあります。同じERESOLVEでも原因はさまざまです。推測せず、実際のエラー全文を読むところから始めます。

エラー全文から競合の3点を読み取る

ERESOLVEの全文を途中で切らずに保存し、次の形の行を探します。

Found: [email protected]
Could not resolve dependency:
peer ui-library@"^4.0.0" from [email protected]

読み方は次のとおりです。

  1. Found:の行 = いま入っている版(この例では[email protected]
  2. fromの後ろ = 競合を起こしている相手([email protected]
  3. peer ...@"..."の範囲 = 相手が許している版の範囲(^4.0.0

まずこの3点を作業メモへ写します。ここが決まれば、直す場所はほぼ特定できています。

すでにインストール済みのパッケージが「どの経路から入ったのか」を知りたいときは、npm explain ui-libraryが使えます。npm公式のnpm explain資料によると、このコマンドは指定したパッケージが入った原因を、依存の連鎖(AがBを呼び、BがCを呼ぶ、のつながり)で表示します。別名のnpm whyでも同じです。ただし説明できるのは「現在のプロジェクトに入っている」パッケージです。インストール自体が失敗してnode_modulesに無いものは、ERESOLVE全文、package.jsonpackage-lock.jsonを読んで追いかけます。

package.jsonでは、dependenciesdevDependenciesから競合した名前を探します。固定版なのか、^~付きの範囲指定なのかを確認します。ワークスペース(1つのリポジトリに複数プロジェクトを入れる構成)では、エラーに出た配下のpackage.jsonも見ます。

互換する組み合わせを選び、直接依存を1組だけ直す

版の数字の意味はSemVer(セマンティック バージョニング)2.0.0で決められています。MAJOR(1つ目)は互換性が壊れる変更、MINOR(2つ目)は後方互換の機能追加、PATCH(3つ目)は後方互換の修正です。ただしこれは「番号の付け方のルール」であって、個々のパッケージが実際にそのとおり互換である保証ではありません。判断は、peerDependenciesの範囲、公式リリースノート、実際のテストの3つを組み合わせます。

候補の版が何を要求しているかは、npmレジストリ(パッケージの倉庫)から確認できます。

npm view ui-plugin versions --json
npm view ui-[email protected] peerDependencies
npm view ui-plugin@latest peerDependencies

latest(最新)が自分の構成に最適とは限りません。候補が見つかったら、公式リリースノートで破壊的変更、Node.jsの対応範囲、移行手順も読みます。公式情報で互換性を判別できなければ「※要確認」として保留します。

選択肢は主に3つと、一時回避の1つです。

選択肢向いている状況主な確認点注意点
プラグインを上げるいまのホスト版を維持したい新版のpeerDependenciesと移行手順プラグイン側の破壊的変更
ホストを戻すプラグインに対応版や代替がない他の依存が旧版を許すか新版で使っていた機能や修正が失われないか
別パッケージへ替える互換版がなく、保守状況にも不安がある必要な機能・ライセンス・移行量設定やAPIの書き換えが必要
強制オプションで一時回避原因の切り分けだけを行う実行時テストとCIの同一条件互換性の競合そのものは残る

方針を決めたら、元へ戻せる状態(gitのコミットなど)を用意し、直接依存を1回に1組だけ変えます。実際の版は、確認した値へ置き換えてください。

npm install ui-[email protected]

複数のメジャー更新を混ぜると、不具合が出たときに原因を切り分けられません。実行後はpackage.jsonpackage-lock.jsonの差分を見ます。lockfileは手で部分編集せず、npmに更新させます。差分が対象パッケージの周りに収まっていれば前進です。想定外の大量更新が出たら、npmやNode.jsの版、作業フォルダ、元のlockfileを見直します。端末ごとに版が違うときはNode.jsのバージョン不一致を直す手順も確認してください。

強制オプションを避け、テストとCIで解決を証明する

エラー文には--force--legacy-peer-depsという逃げ道が表示されます。しかしnpm公式のConfig資料では、legacy-peer-depsは依存ツリーを作るときにpeerDependenciesを完全に無視する設定で、互換性の契約を守らせないため推奨されないと説明されています。--forceはさらに広く、ルート直下のpeer競合の押し通しだけでなく、対応エンジン(Node.jsの版)の不一致など複数の保護をまとめて外します。「インストールが通った」と「互換性が解決した」は同じではありません。

原因の切り分けに一時的に使う場合も、「採用するかどうかの判断基準」「lockfileへの影響」「元へ戻す条件」を先に決めます。npm公式のnpm ci資料によると、依存ツリーへ影響するフラグでlockfileを作った場合、npm ci(CI用のクリーンインストール)にも同じフラグが必要になることがあります。自分の手元だけ通る構成は、チームやCIで再現できません。

ERESOLVEの表示が消えたら、次の順で証拠を残します。

  1. npm ciで入れ直す。npm cipackage.jsonとlockfileが一致しないと、lockfileを書き換えずにエラーで止まります。開始前に既存のnode_modulesは自動で削除されます。役割の違いはnpm ciとnpm installの違いで整理しています
  2. ビルド、型検査、単体テストを回す
  3. 更新したプラグインを使う代表機能を実際に動かす。初期化や設定の読み込みは、インストール成功だけでは検査されません。正常系だけでなく設定不足も試します
  4. CIでも同じ結果になるか確かめる。GitHub公式のNode.js向けCI資料の例も、npm ciのあとにビルドとテストを実行する順になっています。例に載っている具体的な版や部品は更新されるので、この検証の順番だけを参考にします

再発に備えて、ERESOLVE全文、選んだ版、実行コマンド、差分、テスト結果を1つの作業メモへ残します。更新後の確認項目を定型化するなら、AIコーディングの回帰テスト手順も参考になります。

よくある質問

ERESOLVEが出たらpackage-lock.jsonを削除してよいですか?

最初の手段にはしません。lockfileを消して作り直すと、無関係な間接依存まで一斉に変わる可能性があります。先に競合の3点(現在版・競合元・要求範囲)を特定し、package.jsonの直接依存を直してから、npmにlockfileを更新させます。どうしても再生成が必要な場合は、元のlockfileを復元できる状態にしてから行い、再生成後の差分を検査します。

—legacy-peer-depsでインストールできたら解決ですか?

いいえ。これはpeerDependenciesを無視して進める設定で、互換版を選んだことにはなりません。npm公式資料も、契約を強制しないため非推奨としています。使うのは原因調査の一時比較までにして、採用する前にビルド・テスト・代表機能の動作を確認します。

—forceと—legacy-peer-depsの違いは何ですか?

--legacy-peer-depsは、peer依存の解決だけを無視する設定です。--forceは、peer競合の上書きを含めて、npmの複数の安全保護をまとめて外す、さらに広い設定です。どちらも「要求範囲の不一致」そのものは直しません。常用せず、互換版をそろえる方法を先に検討します。

npm ciでだけERESOLVEになるのはなぜですか?

npm cipackage.jsonとlockfileが一致しないと、lockfileを更新せずに終了する決まりだからです。また、lockfileを作ったときに依存ツリーへ影響するフラグを使っていた場合、CI側にも同じフラグが要ることがあります。ローカルとCIのNode.js、npm、設定ファイル、lockfileを比べてください。

AIにERESOLVEの修正を頼むとき、何を渡せばよいですか?

材料は6点です。ERESOLVE全文、package.jsonpackage-lock.jsonnode --versionの結果、npm --versionの結果、直前に実行したコマンド。あわせて条件を付けます。「変更は直接依存1組まで」「強制フラグの常用とlockfileの削除は勝手にしない」「npm ci・ビルド・テストの成功と、差分の説明を完了条件にする」。ここまで固定すると、AIの作業をあとから安全に検収できます。

まとめ

ERESOLVEは、npmが互換性の矛盾を先に見つけて止めてくれた合図です。強制フラグで黙らせるのではなく、原因の1組を直します。次の3つから始めてください。

  • エラー全文を保存し、Foundの現在版・fromの競合元・peerの要求範囲の3点をメモする
  • 公式のpeerDependenciesとリリースノートで互換版を選び、直接依存を1回に1組だけ変えて、lockfileはnpmに更新させる
  • npm ci→ビルド→テスト→代表機能の順で確かめる。AIに任せるときも、この材料と合格条件をセットで渡す

公式一次情報

確認日: 2026-07-26

  • package.json | npm Docs: peerDependenciesの用途と、npm v7以降は既定でインストールされ競合時にエラーになり得ることの説明
  • Config | npm Docs: legacy-peer-depsがpeerDependenciesを完全に無視するため非推奨であることと、forceが複数の保護を外す設定であることの説明
  • npm-explain | npm Docs: インストール済みパッケージが入った原因を依存の連鎖で表示するコマンドの説明
  • npm-ci | npm Docs: lockfileとpackage.jsonが一致しないと更新せず終了する動作と、lockfile作成時のフラグがCIにも必要になり得ることの説明
  • Handling Conflicting peerDependencies: peer競合をstrict・force・既定モードでどう扱うかを定めたnpm公式の実装済みRFC
  • Semantic Versioning 2.0.0: MAJOR・MINOR・PATCHの意味を定めた版番号の仕様
  • Building and testing Node.js - GitHub Docs: npm ciのあとにビルドとテストを実行する公式のCI構成例

続き(結論と実データ)はnoteに置いています

ここでは手順のところまで書きました。実際に出た数字、うまくいかなかった条件、そのまま使える設定ファイルは、 note の記事にまとめてあります。

noteで続きを読む Xをフォローする