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


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

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

ProjectA | |- moduleA |- moduleB

| |

| |- moduleA

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

   → ProjectA에서 npm install하면 각 모듈의 package,json을 보고, ProjectA의 node_modules에 의존관계를 셋업한다.
   → 하부모듈은 자신이 디펜던시를 가지고 있지 않으면, 상부 모듈의 디펜던시를 자동으로 읽지만, 그 반대 방향은 성립하지 않는다. 예를 들어, moduleB 는 moduleA이 디펜던시로 써 필요한데, ProjectA직하에 moduleA가 존재하기 때문에 따로 설치하지 않고 상부의 moduleA를 참조하여 읽는다.
    → moduleB이하에 있는 moduleA의 버전이 0.5.0이고, 부모어플 직하에 있는 moduleA의 버전이 1.5.0이면 각 node_modules에 서로 다른 버전을 인스톨해준다ProjectA의 node_modules에는 1.5.0버전의 moduleA을 인스톨하고, moduleB의 node_modules에는 0.5.0의 moduleA를 인스톨한다. (직접확인 완료, npm 버전 6.7.0)


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



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


それぞれの違い

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

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

そのため、3.のpeerDependenciesをmoduleBが使っていれば、警告としてProjectA側に通知することができるので、ProjectA側は明示的に(意図的に)moduleA:0.5.0を追加することができる。

はまったところ

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

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

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

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

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

疑問に対する推測

peerDependenciesってProjectAに設定するものじゃないのか?

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

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

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

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

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


'C Lang > npm' 카테고리의 다른 글

package.js의 구성요소 분석하기  (0) 2019.06.16
미처 알지 못했던 package-lock.json  (0) 2019.03.12

+ Recent posts