同级依赖解析
pnpm 最好的功能之一是在一个项目中,特定版本的包始终只有一组依赖项。不过,有一个例外 - 具有 同级依赖 的包。
同级依赖从依赖项图中更高层安装的依赖项中解析,因为它们与父级共享相同的版本。这意味着如果 [email protected]
有两个同级依赖(bar@^1
和 baz@^1
),那么它可能在同一个项目中具有多个不同的依赖项集。
- foo-parent-1
- [email protected]
- [email protected]
- [email protected]
- foo-parent-2
- [email protected]
- [email protected]
- [email protected]
在上面的示例中,[email protected]
为 foo-parent-1
和 foo-parent-2
安装。这两个包都有 bar
和 baz
,但它们依赖于不同版本的 baz
。因此,[email protected]
有两组不同的依赖项:一组是 [email protected]
,另一组是 [email protected]
。为了支持这些用例,pnpm 必须像不同依赖项集的数量一样多次硬链接 [email protected]
。
通常,如果一个包没有同级依赖,它会被硬链接到一个 node_modules
文件夹中,该文件夹位于其依赖项的符号链接旁边,如下所示
node_modules
└── .pnpm
├── [email protected]
│ └── node_modules
│ ├── foo
│ ├── qux -> ../../[email protected]/node_modules/qux
│ └── plugh -> ../../[email protected]/node_modules/plugh
├── [email protected]
├── [email protected]
但是,如果 foo
有同级依赖,那么它可能有多组依赖项,因此我们为不同的同级依赖解析创建不同的集合
node_modules
└── .pnpm
├── [email protected][email protected][email protected]
│ └── node_modules
│ ├── foo
│ ├── bar -> ../../[email protected]/node_modules/bar
│ ├── baz -> ../../[email protected]/node_modules/baz
│ ├── qux -> ../../[email protected]/node_modules/qux
│ └── plugh -> ../../[email protected]/node_modules/plugh
├── [email protected][email protected][email protected]
│ └── node_modules
│ ├── foo
│ ├── bar -> ../../[email protected]/node_modules/bar
│ ├── baz -> ../../[email protected]/node_modules/baz
│ ├── qux -> ../../[email protected]/node_modules/qux
│ └── plugh -> ../../[email protected]/node_modules/plugh
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
我们创建符号链接到 [email protected][email protected][email protected]
中的 foo
或 [email protected][email protected][email protected]
中的 foo
。因此,Node.js 模块解析器将找到正确的同级依赖。
如果一个包没有同级依赖,但其依赖项具有在图中更高层解析的同级依赖,那么该传递包可能会以不同的依赖项集出现在项目中。例如,有一个包 [email protected]
,它只有一个依赖项 [email protected]
。[email protected]
有一个同级依赖 c@^1
。[email protected]
永远不会解析 [email protected]
的同级依赖,因此它也成为 [email protected]
的同级依赖的依赖项。
以下是该结构在 node_modules
中的外观。在这个示例中,[email protected]
需要在项目的 node_modules
中出现两次 - 一次解析为 [email protected]
,另一次解析为 [email protected]
。
node_modules
└── .pnpm
├── [email protected][email protected]
│ └── node_modules
│ ├── a
│ └── b -> ../../[email protected][email protected]/node_modules/b
├── [email protected][email protected]
│ └── node_modules
│ ├── a
│ └── b -> ../../[email protected][email protected]/node_modules/b
├── [email protected][email protected]
│ └── node_modules
│ ├── b
│ └── c -> ../../[email protected]/node_modules/c
├── [email protected][email protected]
│ └── node_modules
│ ├── b
│ └── c -> ../../[email protected]/node_modules/c
├── [email protected]
├── [email protected]