質問: vue/webpack などの大きめな js フレームワークを利用していると、ほぼほぼ確実に `パッケージ名 has unmet peer dependency 別のパッケージ名` の warning が `npm install` 時に表示されます。 そして、割とそのままの状態でも問題なく動いたりします。 ### 質問 * npm において has unmet peer dependency とはどういう状態ですか?
回答: ### peer dependencyとは Peer dependencyは,パッケージ間の依存の一種であり,**依存先が自動的にはインストールされないもの**を指します. パッケージAがパッケージBに(peerではない通常の)依存をする場合,Aを`npm`でインストールすると依存関係が解消され,自動的にBもインストールされます.一方,AからBへの依存がpeer dependencyである場合,AをインストールしてもBは自動的にはインストールされません. Peer dependencyの使い所はいくつかありますが,peer dependencyはAがBを`require`するわけではないような場合に適しています.むしろ逆に,直接的もしくは間接的にBがAを`require`するような場合に,AからBへのpeer dependencyを設定するべきです.npmのドキュメントでも言及されているように,このような状況はAがB用の**プラグイン**である場合によく現れます. 例えば,html-webpack-pluginは`webpack@^4.0.0`へのpeer dependencyが設定されています(回答時点).これは,html-webpack-pluginが(現行バージョンである)webpack4系をサポートしているという意味に捉えることができます.すなわち,webpack3系(あるいはもっと前のバージョン)は4系と挙動が違うために,html-webpack-pluginを使おうとしても上手くいかない可能性があります.また,将来webpack5系が出た場合,動作に破壊的変更があるかもしれないため,html-webpack-pluginの動作は保証されません. このように,別のパッケージへのプラグインとして協調して動作するようなパッケージの場合に,正しく動作できるバージョンを指定するというのがpeer dependencyの代表的なユースケースです.Peer dependencyの対象が自動的にインストールされないという挙動は,その必要がないことから説明できます.例えば上の例のhtml-webpack-pluginをインストールする場合,peer依存先のwebpackは普通はすでにインストールされているはずです. ### unmet peer dependencyの意味 文字通り,**peer dependencyの指定が満たされていない**ことを意味します.例えば,webpack4系をpeer dependencyに持つhtml-webpack-pluginを,webpack3系と一緒にインストールした場合はこの警告が出ることになります. Peer dependencyは依存先を一緒にインストールするものでありませんから,**このunmet peer dependency警告を出すことが主たる機能である**といえます.一般には,**unmet peer dependencyという警告が出る状態では,パッケージが正しく動作することを期待すべきではありません**.あるパッケージAのpeer dependencyとなっているパッケージBが正しくインストールされていないということは,AがBと協調して動作するという保証がないということです.実際にunmet peer dependencyという警告が発生する場合にはいくつかの状態が考えられます. * 本当にpeer dependencyの指定が満たされていないと動作しない場合. この場合は何かまずいことが発生するでしょうから,関連パッケージの現状を調査して状況を改善する必要があります.大抵の場合は依存元と依存先のどちらかが古いので,アップデートする必要があります. * 依存先のバージョンアップに追随できていない場合. html-webpack-pluginの例において,webpack5系が正式にリリースされた直後などは,まだhtml-webpack-pluginのpeer dependencyはv4系のままかもしれません.この場合,webpackを5系にアップデートするとこの警告が発生します.このケースでは,まだhtml-webpack-pluginがwebpack5系と協調して動作できるか不明ですので,やはり対処が必要です.具体的には,webpackを4系に戻して様子見をする必要があります.html-webpack-pluginがそのうち対応する(webpack5系に対応するようにアップデートされる.最低でもpeer dependencyの対象が広げられる)でしょうから,それまで待つことになります. * peer dependencyの指定が不適切な場合 この質問の場合のように,実際は問題ないのにpeer dependencyの対象バージョンが不必要に狭い場合もあります.この場合も,基本的にはunmet dependency警告が出る場合はissueに上がるでしょうから,パッケージ側の対処を待つことになります. 「割とそのままの状態でも問題なく動く」場合というのは,2番目のケースでバージョンが上がったけど関連部分の互換性が壊れていなかったという場合や,3番目のケースが相当するでしょう.