package.jsonのpeerDependenciesについての理解

依存の解決の違い(dependencies, devDependencies, peerDependencies)

親アプリで利用されるためのnpmモジュールを開発している時に、このモジュールをインストールするときはmoduleA:0.5.0と一緒にインストールする必要がある」 というケースを考える

 親アプリ
 |
 |- このモジュール
 |          |
 |          |- moduleA

1. このモジュールのpackage.jsonのdependenciesにmoduleA:0.5.0を書いた場合
親アプリにも自動的にmoduleA:0.5.0がインストールされるが、もし親アプリのpackage.jsonにmoduleA:1.5.0が設定されてた場合は上書きされて実行時エラーになる



2. このモジュールのpackage.jsonのdevDependenciesにmoduleA:0.5.0を書いた場合
親アプリでnpm installした時に、このモジュールのdevDependenciesは無視されるのでmoduleA:0.5.0はインストールされないため実行時エラーになる
対処: 親アプリ側でmoduleA:0.5.0をpackege.jsonに書く必要がある



3. (1.か2.に加えて) このモジュールのpackage.jsonのpeerDependenciesにmoduleA:0.5.0を書いた場合
npm-v3より前の場合は、親アプリのnode_modulesにmoduleA:0.5.0も一緒にインストールされる(WARNは出る)
npm-v3以降の場合は、 `このモジュール@1.0.0 requires a peer of moduleA@^0.5.0 but none was installed.` みたいなWARNが出るだけでmoduleA:0.5.0はインストールされない


それぞれの違い

2.のケースはそもそもとして、このモジュールの実行に必要なmoduleA:0.5.0をdevDependenciesに書くのは間違いである(開発用途に必要なモジュールではなく、実行に必要なモジュールのため)

1.のケースは親アプリ側がこのモジュールを利用するときにmoduleA:0.5.0が必須なことに気づけないため、なんらかの理由で親アプリのpackage.jsonにmoduleA:1.5.0を入れた場合に、このモジュールが動かなくなることを事前に気づくことができない

そのため、3.のpeerDependenciesをこのモジュールが使っていれば、警告として親アプリ側に通知することができるので、親アプリ側は明示的に(意図的に)moduleA:0.5.0を追加することができる。

はまったところ

この時注意が必要なのは、peerDependenciesはあくまで親アプリ側に警告を促すだけである。
親アプリは `このモジュールがmoduleA:0.5.0に依存しているからそれを利用しよう'と意図的に親アプリのpackage.jsonにmoduleA:0.5.0を追加することができるということが重要である。
もしも親アプリがmoduleA:1.5.0を利用したかったとしてもこのモジュールはmoduleA:0.5.0を使っているので、それぞれのモジュールの依存バージョンの互換性を解決してくれるものではない

どういうときに使うのか?

開発ではmoduleA:1.5.0を使っているが、このモジュールを利用するときは最低でもmoduleA:0.5.0を使ってほしいときとか?

結局、親アプリでmoduleA:1.5.0を参照して、このモジュールではmoduleA:0.5.0を参照するようにして依存性をよしなに解決して同時に使いたい

そのままではできないっぽい。
(なんかごにょごにょ工夫すればできるかもしれないけど)

疑問に対する推測

peerDependenciesって親アプリに設定するものじゃないのか?

親アプリのpeerDependenciesに指定することにより、このモジュールがどのバージョンのmoduleAに依存しているのかを指定する使い方なのもと思ったがどうやら違うっぽい

  • 親アプリにpeerDependenciesを設定してもこのモジュールのバージョン依存を解決してくれるわけではないっぽい(WARN出るし)
  • そもそも、peerDependenciesの書式的にどのモジュールがどのモジュールのどのバージョンに依存しているという書き方ができない
じゃぁ、devDependenciesとpeerDependenciesの両方に違うバージョンで書いてあるOSSモジュールをよく見るのはなんで?

これとか
リリースバージョンの依存はpeerDependenciesに書いて、開発中とか動作確認中のものはdevDependenciesに書いているのでは?

このモジュールのpeerDependenciesだけに書いた場合、このモジュールでnpm iinstallした場合はどうなるの?

peerDependenciesに書いただけでは、npm installしてもnode_modulesにインストールされない。
dependenciesかdevDependenciesと組み合わせて利用するみたい。








あんまり情報がなくて推測の部分が多い。
あんまりしっくり来てないけどこれ以上時間かけられないのでこんなもんの理解でとどめておく。




package.jsonのpeerDependenciesについて調べた
http://yukidarake.hateblo.jp/entry/2016/02/16/201614

Peer Dependencies
https://nodejs.org/en/blog/npm/peer-dependencies/