跳到主内容
版本:9.x

对等依赖 (peers) 是如何被处理的

pnpm 的最佳特性之一是,在一个项目中,软件包的特定版本将始终具有同一组依赖项。 不过,这个规则有一个例外 - 具有 [对等依赖项][peer dependedncies] 的软件包。

对等依赖会从依赖图中更高的已安装的依赖项中解析,因为它们与父级共享相同的版本。 这意味着 如果 [email protected] 有两个对等(bar@^1baz@^1)那么它可能在同一个项目中有 多组不同的依赖项。

在上面的示例中, [email protected] 已安装在 foo-parent-1foo-parent-2 中。 这两个包都有依赖包 bazbar, 但是它们却依赖着不同版本的 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][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]