Skip to content

npm --force--legacy-peer-deps の違いと使い分け

問題点

npm 7 以降、プロジェクトの依存関係に競合がある場合(特に peerDependencies の競合)、npm installnpm ci の実行が失敗することがあります。この場合、次のようなエラーメッセージが表示されます:

Fix the upstream dependency conflict, or retry this command with --force, or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution.

このエラーに対処するためのオプションとして --force--legacy-peer-deps が提供されていますが、両者の違いと適切な使い分けについて理解する必要があります。

解決策

基本概念の理解

npm 7 から peerDependencies の扱いが変更され、デフォルトでより厳格なチェックが行われるようになりました。peerDependencies とは、パッケージが正常に動作するために必要な「互換性のある」依存関係を指定するものです。

--legacy-peer-deps オプション

このオプションは、npm のバージョン 4 から 6 までの挙動を再現します。peerDependencies のチェックを完全に無視し、インストールを続行します。

bash
npm install --legacy-peer-deps

または

bash
npm ci --legacy-peer-deps

特徴

  • peerDependencies チェック: スキップ
  • その他の安全対策: 保持(バージョン解決、ロックファイルの整合性、整合性チェック)
  • 推奨される場面: プロジェクトの依存関係が複雑で、peerDependencies の競合が発生している場合の一時的な解決策

--force オプション

このオプションは、ローカルキャッシュがある場合でもリモートリソースを強制的に取得し、すべてのエラーや警告を無視します。

bash
npm install --force

注意点

  • peerDependencies チェック: スキップ
  • その他の安全対策: すべて無視
  • リスク: 壊れた依存関係ツリー、非再現性のあるビルド、重複したパッケージバージョンが発生する可能性があります

比較表

オプションpeerDependencies チェックその他の安全対策使用場面
なし適用すべて適用デフォルト、理想的
--legacy-peer-depsスキップ保持安全な回避策、一時的な解決
--forceスキップすべて無視最終手段、キャッシュの無効化

実例で見る違い

実際のプロジェクトで両オプションを使用した場合、package-lock.json に以下のような違いが生じます:

json
"@unimodules/react-native-adapter": {
  "version": "5.7.0",
  "resolved": "https://registry.npmjs.org/...",
  "integrity": "sha512-...",
  "requires": {
    "invariant": "^2.2.4",
    "lodash": "^4.5.0"
  }
}
json
"expo/node_modules/@unimodules/react-native-adapter": {
  "version": "5.7.0",
  "resolved": "https://registry.npmjs.org/...",
  "integrity": "sha512-...",
  "dependencies": {
    "invariant": "^2.2.4",
    "lodash": "^4.5.0"
  },
  "peerDependencies": {
    "react-native": "*",
    "react-native-web": "~0.13.7"
  }
}

--force を使用すると、依存関係の重複が発生し、より複雑な依存関係ツリーが生成されることがわかります。

ベストプラクティス

1. 優先すべき解決策

依存関係の競合が発生した場合、以下の順序で対策を検討してください:

  1. 根本的な解決: 依存関係のバージョンを調整し、競合を解消する
  2. --legacy-peer-deps: 一時的な回避策として使用
  3. --force: 最終手段としてのみ使用

2. 設定の永続化

プロジェクトで常に --legacy-peer-deps が必要な場合は、設定を永続化できます:

bash
npm config set legacy-peer-deps true

ただし、これはチーム全体の開発環境に影響するため、慎重に判断してください。

3. 代替手段の検討

  • npm dedupe: 重複した依存関係を整理する
  • --strict-peer-deps: より厳格な peerDependencies チェックを適用する

結論

一般的に、--legacy-peer-deps--force よりも安全なオプションです。--legacy-peer-deps は peerDependencies のチェックのみをスキップする一方、--force はすべての安全対策を無視するため、予期しない問題を引き起こす可能性があります。

依存関係の問題に対処する際は、常に根本的な解決を優先し、これらのフラグは一時的な回避策としてのみ使用することをお勧めします。