Movatterモバイル変換


[0]ホーム

URL:


Ana içeriğe atla
Bu, artık aktif olarak desteklenmeyen pnpm8.x versiyonuna ait dökümantasyondur.
Güncel dokümantasyon için, şuraya bakın:en son sürüm (10.x).
Sürüm: 8.x

How peers are resolved

One of the best features of pnpm is that in one project, a specific version of a package will always have one set of dependencies. There is one exception from this rule, though - packages withpeer dependencies.

Peer dependencies are resolved from dependencies installed higher in the dependency graph, since they share the same version as their parent. That means that iffoo@1.0.0 has two peers (bar@^1 andbaz@^1) then it might have multiple different sets of dependencies in the same project.

- 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

In the example above,foo@1.0.0 is installed forfoo-parent-1 andfoo-parent-2. Both packages havebar andbaz as well, but they depend on different versions ofbaz. As a result,foo@1.0.0 has two different sets of dependencies: one withbaz@1.0.0 and the other one withbaz@1.1.0. To support these use cases, pnpm has to hard linkfoo@1.0.0 as many times as there are different dependency sets.

Normally, if a package does not have peer dependencies, it is hard linked to anode_modules folder next to symlinks of its dependencies, like so:

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

However, iffoo has peer dependencies, there may be multiple sets of dependencies for it, so we create different sets for different peer dependency resolutions:

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

We create symlinks either to thefoo that is insidefoo@1.0.0_bar@1.0.0+baz@1.0.0 or to the one infoo@1.0.0_bar@1.0.0+baz@1.1.0. As a consequence, the Node.js module resolver will find the correct peers.

If a package has no peer dependencies but has dependencies with peers that are resolved higher in the graph, then that transitive package can appear in the project with different sets of dependencies. For instance, there's packagea@1.0.0 with a single dependencyb@1.0.0.b@1.0.0 has a peer dependencyc@^1.a@1.0.0 will never resolve the peers ofb@1.0.0, so it becomes dependent from the peers ofb@1.0.0 as well.

Here's how that structure will look innode_modules. In this example,a@1.0.0 will need to appear twice in the project'snode_modules - resolved once withc@1.0.0 and again withc@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

[8]ページ先頭

©2009-2025 Movatter.jp