npm --force
と --legacy-peer-deps
の違いと使い分け
問題点
npm 7 以降、プロジェクトの依存関係に競合がある場合(特に peerDependencies の競合)、npm install
や npm 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 のチェックを完全に無視し、インストールを続行します。
npm install --legacy-peer-deps
または
npm ci --legacy-peer-deps
特徴
- peerDependencies チェック: スキップ
- その他の安全対策: 保持(バージョン解決、ロックファイルの整合性、整合性チェック)
- 推奨される場面: プロジェクトの依存関係が複雑で、peerDependencies の競合が発生している場合の一時的な解決策
--force
オプション
このオプションは、ローカルキャッシュがある場合でもリモートリソースを強制的に取得し、すべてのエラーや警告を無視します。
npm install --force
注意点
- peerDependencies チェック: スキップ
- その他の安全対策: すべて無視
- リスク: 壊れた依存関係ツリー、非再現性のあるビルド、重複したパッケージバージョンが発生する可能性があります
比較表
オプション | peerDependencies チェック | その他の安全対策 | 使用場面 |
---|---|---|---|
なし | 適用 | すべて適用 | デフォルト、理想的 |
--legacy-peer-deps | スキップ | 保持 | 安全な回避策、一時的な解決 |
--force | スキップ | すべて無視 | 最終手段、キャッシュの無効化 |
実例で見る違い
実際のプロジェクトで両オプションを使用した場合、package-lock.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"
}
}
"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. 優先すべき解決策
依存関係の競合が発生した場合、以下の順序で対策を検討してください:
- 根本的な解決: 依存関係のバージョンを調整し、競合を解消する
--legacy-peer-deps
: 一時的な回避策として使用--force
: 最終手段としてのみ使用
2. 設定の永続化
プロジェクトで常に --legacy-peer-deps
が必要な場合は、設定を永続化できます:
npm config set legacy-peer-deps true
ただし、これはチーム全体の開発環境に影響するため、慎重に判断してください。
3. 代替手段の検討
npm dedupe
: 重複した依存関係を整理する--strict-peer-deps
: より厳格な peerDependencies チェックを適用する
結論
一般的に、--legacy-peer-deps
は --force
よりも安全なオプションです。--legacy-peer-deps
は peerDependencies のチェックのみをスキップする一方、--force
はすべての安全対策を無視するため、予期しない問題を引き起こす可能性があります。
依存関係の問題に対処する際は、常に根本的な解決を優先し、これらのフラグは一時的な回避策としてのみ使用することをお勧めします。