ピアの解決方法
pnpm の最も優れた機能の1つは、1つのプロジェクト内で、特定のバージョンのパッケージが常に1つの依存関係セットを持つことです。ただし、このルールには1つの例外があります - ピア依存関係を持つパッケージです。
ピア依存関係は、依存関係グラフの上位にインストールされた依存関係から解決されます。これは、親と同じバージョンを共有するためです。つまり、`foo@1.0.0` に2つのピア(`bar@^1` と `baz@^1`)がある場合、同じプロジェクト内に複数の異なる依存関係セットが存在する可能性があります。
- foo-parent-1
  - bar@1.0.0
  - baz@1.0.0
  - foo@1.0.0
- foo-parent-2
  - bar@1.0.0
  - baz@1.1.0
  - foo@1.0.0
上記の例では、`foo@1.0.0` は `foo-parent-1` と `foo-parent-2` にインストールされています。どちらのパッケージにも `bar` と `baz` がありますが、異なるバージョンの `baz` に依存しています。その結果、`foo@1.0.0` には2つの異なる依存関係セットがあります。1つは `baz@1.0.0` を含み、もう1つは `baz@1.1.0` を含みます。これらのユースケースをサポートするために、pnpm は異なる依存関係セットの数だけ `foo@1.0.0` をハードリンクする必要があります。
通常、パッケージにピア依存関係がない場合、依存関係のシンボリックリンクの横に `node_modules` フォルダーにハードリンクされます。
node_modules
└── .pnpm
    ├── foo@1.0.0
    │   └── node_modules
    │       ├── foo
    │       ├── qux   -> ../../qux@1.0.0/node_modules/qux
    │       └── plugh -> ../../plugh@1.0.0/node_modules/plugh
    ├── qux@1.0.0
    ├── plugh@1.0.0
ただし、`foo` にピア依存関係がある場合、複数の依存関係セットが存在する可能性があるため、異なるピア依存関係の解決に対して異なるセットを作成します。
node_modules
└── .pnpm
    ├── foo@1.0.0_bar@1.0.0+baz@1.0.0
    │   └── node_modules
    │       ├── foo
    │       ├── bar   -> ../../bar@1.0.0/node_modules/bar
    │       ├── baz   -> ../../baz@1.0.0/node_modules/baz
    │       ├── qux   -> ../../qux@1.0.0/node_modules/qux
    │       └── plugh -> ../../plugh@1.0.0/node_modules/plugh
    ├── foo@1.0.0_bar@1.0.0+baz@1.1.0
    │   └── node_modules
    │       ├── foo
    │       ├── bar   -> ../../bar@1.0.0/node_modules/bar
    │       ├── baz   -> ../../baz@1.1.0/node_modules/baz
    │       ├── qux   -> ../../qux@1.0.0/node_modules/qux
    │       └── plugh -> ../../plugh@1.0.0/node_modules/plugh
    ├── bar@1.0.0
    ├── baz@1.0.0
    ├── baz@1.1.0
    ├── qux@1.0.0
    ├── plugh@1.0.0
`foo@1.0.0_bar@1.0.0+baz@1.0.0` 内にある `foo` へのシンボリックリンク、または `foo@1.0.0_bar@1.0.0+baz@1.1.0` 内にある `foo` へのシンボリックリンクを作成します。結果として、Node.js モジュールリゾルバーは正しいピアを見つけます。
パッケージにピア依存関係がないが、グラフの上位で解決されるピアを持つ依存関係がある場合、その推移的なパッケージは、異なる依存関係セットを持つプロジェクトに表示される可能性があります。たとえば、単一の依存関係 `b@1.0.0` を持つパッケージ `a@1.0.0` があります。 `b@1.0.0` にはピア依存関係 `c@^1` があります。 `a@1.0.0` は `b@1.0.0` のピアを解決しないため、`b@1.0.0` のピアにも依存するようになります。
`node_modules` での構造は次のようになります。この例では、`a@1.0.0` はプロジェクトの `node_modules` に2回表示される必要があります。1回は `c@1.0.0` で解決され、もう1回は `c@1.1.0` で解決されます。
node_modules
└── .pnpm
    ├── a@1.0.0_c@1.0.0
    │   └── node_modules
    │       ├── a
    │       └── b -> ../../b@1.0.0_c@1.0.0/node_modules/b
    ├── a@1.0.0_c@1.1.0
    │   └── node_modules
    │       ├── a
    │       └── b -> ../../b@1.0.0_c@1.1.0/node_modules/b
    ├── b@1.0.0_c@1.0.0
    │   └── node_modules
    │       ├── b
    │       └── c -> ../../c@1.0.0/node_modules/c
    ├── b@1.0.0_c@1.1.0
    │   └── node_modules
    │       ├── b
    │       └── c -> ../../c@1.1.0/node_modules/c
    ├── c@1.0.0
    ├── c@1.1.0