點對點如何解析
pnpm 最棒的功能之一是,在一個專案中,特定版本的套件永遠只會有一組相依性。不過,這個規則有一個例外,那就是有 同儕相依性 的套件。
同儕相依性會從相依性圖中較高層級安裝的相依性中解析,因為它們與其父項共用相同的版本。這表示如果 foo@1.0.0
有兩個同儕 (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
有兩組不同的依賴項:一組與 baz@1.0.0
,另一組與 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@1.0.0_bar@1.0.0+baz@1.1.0
內部的 foo
。因此,Node.js 模組解析器將找到正確的對等項。
如果套件沒有對等依賴項,但有依賴項與在圖表中較高層級解析的對等項,則該傳遞依賴項可能出現在專案中,並有不同的依賴項組。例如,有套件 a@1.0.0
,單一依賴項為 b@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
中出現兩次 - 一次解析為 c@1.0.0
,另一次解析為 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