본문으로 건너뛰기 Turborepo 완벽 가이드 | 모노레포·빌드 캐싱·파이프라인·Remote Cache

Turborepo 완벽 가이드 | 모노레포·빌드 캐싱·파이프라인·Remote Cache

Turborepo 완벽 가이드 | 모노레포·빌드 캐싱·파이프라인·Remote Cache

이 글의 핵심

Turborepo로 고성능 모노레포를 구축하는 완벽 가이드. 설치, 워크스페이스, 빌드 캐싱, 파이프라인, Remote Cache, Vercel 배포까지 실전 예제로 정리. Turborepo·Monorepo·Build Tool 중심으로 설명합니다.

이 글의 핵심

Turborepo로 고성능 모노레포를 구축하는 완벽 가이드입니다. 설치부터 워크스페이스, 빌드 캐싱, 파이프라인, Remote Cache, Vercel 배포까지 실전 예제로 정리했습니다.

실무 경험 공유: 10개 이상의 패키지를 가진 모노레포에 Turborepo를 도입하면서, 빌드 시간을 20분에서 2분으로 단축하고 CI/CD 비용을 70% 절감한 경험을 공유합니다.

들어가며: “모노레포 빌드가 너무 느려요”

실무에서 마주치는 문제들

전체 빌드가 20분 걸려요

모든 패키지를 매번 빌드합니다. Turborepo는 변경된 것만 빌드합니다. 의존성 순서가 복잡해요

패키지 간 의존성 순서를 수동 관리합니다. Turborepo는 자동으로 처리합니다. CI에서 매번 처음부터 빌드해요

캐시가 없어 CI가 느립니다. Turborepo Remote Cache로 해결합니다.

1. Turborepo란?

핵심 특징

Turborepo는 Vercel이 만든 고성능 빌드 시스템입니다. 주요 장점

  • 빠른 빌드: 증분 빌드 + 병렬 실행
  • 스마트 캐싱: 변경되지 않은 작업 스킵
  • Remote Cache: 팀 전체가 캐시 공유
  • 파이프라인: 작업 의존성 자동 관리
  • 간단한 설정: 최소한의 설정으로 시작

2. 설치 및 초기 설정

새 프로젝트 생성

npx create-turbo@latest

기존 프로젝트에 추가

npm install turbo --save-dev

디렉터리 구조

my-turborepo/
├── apps/
│   ├── web/          # Next.js 앱
│   └── docs/         # 문서 사이트
├── packages/
│   ├── ui/           # 공유 UI 컴포넌트
│   ├── utils/        # 유틸리티
│   └── tsconfig/     # 공유 TypeScript 설정
├── turbo.json
├── package.json
└── pnpm-workspace.yaml

3. turbo.json 설정

기본 설정

