为了提高英语水平和保持技术成长,开始按计划翻译一些短篇和博客,有问题欢迎讨论👻
原文:How peers are resolved
正文
pnpm最大的一个特点是,在一个项目中,一个特定版本的package总是有一组依赖关系。不过,这个规则有一个例外–有peer dependencies的packages
在dependency graph中,peer dependencies是从更高级别的依赖中解析的,因为它们与它们的父依赖项共享相同的版本。这意味着如果foo@1.0.0有两个peer依赖项(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安装的。这两个packages中都有bar和baz,但是他们依赖不同版本的baz。因此,foo@1.0.0有两个不同的依赖集:一个是baz@1.0.0,另一个是baz@1.1.0。为了支持这些用例,pnpm必须hand link foo@1.0.0,次数和不同的依赖集一样多。
通常,如果一个package没有peer依赖项,它会与其依赖项的symlinks一起hard linked到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有peer dependencies,它可能有多组依赖关系,所以我们为不同的peer dependencies 创建不同的集合:
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
我们要么创建symlinks到foo@1.0.0_bar@1.0.0+baz@1.0.0
中的foo,要么创建symlinks到foo@1.0.0_bar@1.0.0+baz@1.1.0
中的foo。因此,Node.js模块解析可以找到正确的peers依赖项。
如果一个package没有peer依赖项,但是有依赖于已在图中解析的同级依赖项的依赖项,那么这个transitive package可以以不同的依赖项集出现在项目中。例如,存在一个版本为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