테마
레포지토리 전략 비교: 싱글 레포 vs 멀티 레포 vs 모노레포
프로젝트 규모와 팀 구조에 따라 선택해야 하는 세 가지 레포지토리 전략의 개념, 장단점, 그리고 마이크로프론트엔드에서 모노레포가 선호되는 이유를 정리한다.
학습 목표
- 싱글 레포지토리의 정의와 적합한 사용 사례를 이해한다.
- 멀티 레포지토리(폴리 레포)의 구조와 한계를 파악한다.
- 모노레포지토리의 핵심 정의인 "잘 정의된 관계"를 이해한다.
- 세 전략의 장단점을 비교하고, 마이크로프론트엔드에서 모노레포가 갖는 이점을 설명할 수 있다.
본문
1. 싱글 레포지토리 (Single Repository)
싱글 레포지토리는 하나의 Git 저장소에 하나의 프로젝트가 있는 가장 기본적인 형태다. 프로젝트 안에는 소스 코드, 정적 에셋, 그리고 package.json으로 대표되는 프로젝트 설정이 들어 있다.
싱글 레포의 핵심 특징은 다음과 같다.
- 레포지토리가 하나이며, 외부 라이브러리(npm 패키지)를 제외하면 어떤 연관 관계도 없이 자체적으로 완결된다.
- 주로 모놀리식(Monolithic) 앱이거나 범용적인 독립 라이브러리일 때 사용한다.
- 프로젝트 규모가 작고 팀이 하나의 결과물만 만들 때 가장 자연스러운 선택이다.
최근에는 범용 라이브러리도 내부적으로 여러 패키지를 나누어 모노레포로 관리하는 경우가 늘고 있지만, 단독으로 동작하는 앱이나 소규모 라이브러리라면 싱글 레포가 여전히 적합하다.
2. 멀티 레포지토리 (Multi Repository / Poly Repository)
프로젝트 규모가 커지면 공통 코드를 여러 앱에서 공유해야 하는 상황이 발생한다. 이때 각 프로젝트를 별도의 Git 저장소로 분리하여 관리하는 방식이 멀티 레포지토리다.
멀티 레포의 핵심은 단순히 여러 레포를 갖는 것이 아니라, 프로젝트들이 유기적으로 함께 개발되면서 서로 의존 관계를 갖는다는 점이다. 각각이 독립적인 외부 라이브러리를 만드는 것과는 본질적으로 다르다.
멀티 레포의 주요 단점
| 문제 영역 | 설명 |
|---|---|
| 라이브러리 수정 번거로움 | 앱에서 버그를 발견했는데 원인이 라이브러리에 있다면, 라이브러리 레포를 열고 수정 -> 퍼블리시 -> 앱에서 새 버전 설치라는 긴 흐름을 거쳐야 한다. |
| 이슈 단위 커밋 어려움 | 하나의 이슈가 여러 레포에 걸쳐 수정되면 커밋이 분산되어 변경 이력을 한눈에 파악하기 어렵다. |
| 코드 재사용 비용 | 기존 코드를 다른 프로젝트에서 활용하려면 별도 레포 생성, CI/CD 설정, 퍼블리시 파이프라인 구축 등 추가 비용이 크다. |
| 프로젝트 생성 비용 | 새 레포를 만들 때마다 CI/CD, 린터, 테스트, 스토리북 등 모든 설정을 처음부터 해야 한다. |
| 컨텍스트 스위칭 | 프로젝트마다 설정이 달라 개발자 경험(DX)이 일관적이지 않고, 오래 방치된 레포는 맥락이 끊긴다. |
3. 모노레포지토리 (Mono Repository)
모노레포는 하나의 Git 저장소 안에 여러 프로젝트(워크스페이스)를 포함하되, 이들이 **잘 정의된 관계(well-defined relationships)**를 갖는 구조다.
모노레포의 공식 정의 (monorepo.tools) "A monorepo is a single repository containing multiple distinct projects, with well-defined relationships."
단순히 하나의 레포에 여러 프로젝트를 넣는 것만으로는 모노레포가 아니다. 패키지 간 의존 관계가 명확하게 정의되고, 유기적으로 함께 개발될 때 비로소 모노레포라 부를 수 있다.
모노레포 vs 멀티레포: 핵심 비교
모노레포와 멀티레포의 본질적인 공통점은 모듈로 나누어 연관 짓는다는 개념이다. 차이는 이 모듈들을 하나의 레포에서 관리하느냐(모노레포), 각각의 레포에서 관리하느냐(멀티레포)에 있다.
| 비교 항목 | 싱글 레포 | 멀티 레포 | 모노레포 |
|---|---|---|---|
| 레포 개수 | 1개 | 여러 개 | 1개 |
| 프로젝트 수 | 1개 | 여러 개 (각 레포에 1개) | 여러 개 (워크스페이스) |
| 패키지 간 관계 | 없음 | npm 퍼블리시를 통한 연결 | 내부 의존성으로 직접 연결 |
| 라이브러리 수정 | 해당 없음 | 레포 전환 + 퍼블리시 + 버전 갱신 | 동일 레포에서 바로 수정 |
| 이슈 기반 커밋 | 단일 커밋 | 여러 레포에 분산 커밋 | 하나의 커밋으로 통합 가능 |
| 프로젝트 생성 비용 | 해당 없음 | 높음 (전체 설정 반복) | 낮음 (기존 설정 재사용) |
| 설정 일관성 | 단일 프로젝트 | 프로젝트마다 상이 | 전체 일관된 DX |
| 저장소 크기 | 작음 | 각각 작음 | 커질 수 있음 |
| CI/CD 복잡도 | 단순 | 레포별 독립 (비교적 단순) | 복잡하지만 통합 관리 가능 |
| 대표 사용 사례 | 소규모 앱, 범용 라이브러리 | 독립적 팀 운영 | Google, Meta, 대규모 프론트엔드 |
4. 마이크로프론트엔드에서 모노레포가 선호되는 이유
마이크로프론트엔드는 본질적으로 여러 개의 마이크로 앱이 잘 정의된 관계를 가지며 하나의 서비스를 구성하는 아키텍처다. 이 특성이 모노레포의 정의와 정확히 일치한다.
배포 범위 결정에 의존 그래프 필수
모노레포에서는 패키지 간 의존 관계가 명확하므로, 특정 라이브러리가 변경되었을 때 영향을 받는 마이크로 앱을 자동으로 감지하여 배포 범위를 결정할 수 있다.
예를 들어 라이브러리 3이 수정되면:
라이브러리 3을 직접 사용하는앱 2가 영향을 받는다.라이브러리 3을 사용하는라이브러리 2도 영향을 받는다.라이브러리 2를 사용하는앱 1도 연쇄적으로 영향을 받는다.- 따라서
앱 1과앱 2모두 재배포가 필요하다.
이런 영향 범위 분석은 모노레포 빌드 도구(Nx, Turborepo 등)가 자동으로 수행해 주며, 멀티레포에서는 수동으로 추적해야 한다.
모노레포가 마이크로프론트엔드에 주는 이점
| 이점 | 설명 |
|---|---|
| 공통 코드 즉시 공유 | UI 컴포넌트, 유틸리티, 타입 정의 등을 별도 퍼블리시 없이 내부 패키지로 바로 참조 |
| 이슈 단위 통합 커밋 | 하나의 버그 수정이 여러 마이크로 앱에 걸쳐도 단일 커밋으로 관리 |
| 일관된 개발자 경험 | 린터, 테스트, 빌드 설정을 전체에 통일하여 컨텍스트 스위칭 비용 최소화 |
| 변경 영향 자동 감지 | 빌드 도구가 의존 그래프를 분석해 영향받는 앱만 선택적으로 빌드/배포 |
| 프로젝트 추가 비용 절감 | 새 마이크로 앱을 워크스페이스로 추가하면 기존 CI/CD, 설정을 그대로 활용 |
주의해야 할 단점
물론 모노레포가 만능은 아니다. 다음 사항에 유의해야 한다.
- 과도한 의존 관계: 연결이 쉬운 만큼 불필요한 의존이 생기지 않도록 코드 리뷰로 관리해야 한다.
- CI 복잡도: 하나의 CI로 여러 앱을 빌드하므로 파이프라인 설계가 복잡해질 수 있다.
- 저장소 크기 증가: 프로젝트가 늘어나면 저장소가 무거워지므로 캐싱과 변경 감지 도구를 적극 활용해야 한다.
- 추가 학습 곡선: 패키지 매니저의 워크스페이스 기능과 빌드 시스템 도구(Nx, Turborepo 등)를 학습해야 한다.
핵심 정리
- 싱글 레포: 하나의 프로젝트 = 하나의 레포. 단독 앱이나 범용 라이브러리에 적합하다.
- 멀티 레포(폴리 레포): 유기적 관계를 가진 여러 프로젝트를 각각 별도 레포로 관리. 코드 공유, 이슈 추적, 프로젝트 생성 비용이 높다.
- 모노레포: 잘 정의된 관계를 가진 여러 프로젝트를 하나의 레포에서 관리. Google, Meta 등 대기업에서 채택한 전략이다.
- 모노레포와 멀티레포의 공통 본질은 "모듈로 나누어 연관 짓는다"는 것이며, 관리 방식(단일 레포 vs 다중 레포)만 다르다.
- 마이크로프론트엔드는 여러 앱이 유기적으로 구성되므로 모노레포의 장점(통합 커밋, 코드 공유, 변경 감지, 일관된 DX)이 극대화된다.
다음 단계
모노레포의 전략적 이점을 이해했으므로, 다음으로 모노레포의 구체적인 특성과 내부 구조(루트 프로젝트, 워크스페이스, 빌드 시스템 도구의 역할)를 살펴본다.
다음: 02-모노레포-특성과-구조.md | 패키지 매니저로 이동: ../04-패키지-매니저/01-프론트엔드-프로젝트-구조.md