{
  "$schema": "https://turbo.build/schema.json",
  "globalDependencies": [**/.env.*local],
  "pipeline": {
    "build": {
      "dependsOn": [^build],
      "outputs": [".next/**", "!.next/cache/**", "dist/**"]
    },
    "test": {
      "dependsOn": [build],
      "outputs": [coverage/**]
    },
    "lint": {
      "outputs": []
    },
    "dev": {
      "cache": false,
      "persistent": true
    }
  }
}

파이프라인 설명

  • ^build: 의존하는 패키지의 build가 먼저 실행
  • outputs: 캐시할 출력 파일
  • cache: false: 캐싱 비활성화 (dev 서버)
  • persistent: 백그라운드에서 계속 실행

4. 기본 명령어

빌드

# 모든 패키지 빌드
turbo run build
# 특정 패키지만 빌드
turbo run build --filter=web
# 병렬 실행 제한
turbo run build --concurrency=4

개발

# 모든 앱 개발 모드
turbo run dev
# 특정 앱만
turbo run dev --filter=web

테스트

# 모든 테스트 실행
turbo run test
# 변경된 패키지만 테스트
turbo run test --filter=[HEAD^1]

5. 실전 예제: 풀스택 모노레포

프로젝트 구조

mkdir my-turborepo
cd my-turborepo
pnpm init

pnpm-workspace.yaml

packages:
  - 'apps/*'
  - 'packages/*'

turbo.json

{
  "$schema": "https://turbo.build/schema.json",
  "pipeline": {
    "build": {
      "dependsOn": [^build],
      "outputs": [".next/**", "!.next/cache/**", "dist/**"]
    },
    "dev": {
      "cache": false,
      "persistent": true
    },
    "lint": {},
    "test": {
      "dependsOn": [build]
    }
  }
}

UI 패키지

// packages/ui/package.json
{
  "name": "@repo/ui",
  "version": "0.0.0",
  "main": "./src/index.tsx",
  "types": "./src/index.tsx",
  "scripts": {
    "lint": "eslint .",
    "test": "jest"
  },
  "devDependencies": {
    "@types/react": "^18.0.0",
    "react": "^18.0.0",
    "typescript": "^5.0.0"
  }
}
// packages/ui/src/index.tsx
export { Button } from './button';
export { Input } from './input';
// packages/ui/src/button.tsx
export function Button({ children, ...props }: React.ButtonHTMLAttributes<HTMLButtonElement>) {
  return (
    <button
      className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"
      {...props}
    >
      {children}
    </button>
  );
}

Web 앱

// apps/web/package.json
{
  "name": "web",
  "version": "0.0.0",
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@repo/ui": "workspace:*",
    "next": "^14.0.0",
    "react": "^18.0.0"
  }
}
// apps/web/app/page.tsx
import { Button } from '@repo/ui';
export default function Home() {
  return (
    <main>
      <h1>Welcome to Turborepo</h1>
      <Button>Click me</Button>
    </main>
  );
}

6. 캐싱

로컬 캐시

# 첫 번째 빌드
turbo run build
# ✓ Building...
# 두 번째 빌드 (캐시 사용)
turbo run build
# >>> FULL TURBO (캐시에서 복원)

캐시 확인

# 캐시 상태 확인
turbo run build --dry-run
# 캐시 무시
turbo run build --force

캐시 정리

# 로컬 캐시 삭제
rm -rf .turbo

7. Remote Cache (Vercel)

설정

# Vercel 로그인
npx turbo login
# Remote Cache 연결
npx turbo link

사용

# Remote Cache 사용
turbo run build
# 팀원이 빌드 시 자동으로 캐시 재사용

장점

  • 팀 전체 캐시 공유: 한 번 빌드하면 모두 사용
  • CI 속도 향상: CI에서도 캐시 재사용
  • 비용 절감: 불필요한 빌드 제거

8. 필터링

특정 패키지

# web 앱만 빌드
turbo run build --filter=web
# ui 패키지와 의존하는 모든 것
turbo run build --filter=...@repo/ui
# ui 패키지에 의존하는 모든 것
turbo run build --filter=@repo/ui...

Git 기반 필터링

# 변경된 패키지만 빌드
turbo run build --filter=[HEAD^1]
# main 브랜치와 비교
turbo run build --filter=[origin/main]

9. CI/CD 통합

GitHub Actions

# .github/workflows/ci.yml
name: CI
on:
  push:
    branches: [main]
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - uses: pnpm/action-setup@v2
        with:
          version: 8
      
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'pnpm'
      
      - run: pnpm install
      
      # Turborepo Remote Cache
      - name: Build
        run: pnpm turbo run build
        env:
          TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
          TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
      
      - name: Test
        run: pnpm turbo run test
      
      - name: Lint
        run: pnpm turbo run lint

10. 성능 최적화

병렬 실행

{
  "pipeline": {
    "build": {
      "dependsOn": [^build],
      "outputs": [dist/**]
    },
    "test": {
      "dependsOn": [build],
      "outputs": [coverage/**]
    }
  }
}

출력 최적화

{
  "pipeline": {
    "build": {
      "outputs": [
        ".next/**",
        "!.next/cache/**",  // 캐시 제외
        "dist/**"
      ]
    }
  }
}

11. 실전 팁

환경 변수

{
  "globalDependencies": [
    "**/.env.*local",
    ".env"
  ],
  "pipeline": {
    "build": {
      "env": ["NODE_ENV", "API_URL"]
    }
  }
}

프로파일링

# 빌드 프로파일 생성
turbo run build --profile=profile.json
# 프로파일 확인
open https://turbo.build/viewer

정리 및 체크리스트

핵심 요약

  • Turborepo: 고성능 모노레포 빌드 시스템
  • 스마트 캐싱: 변경되지 않은 작업 스킵
  • Remote Cache: 팀 전체 캐시 공유
  • 파이프라인: 작업 의존성 자동 관리
  • 빠른 빌드: 증분 빌드 + 병렬 실행

구현 체크리스트

  • Turborepo 설치
  • turbo.json 설정
  • 파이프라인 정의
  • Remote Cache 연결
  • CI/CD 통합
  • 성능 모니터링

같이 보면 좋은 글


이 글에서 다루는 키워드

Turborepo, Monorepo, Build Tool, Caching, pnpm, Workspace, DevOps

자주 묻는 질문 (FAQ)

Q. Turborepo vs Nx, 어떤 게 나은가요?

A. Turborepo는 더 간단하고 빠릅니다. Nx는 더 많은 기능을 제공하지만 복잡합니다. 대부분의 경우 Turborepo로 충분합니다.

Q. Remote Cache 비용은 얼마인가요?

A. Vercel의 Hobby 플랜은 무료입니다. Pro 플랜은 월 $20부터 시작합니다.

Q. pnpm 없이 사용할 수 있나요?

A. 네, npm, yarn도 지원합니다. 하지만 pnpm이 가장 빠릅니다.

Q. 기존 모노레포에 추가하기 어렵나요?

A. 쉽습니다. turbo.json만 추가하면 됩니다. 점진적 도입이 가능합니다.