Why NextWhy Next
목록으로
💻 개발1분 읽기

앱 5개를 한 저장소에서 - 1인 개발자의 Turborepo 모노레포

여러 앱과 웹을 하나의 저장소에서 관리하는 Turborepo 모노레포 구성법. 공용 설정 공유, 캐시로 빌드 아끼기, 앱별 배포까지 실전 관점으로 정리했습니다.

핵심 요약

혼자 앱을 여러 개 만들면 설정이 흩어진다. Turborepo 모노레포로 eslint·tsconfig 를 packages 로 공유하고, turbo 캐시로 안 바뀐 앱은 다시 빌드하지 않으며, --filter 로 앱별로 배포한다.

목차

혼자 앱을 만들다 보면 저장소가 우수수 늘어납니다. 앱 하나, 웹 하나, 또 앱 하나… 그리고 eslint 설정을 다섯 번 복붙하게 되죠. 저는 이걸 하나의 모노레포로 합쳤습니다.

흩어진 설정이 진짜 문제다

저장소가 많을 때 가장 아픈 건 코드가 아니라 설정입니다.

  • eslint·prettier·tsconfig 를 저장소마다 복사
  • 규칙 하나 바꾸면 전부 순회하며 수정
  • 공용 UI·유틸을 npm 에 올리기엔 너무 사소함

모노레포는 이걸 한 곳에서 공유하는 방식으로 바꿉니다.

기본 구조

apps/
├── web/      # 랜딩
├── blog/     # 이 블로그
├── wave/     # 오늘의 파도
└── ...
packages/
├── eslint-config/       # 공용 eslint
└── typescript-config/   # 공용 tsconfig

apps/* 는 실제 배포물, packages/* 는 앱들이 공유하는 설정·코드입니다. 각 앱의 tsconfig.json 은 이렇게 상속만 받습니다.

{ "extends": "@repo/typescript-config/nextjs.json" }

이제 규칙은 packages 한 곳에서만 고칩니다.

turbo 캐시가 핵심

Turborepo 의 진짜 무기는 캐시입니다. 각 작업의 입력(소스·설정)이 안 바뀌면 이전 결과를 그대로 재사용해요.

turbo run build            # 전체 빌드(바뀐 것만 실제로 돎)
turbo run build --filter=blog   # blog 앱만

turbo.json 에 작업 간 의존과 출력만 선언하면 됩니다.

{
  "tasks": {
    "build": { "dependsOn": ["^build"], "outputs": [".next/**"] }
  }
}

두 번째 빌드부터는 "FULL TURBO" 로 몇 초 만에 끝납니다.

앱별로 배포하기

한 저장소여도 배포는 앱별로 분리됩니다. 도커라면 turbo prune 으로 해당 앱 서브트리만 잘라내 이미지를 가볍게 만들 수 있어요.

turbo prune blog --docker   # blog + 내부 의존성만 남긴 out/ 생성

이 블로그도 이렇게 잘라서 미니 PC 에 도커로 올렸습니다. 그 이야기는 셀프 호스팅 글에서 다룹니다.

정리

  • apps/* = 배포물, packages/* = 공유 설정
  • tsconfig·eslint 는 상속으로 한 곳에서 관리
  • turbo 캐시로 안 바뀐 앱은 다시 안 빌드
  • --filter·prune 으로 앱별 배포

혼자서 여러 제품을 굴린다면, 모노레포는 사치가 아니라 생존 도구입니다.

자주 묻는 질문

앱이 몇 개부터 모노레포가 이득인가요?

2개만 넘어가도 공용 설정(eslint·tsconfig·UI)이 생기면 이득입니다. 설정을 한 곳에서 고치고 모든 앱에 반영되는 게 핵심입니다.

빌드가 느려지지 않나요?

오히려 빨라집니다. turbo 는 입력이 안 바뀐 작업의 결과를 캐시해서, 바뀐 앱만 다시 빌드합니다.

관련 글