작업 공간
pnpm은 기본적으로 ('multi-package repositories', 'multi-project repositories', 'monolithic repositories'로도 알려진) 모노레포를 지원합니다. 하나의 레포지토리에 다수의 프로젝트가 존재하는 워크스페이스를 생성할 수 있습니다.
워크스페이스는 루트에 반드시 pnpm-workspace.yaml 파일이 있어야 합니다.
팁
모노레포 관리를 알아보고 있다면 Bit도 살펴보는 것이 좋습니다.
내부적으로 pnpm을 사용하는 Bit은 기존에 pnpm/npm/Yarn으로 관리되는 workspace에서 수동으로 이루어지는 많은 일을 자동으로 처리합니다. 이에 대해 다루는 bit install에 관한 글이 있습니다: Painless Monorepo Dependency Management with Bit.
Workspace 프로토콜 (workspace:)#
linkWorkspacePackages가 true로 설정된 경우, 사용 가능한 패키지가 선언된 범위와 일치하면 pnpm은 워크스페이스의 패키지를 링크합니다. 예를 들어, bar의 종속성에 "foo": "^1.0.0"이 있고 foo@1.0.0이 워크스페이스에 있으면 foo@1.0.0이 bar에 링크됩니다. 하지만 bar의 종속성에 "foo": "2.0.0"이 있고 foo@2.0.0이 워크스페이스에 없으면 foo@2.0.0은 레지스트리에서 설치됩니다. 이 동작은 다소 불확실합니다.
다행히 pnpm은 workspace: 프로토콜을 지원합니다. 이 프로토콜을 사용한다면, pnpm은 로컬 workspace 바깥의 패키지에서는 작업을 수행하지 않습니다. 따라서 "foo": "workspace:2.0.0"으로 설정하면, 이번에는 "foo@2.0.0"이 워크스페이스에 없으므로 설치가 실패합니다.
이 프로토콜은 linkWorkspacePackages 옵션이 false로 설정된 경우 특히 유용합니다. 이 경우 pnpm은 workspace: 프로토콜이 사용된 경우에만 워크스페이스의 패키지를 링크합니다.
별칭으로 workspace 패키지를 참조하기#
워크스페이스에 foo라는 이름의 패키지가 있다고 가정해 보겠습니다. 일반적으로 "foo": "workspace:*"와 같이 참조합니다.
다른 별칭을 사용하려면 다음 구문도 사용할 수 있습니다: "bar": "workspace:foo@*".
이 별칭들은 게시되기 전에 별칭이 가리키는 의존성으로 변환됩니다. 위의 예시는 다음과 같이 됩니다: "bar": "npm:foo@1.0.0".
상대 경로로 workspace 패키지를 참조하기#
2개의 패키지가 포함된 workspace에서
+ packages
+ foo
+ bar
bar는 종속성에 foo를 "foo": "workspace:../foo"로 선언할 수 있습니다. 패키지를 게시하기 전에 이 설명들은 모든 패키지 관리자가 지원하는 일반 버전 설명으로 변환됩니다.
Workspace 패키지를 게시하기#
워크스페이스 패키지가 아카이브로 패킹될 때(pnpm pack을 통하든 pnpm publish와 같은 게시 명령 중 하나를 통하든), 모든 workspace: 종속성을 다음으로 동적으로 대체합니다:
- 대상 워크스페이스의 해당 버전(
workspace:,workspace:*,workspace:~또는workspace:^를 사용하는 경우) - 연관된 시맨틱 범위 (기타 범위 유형의 경우)
버전 범위가 없는 단순 workspace:는 workspace:*로 취급됩니다.
예를 들어 워크스페이스에 foo, bar, qar, zoo가 있고 모두 버전 1.5.0이라면 다음은:
{
"dependencies": {
"foo": "workspace:*",
"bar": "workspace:~",
"qar": "workspace:^",
"zoo": "workspace:^1.5.0"
}
}
이 설명은 다음으로 변환됩니다.
{
"dependencies": {
"foo": "1.5.0",
"bar": "~1.5.0",
"qar": "^1.5.0",
"zoo": "^1.5.0"
}
}
이 기능을 사용하면 로컬 workspace 패키지에 의존할 수 있으면서 동시에 원격 레지스트리에 결과 패키지를 중간 단계없이 게시할 수 있습니다. 패키지 사용자는 다른 패키지처럼 게시된 workspace를 사용할 수 있으며 여전히 시맨틱 제공을 보장받습니다.
릴리즈 워크플로#
pnpm versions and releases workspace packages with
pnpm change and pnpm version -r. See
Release management.
These external tools also handle versioning and support pnpm:
Rush를 사용하여 저장소를 설정하는 방법은 이 페이지를 읽어보세요.
Changesets를 pnpm과 함께 사용하려면 이 가이드를 읽어보세요.
문제 해결 안내#
pnpm은 workspace 의존성에 순환이 있는 경우 스크립트가 토폴로지 순서대로 실행됨을 보장할 수 없습니다. Pnpm이 설치 도중 순환 의존성을 감지하면 경고를 생성합니다. If pnpm can find out which dependencies are causing the cycles, it will display them too.
If you see the message There are cyclic workspace dependencies, inspect workspace dependencies declared in dependencies, optionalDependencies and devDependencies.
Workspaces in the wild#
다음은 pnpm의 workspace 기능을 사용하는 가장 인기 있는 오픈 소스 프로젝트 중 일부입니다.
환경설정#
linkWorkspacePackages#
- 기본값: false
- 유형: true, false, deep
이 옵션을 활성화하면 로컬에서 사용 가능한 패키지가 레지스트리에서 다운로드되는 대신 node_modules에 링크됩니다. 이는 모노레포에서 매우 편리합니다. 로컬 패키지를 하위 종속성에도 링크해야 하는 경우 deep 설정을 사용할 수 있습니다.
그렇지 않으면 패키지는 레지스트리에서 다운로드되어 설치됩니다. 하지만 워크스페이스 패키지는 여전히 workspace: 범위 프로토콜을 사용하여 링크할 수 있습니다.
패키지는 버전이 종속성 범위를 충족하는 경우에만 링크됩니다.
injectWorkspacePackages#
- 기본값: false
- 유형: Boolean
로컬 워크스페이스의 모든 종속성을 심볼릭 링크 대신 하드 링크로 연결합니다. 또는 특정 종속성에 대해 선택적으로 하드 링크를 활성화할 수 있는 dependenciesMeta[].injected를 사용하여 이를 구현할 수도 있습니다.
참고
Even if this setting is enabled, pnpm will prefer to deduplicate injected dependencies using symlinks, unless multiple dependency graphs are required due to mismatched peer dependencies. 이 동작은 dedupeInjectedDeps 설정으로 제어됩니다.
dedupeInjectedDeps#
- 기본값: true
- 유형: Boolean
이 설정을 활성화하면 주입된 종속성이 가능한 한 워크스페이스에서 심볼릭 링크됩니다. 종속 프로젝트와 주입된 종속성이 동일한 피어 종속성을 참조하는 경우, 주입된 종속성을 종속 프로젝트의 node_modules에 물리적으로 복사할 필요 없이 심볼릭 링크로 충분합니다.
syncInjectedDepsAfterScripts#
버전 10.5.0에서 추가됨
- 기본값: undefined
- 유형: String[]
주입된 워크스페이스 종속성은 하드 링크의 모음이므로, 소스가 변경되어도 파일이 추가되거나 제거되지 않습니다. 이로 인해 빌드가 필요한 패키지(예: TypeScript 프로젝트)에서 문제가 발생합니다.
이 설정은 스크립트 이름의 목록입니다. 워크스페이스 패키지에서 이러한 스크립트 중 하나가 실행되면 node_modules 내부의 주입된 종속성도 동기화됩니다.
preferWorkspacePackages#
- 기본값: false
- 유형: Boolean
이 설정을 활성화하면 레지스트리에 더 새로운 버전의 패키지가 있더라도 레지스트리의 패키지보다 워크스페이스의 로컬 패키지가 우선됩니다.
이 설정은 워크스페이스가 saveWorkspaceProtocol을 사용하지 않는 경우에만 유용합니다.
sharedWorkspaceLockfile#
- 기본값: true
- 유형: Boolean
이 옵션을 활성화하면 pnpm은 워크스페이스 루트에 단일 pnpm-lock.yaml 파일을 생성합니다. 이는 또한 워크스페이스 패키지의 모든 종속성이 단일 node_modules에 위치한다는 의미이기도 합니다(그리고 Node의 모듈 해석을 위해 각 패키지의 node_modules 폴더에 심볼릭 링크됩니다).
이 옵션의 장점:
- 모든 종속성이 싱글톤입니다
- 모노레포에서 더 빠른 설치
- 모든 변경이 하나의 파일에 있으므로 코드 리뷰에서 변경 사항이 더 적음
참고
모든 종속성이 루트 node_modules에 하드 링크되더라도, 패키지는 자신의 package.json에 선언된 종속성에만 접근할 수 있으므로 pnpm의 엄격함이 유지됩니다.
이는 앞서 언급한 심볼릭 링크의 결과입니다.
saveWorkspaceProtocol#
- 기본값: rolling
- 유형: true, false, rolling
이 설정은 워크스페이스에서 링크된 종속성이 package.json에 추가되는 방식을 제어합니다.
foo@1.0.0이 워크스페이스에 있고 워크스페이스의 다른 프로젝트에서 pnpm add foo를 실행하는 경우, foo가 종속성 필드에 추가되는 방식은 다음과 같습니다. savePrefix 설정도 사양이 생성되는 방식에 영향을 줍니다.
| saveWorkspaceProtocol | savePrefix | spec |
|---|---|---|
| false | '' |
1.0.0 |
| false | '~' |
~1.0.0 |
| false | '^' |
^1.0.0 |
| true | '' |
workspace:1.0.0 |
| true | '~' |
workspace:~1.0.0 |
| true | '^' |
workspace:^1.0.0 |
| rolling | '' |
workspace:* |
| rolling | '~' |
workspace:~ |
| rolling | '^' |
workspace:^ |
includeWorkspaceRoot#
- 기본값: false
- 유형: Boolean
워크스페이스에서 명령을 재귀적으로 실행할 때 루트 워크스페이스 프로젝트에서도 실행합니다.
ignoreWorkspaceCycles#
- 기본값: false
- 유형: Boolean
When set to true, no workspace dependency cycle warnings will be printed.
It also downgrades an ERR_PNPM_TASK_CYCLE from a recursive run to a warning.
The tasks in that cycle then have no guaranteed order relative to each other.
See Workspace task orchestration.
disallowWorkspaceCycles#
- 기본값: false
- 유형: Boolean
true로 설정하면 워크스페이스에 순환이 있을 경우 설치가 실패합니다.
workspaceConcurrency#
- Default: the smaller of 4 and the number of available CPU cores
- 유형: Number
Controls how many workspace tasks run at once. See
--workspace-concurrency for details.
ignoreWorkspaceRootCheck#
- 기본값: false
- 유형: Boolean
Allow adding dependencies to the workspace root without passing
--ignore-workspace-root-check or -w.
ignoreWorkspaceRootCheck: true
failIfNoMatch#
- 기본값: false
- 유형: Boolean
true로 설정하면 제공된 필터와 일치하는 패키지가 없을 때 CLI가 오류 종료 코드로 종료됩니다.
예를 들어, 다음 명령은 bad-pkg-name이 워크스페이스에 없으므로 오류 종료 코드로 종료됩니다:
pnpm --filter=bad-pkg-name test