Ch4. Turborepo 파이프라인과 캐싱
Task pipeline 설계, dependsOn, remote caching, 빌드 최적화
핵심 요약
dependsOn의^는 의존 패키지 태스크 선행, 접두사 없음은 같은 패키지 내 선행,pkg#task는 특정 패키지 지정을 의미합니다.- Turborepo는 타임스탬프 대신 content-aware hashing(소스·의존 해시·태스크 설정·env·globalDependencies)으로 캐시 히트를 판단하므로, 파일을 되돌려도 캐시를 다시 씁니다.
- Remote caching은 Vercel·자체 S3·GitHub Actions Cache 중 선택하며, 빌드에 영향을 주는
NEXT_PUBLIC_*등은 반드시env에 선언해 캐시 포이즌을 막습니다. - Git worktree를 감지하면 메인 worktree의
.turbo/cache를 공유하지만, 명시적cacheDir지정 시 공유가 꺼집니다. - 2025~2026 신기능으로 Composable Configuration(
extends), Sidecar Tasks, Boundaries,--affected, Daemon deprecation이 추가됐습니다.
turbo.json 파이프라인 설계
// turbo.json
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": ["**/.env.*local"],
"globalEnv": ["NODE_ENV", "VERCEL_URL"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**", "dist/**"]
},
"dev": {
"cache": false,
"persistent": true
},
"lint": {
"dependsOn": ["^build"]
},
"test": {
"dependsOn": ["^build"],
"inputs": ["src/**", "tests/**", "vitest.config.*"]
},
"typecheck": {
"dependsOn": ["^build"]
}
}
}dependsOn과 실행 순서
| 접두사 | 의미 | 예시 |
|---|---|---|
^ | 의존 패키지의 태스크 먼저 실행 | "dependsOn": ["^build"] |
| 없음 | 같은 패키지 내 태스크 먼저 실행 | "dependsOn": ["lint"] |
$ | 특정 패키지의 태스크 지정 | "dependsOn": ["@org/types#build"] |
^build는 "내가 의존하는 모든 패키지의 build가 끝난 뒤 내 build를 시작하라"는 뜻입니다. Turborepo가 의존성 그래프를 분석해 최대한 병렬로 실행합니다.
Content-aware hashing
Turborepo는 파일 내용을 해싱해 캐시 히트를 판단합니다.
해시 입력:
├── 소스 파일 내용 (inputs에 매칭되는 파일)
├── 의존 패키지의 해시
├── turbo.json의 태스크 설정
├── env에 선언된 환경 변수 값
└── globalDependencies 파일 내용타임스탬프가 아니라 내용 기반이라, 파일을 되돌려도 이전 캐시를 그대로 씁니다.
Remote caching
| 방식 | 설정 | 장점 | 단점 |
|---|---|---|---|
| Vercel | npx turbo login + npx turbo link | 제로 설정, 팀 자동 공유 | Vercel 계정 필요 |
| 자체 S3 | turbo.json에 endpoint 설정 | 완전 통제, 비용 최적화 | 서버 운영 필요 |
| GitHub Actions Cache | actions/cache + .turbo | CI 한정, 추가 인프라 없음 | 팀원 로컬에선 불가 |
# Vercel Remote Cache 연결
npx turbo login
npx turbo link
# CI 환경 변수 (GitHub Actions)
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}환경 변수와 캐시 무효화
{
"globalEnv": ["NODE_ENV"], // 모든 태스크의 캐시 키에 포함
"globalPassThroughEnv": ["CI"], // 캐시 키에서 제외 (런타임에만 사용)
"tasks": {
"build": {
"env": ["DATABASE_URL"], // 이 태스크 캐시 키에만 포함
"passThroughEnv": ["DEBUG"] // 이 태스크에서 캐시 키 제외
}
}
}캐시 포이즌 방지
NEXT_PUBLIC_* 환경 변수를 env에 선언하지 않으면, 환경 변수가 바뀌어도 이전 캐시가 사용됩니다.
빌드 결과에 영향을 주는 환경 변수는 반드시 env에 명시하세요.
변경 감지와 캐시 디버깅
# 캐시 히트/미스 상세 확인
turbo run build --summarize
# 변경된 패키지와 영향을 받는 패키지만 실행
turbo run build test lint --affected
# 특정 패키지만 빌드 (필터)
turbo run build --filter=apps/web
# 변경된 패키지만 빌드 (since)
turbo run build --filter=...[HEAD~1]
# 캐시 무시하고 전체 빌드
turbo run build --force--summarize 플래그는 .turbo/runs/ 디렉토리에 JSON 리포트를 남깁니다. 캐시 미스가 난 이유를 추적할 때 유용합니다.
--affected는 현재 브랜치에서 바뀐 패키지와 그 변경의 영향을 받는 패키지를 실행합니다. CI에서는 actions/checkout에 fetch-depth: 0을 줘야 기준 브랜치와 비교할 수 있습니다.
Git worktree 캐시 공유
Turborepo는 Git worktree를 감지하면 기본 로컬 캐시를 메인 worktree의 .turbo/cache로 공유합니다. 에이전트가 git worktree add로 여러 브랜치를 한꺼번에 작업하는 팀이라면 같은 머신의 캐시 히트율이 크게 올라갑니다.
git worktree add ../acme-checkout feat/checkout
cd ../acme-checkout
turbo run build --affectedcacheDir 설정 주의
turbo.json에 명시적인 cacheDir을 지정하면 worktree 캐시 공유가 꺼지고 각 worktree가 별도 캐시를 사용합니다. 특별한 이유가 없다면 기본 캐시 디렉토리를 유지하세요.
2025~2026 Turborepo 신기능
Composable Configuration
turbo.jsonc를 지원하면서 설정을 앱·패키지별로 나눠 합성할 수 있게 됐습니다:
// apps/web/turbo.json — 앱별 태스크 오버라이드
{
"extends": ["//"],
"tasks": {
"build": {
"env": ["NEXT_PUBLIC_API_URL"]
}
}
}Sidecar Tasks
메인 태스크와 함께 실행되는 보조 프로세스를 선언할 수 있습니다. 개발 서버와 함께 타입 체크 워처를 자동 실행하는 등의 패턴에 유용합니다.
Boundaries
패키지 간 의존성 규칙을 선언적으로 정의하고 위반을 잡아냅니다. 캐싱을 더 안전하게 하고 모노레포 아키텍처 규칙을 자동으로 검증합니다.
// turbo.json
{
"boundaries": {
"tags": {
"packages/ui": ["ui"],
"packages/db": ["data"]
},
"deny": [
{ "from": "ui", "to": "data" }
]
}
}기타 변경
| 항목 | 버전 | 설명 |
|---|---|---|
--affected | 2.x | 변경된 패키지와 dependents만 실행하는 CI 기본 플래그 |
| Worktree cache sharing | 2.8+ | Git worktree 간 로컬 캐시 자동 공유 |
| Devtools | 2.8+ | 패키지·태스크 그래프 시각화 |
turbo docs | 2.8+ | AI 에이전트가 읽기 쉬운 문서 응답 |
| Daemon deprecation | 2.9+ | 명시적 --daemon 사용을 줄이고 기본 실행 경로에 맞춤 |
참고 문서
- Turborepo: Configuring Tasks (영어)
- Turborepo: Remote Caching (영어)
- Turborepo: Caching (영어)
- Turborepo: Environment Variables (영어)
- Turborepo: Boundaries (영어)
- Turborepo Blog (영어)