Turborepo 완벽 가이드 | Monorepo·빌드 캐싱·병렬 실행·pnpm·실전 활용
이 글의 핵심
Turborepo로 고성능 Monorepo를 구축하는 완벽 가이드. 빌드 캐싱, 병렬 실행, pnpm Workspace 통합까지 실전 예제로 정리. Turborepo·Monorepo·Build 중심으로 설명합니다. Start now.
🎯 이 글을 읽으면 (읽는 시간: 40분)
TL;DR: Turborepo로 Monorepo 빌드를 5배 빠르게 만드는 방법을 배웁니다. 빌드 캐싱, 병렬 실행, pnpm Workspace 통합까지 실전 예제로 완벽하게 마스터합니다. 이 글을 읽으면
-
✅ Turborepo 설치부터 설정까지 완벽 이해
-
✅ 빌드 캐싱으로 CI/CD 시간 80% 단축
-
✅ 병렬 실행으로 빌드 속도 5배 향상
-
✅ pnpm Workspace와 통합하여 프로덕션 레벨 구축 실무 활용
-
🔥 대규모 Monorepo 프로젝트 관리
-
🔥 CI/CD 파이프라인 최적화
-
🔥 팀 개발 생산성 향상
-
🔥 빌드 비용 절감 난이도: 중급 | 실습 예제: 10개 | 프로덕션 레벨
이 글의 핵심
Turborepo로 고성능 Monorepo를 구축하는 완벽 가이드입니다. 빌드 캐싱, 병렬 실행, pnpm Workspace 통합까지 실전 예제로 정리했습니다.
실무 경험 공유: Lerna에서 Turborepo로 전환하면서, 빌드 시간이 10분에서 2분으로 단축되고 CI/CD가 5배 빨라진 경험을 공유합니다.
들어가며: “Monorepo 빌드가 느려요”
실무에서 마주치는 문제들
빌드가 너무 느려요
순차 빌드는 느립니다. Turborepo는 병렬 실행합니다. 캐싱이 없어요
매번 전체 빌드합니다. Turborepo는 스마트 캐싱을 제공합니다. 의존성 관리가 어려워요
수동 관리가 필요합니다. Turborepo는 자동으로 처리합니다.
1. Turborepo란?
핵심 특징
Turborepo는 Vercel이 만든 고성능 Monorepo 빌드 시스템입니다. 주요 장점
- 빠른 빌드: 병렬 실행
- 스마트 캐싱: 변경된 것만 빌드
- Remote Cache: 팀 간 캐시 공유
- 간단한 설정: 최소한의 설정
- pnpm/yarn/npm: 모두 지원
2. 프로젝트 설정
설치
npx create-turbo@latest
프로젝트 구조
my-turborepo/
├── apps/
│ ├── web/
│ │ ├── package.json
│ │ └── next.config.js
│ └── docs/
│ ├── package.json
│ └── next.config.js
├── packages/
│ ├── ui/
│ │ ├── package.json
│ │ └── src/
│ ├── config/
│ │ └── package.json
│ └── tsconfig/
│ └── package.json
├── turbo.json
├── pnpm-workspace.yaml
└── package.json
3. turbo.json 설정
{
"$schema": "https://turbo.build/schema.json",
"globalDependencies": [**/.env.*local],
"pipeline": {
"build": {
"dependsOn": [^build],
"outputs": [".next/**", "dist/**"],
"env": [NEXT_PUBLIC_API_URL]
},
"dev": {
"cache": false,
"persistent": true
},
"test": {
"dependsOn": [build],
"outputs": [coverage/**]
},
"lint": {
"outputs": []
},
"type-check": {
"dependsOn": [^build],
"outputs": []
}
}
}
4. 공유 패키지
UI 패키지
// packages/ui/src/Button.tsx
export function Button({ children, onClick }: ButtonProps) {
return (
<button onClick={onClick} className="btn">
{children}
</button>
);
}
// packages/ui/package.json
{
"name": "ui",
"main": "./src/index.tsx",
"types": "./src/index.tsx",
"scripts": {
"lint": "eslint .",
"type-check": "tsc --noEmit"
}
}
Config 패키지
// packages/config/eslint-preset.js
module.exports = {
extends: ['next', 'turbo', 'prettier'],
rules: {
'@next/next/no-html-link-for-pages': 'off',
},
};
5. 실행 명령어
개발
# 모든 앱 실행
pnpm dev
# 특정 앱만 실행
pnpm --filter web dev
빌드
# 모든 앱 빌드
pnpm build
# 특정 앱과 의존성 빌드
pnpm --filter web... build
테스트
# 모든 패키지 테스트
pnpm test
# 변경된 패키지만 테스트
pnpm test --filter ...[HEAD^]
6. Remote Cache
Vercel Remote Cache
# 로그인
npx turbo login
# 링크
npx turbo link
사용
# 자동으로 remote cache 사용
pnpm build
효과
- 팀 간 캐시 공유
- CI/CD 속도 향상
- 로컬 빌드 속도 향상
7. CI/CD 최적화
GitHub Actions
# .github/workflows/ci.yml
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v3
with:
node-version: 20
cache: 'pnpm'
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm turbo build
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
- name: Test
run: pnpm turbo test
8. 실전 팁
1. 의존성 그래프 확인
pnpm turbo run build --graph
2. 캐시 무효화
pnpm turbo run build --force
3. 로그 상세화
pnpm turbo run build --verbose
4. 병렬 실행 제한
{
"pipeline": {
"build": {
"dependsOn": [^build],
"outputs": [.next/**]
}
},
"globalEnv": [NODE_ENV],
"globalPassThroughEnv": [CI]
}
9. 해시·캐시 키·원격 캐시 내부 모델
Turborepo는 각 태스크에 대해 입력 해시를 계산합니다. 소스 파일, 의존 패키지 버전, 환경 변수(env, globalEnv), 때로는 lockfile까지 포함됩니다. 따라서 “CI에서만 캐시가 안 맞는다”는 문제는 대개 TURBO_CI 외의 숨은 env나 절대 경로가 아티팩트에 박힌 경우가 많습니다.
원격 캐시는 팀원·CI가 동일 해시를 재사용하게 해 주지만, 비밀이 출력물에 섞이면 그 출력을 누군가의 캐시에서 가져오는 순간 유출될 수 있습니다. 따라서 outputs에 .env나 토큰이 포함된 빌드 산출물을 넣지 않도록 파이프라인을 점검합니다.
프로덕션 패턴
dependsOn: ["^build"]: 의존 패키지가 먼저 빌드되도록 그래프를 명시합니다.inputs/outputs정밀화: 불필요한 파일이 해시에 들어가면 캐시 적중률이 떨어집니다.- 필터 실행:
turbo run test --filter=...[origin/main]처럼 변경 패키지만 검증합니다.
10. 트러블슈팅
| 증상 | 흔한 원인 | 대응 |
|---|---|---|
| 로컬은 캐시 히트, CI는 미스 | env·Node 버전 불일치 | engines, globalEnv 명시 |
| 잘못된 산출물 재사용 | outputs 범위가 넓음 | 산출 디렉터리 분리 |
| 순환 의존 | workspace 패키지 간 상호 참조 | 패키지 경계 리팩터 |
정리 및 체크리스트
핵심 요약
- Turborepo: 고성능 Monorepo 빌드
- 병렬 실행: 빠른 빌드
- 스마트 캐싱: 변경된 것만
- Remote Cache: 팀 간 공유
- pnpm: 완벽한 통합
- 간단한 설정: 최소한의 설정
구현 체크리스트
- Turborepo 설치
- 프로젝트 구조 설정
- turbo.json 작성
- 공유 패키지 생성
- Remote Cache 설정
- CI/CD 통합
- 성능 최적화
같이 보면 좋은 글
- pnpm 완벽 가이드
- Docker Compose 완벽 가이드
- Monorepo 아키텍처 가이드
이 글에서 다루는 키워드
Turborepo, Monorepo, Build, Cache, pnpm, Performance, DevOps
자주 묻는 질문 (FAQ)
Q. Lerna와 비교하면 어떤가요?
A. Turborepo가 훨씬 빠르고 간단합니다. Lerna는 더 많은 기능을 제공하지만 복잡합니다.
Q. Nx와 비교하면 어떤가요?
A. Turborepo가 더 간단합니다. Nx는 더 많은 기능과 플러그인을 제공합니다.
Q. 무료로 사용할 수 있나요?
A. 네, 오픈소스입니다. Remote Cache는 Vercel 계정이 필요하지만 무료 플랜이 있습니다.
Q. 프로덕션에서 사용해도 되나요?
A. 네, Vercel, Netflix 등 많은 기업에서 사용합니다.