본문으로 건너뛰기

모노레포 워크스페이스 도구 이해하기 (공유 패키지와 증분 빌드)

· 약 5분

모노레포에서 공통 코드를 공유하고, 바뀐 부분만 다시 빌드하게 해 주는 워크스페이스 도구가 무엇이고 어떻게 나뉘는지 정리합니다.

결론부터 말하면, 모노레포 도구는 두 층위로 나뉩니다. 패키지 매니저의 워크스페이스가 공유 패키지를 연결하고, 빌드 오케스트레이터가 바뀐 부분만 다시 빌드(증분 빌드)와 캐시를 담당합니다.

워크스페이스 도구란

워크스페이스 도구는 한 레포 안의 여러 패키지를 함께 관리하게 해 주는 도구입니다. 공통 코드를 여러 앱이 나눠 쓰게 연결하고, 무엇을 다시 빌드할지 정리해 줍니다.

요리에 비유하면, 여러 메뉴(앱)가 공용 재료 창고(공유 패키지)를 함께 쓰고, 재료가 바뀌면 그 재료를 쓰는 메뉴만 다시 조리하는 것과 같습니다. 창고 연결과 "다시 조리할 메뉴 고르기"는 서로 다른 일입니다.

두 층위로 나눠 보기

도구를 두 층위로 나눠 보면 역할이 분명해집니다.

층위역할대표 도구
패키지 매니저 워크스페이스공유 패키지를 연결(의존성)pnpm/yarn workspaces, uv, Cargo, Go workspace
빌드 오케스트레이터task 그래프 + 증분 빌드·캐시Turborepo, Nx

둘은 함께 씁니다. 패키지 매니저가 "무엇을 공유하는지"를 알고, 오케스트레이터가 "무엇을 다시 만들지"를 정합니다.

패키지 매니저 워크스페이스가 공유 패키지를 연결하고, 빌드 오케스트레이터가 증분 빌드와 캐시��를 담당하는 두 층위 구분

공유 패키지 연결 (패키지 매니저)

첫 층위는 공유 패키지를 연결하는 일입니다. 워크스페이스를 선언하면, 한 패키지를 고쳤을 때 그것을 쓰는 앱이 즉시 같은 코드를 봅니다. 버전을 올려 배포하고 다시 받아오는 왕복이 사라집니다.

# pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
// apps/web/package.json (공유 패키지를 그대로 의존)
{ "dependencies": { "@acme/ui": "workspace:*" } }

이 연결이 모노레포의 가장 큰 이점입니다. 공유 코드와 계약이 한 커밋에서 같이 움직입니다.

바뀐 것만 빌드 (오케스트레이터)

둘째 층위는 바뀐 것만 다시 빌드하는 일입니다. 빌드 오케스트레이터는 패키지 사이의 의존 그래프를 알고 있어서, 바뀐 패키지와 그 영향을 받는 앱만 다시 빌드하고 나머지는 캐시 결과를 씁니다.

turbo run build       # 바뀐 것 + 영향받는 것만 빌드, 나머지는 캐시

핵심은 캐시입니다. 입력(소스·의존·설정)이 그대로면 이전 빌드 결과를 그대로 가져옵니다. 전체를 매번 다시 빌드하지 않으니, 레포가 커져도 피드백이 느려지지 않습니다.

변경된 공유 패키지와 그것을 의존하는 앱만 다시 빌드하고, 무관한 패키지·앱은 캐시 결과를 가져오는 증분 빌드

흔한 함정

  • 순환 의존: 패키지 A가 B를, B가 다시 A를 의존하면 그래프가 꼬여 증분 빌드가 어긋납니다. 의존 방향을 한쪽으로 유지합니다.
  • 캐시 키를 잘못 잡음: 빌드에 영향을 주는 입력(환경 변수·설정 파일 등)을 캐시 키에서 빠뜨리면, 바뀌었는데도 옛 캐시를 가져옵니다. 입력을 빠짐없이 키에 포함합니다.
  • 결국 전부 빌드: 의존을 너무 넓게 걸면 작은 변경에도 전부 다시 빌드됩니다. 공유 패키지를 잘게 나눠 영향 범위를 좁힙니다.

Q&A

  • 패키지 매니저 워크스페이스만 있으면 안 되나요?
    • 공유는 됩니다. 다만 "무엇을 다시 빌드할지"는 직접 관리해야 합니다. 레포가 커지면 증분 빌드·캐시를 주는 오케스트레이터의 이점이 커집니다.
  • Turborepo와 Nx 중 무엇을 고르나요?
    • 핵심 기능(task 그래프·캐시)은 비슷합니다. 설정이 가볍고 단순하면 Turborepo, 플러그인과 코드 생성까지 폭넓게 쓰려면 Nx가 흔한 선택입니다.
  • JS가 아닌 언어도 되나요?
    • 됩니다. uv(파이썬), Cargo(러스트), Go workspace가 같은 "워크스페이스" 개념을 제공합니다. 오케스트레이터도 언어 무관하게 task를 묶을 수 있습니다.

참고자료

  • Turborepo / Nx Docs: Task Graph / Caching
  • pnpm / uv / Cargo / Go Workspaces