본문으로 건너뛰기
버전: Next

피어가 해결되는 방법

pnpm의 가장 좋은 기능 중 하나는 한 프로젝트에서 패키지의 특정 버전이 항상 하나의 의존성 세트를 갖는다는 것입니다. 이 규칙에서 예외가 하나 있습니다. 피어 의존성이 있는 패키지에 대한 것입니다.

피어 의존성은 그들의 부모와 동일한 버전을 공유하기 때문에 의존성 그래프에서 더 높게 설치된 의존성으로부터 해결됩니다. 즉, 만약 foo@1.0.0 에 두 개의 피어(bar@^1baz@^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.0foo-parent-1foo-parent-2에서 설치됩니다. Both packages have bar and baz as well, but they depend on different versions of 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 모듈 resolver는 올바른 피어를 찾습니다.

패키지에 피어 의존성이 없지만 그래프에서 상위 해결된 피어와의 의존성이 있는 경우, 해당 전이 패키지는 의존성 세트가 다른 프로젝트에 나타날 수 있습니다. 예를 들어, 단일 의존성인 b@1.0.0 를 갖는 패키지 a@1.0.0 가 있습니다. b@1.0.0 에는 피어 의존성 c@^1 이 있습니다. a@1.0.0b@1.0.0의 피어를 절대로 해결하지 않으므로, b@1.0.0 의 피어에서도 종속이 됩니다.

이 구조가 node_modules에서 어떻게 보일지 보여줍니다. 이 예시에서, a@1.0.0 는 프로젝트의 node_modules에서 c@1.0.0 로 한 번, c@1.1.0로 다시 resolve되어 두 번 나타나야 합니다.

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