모노레포에 대해 알아보자!

2025년 03월 14일

안녕하세요, 웹 프론트엔드 개발자 Garden, 오소현입니다.

최근에 친한 개발자분들과 함께 시나브로 자바스크립트 강의 스터디를 진행하게 되었어요 :)
저희의 스터디 레포는 아래와 같아요!

https://github.com/The-survivor-is-strong/sinabro-js

이번 주차에는 5주차 강의를 들으면서 모노레포 개념과 적용했던 내용에 대해 한번 더 공부하고 정리해보았습니댱

1. 모노레포의 등장 배경 🏗️

💡 모노레포란?
모노레포(Monorepo)는 버전 관리 시스템에서 두 개 이상의 프로젝트 코드가 동일한 저장소에 저장되는 소프트웨어 개발 전략이에요!

초창기 서비스의 시작, 모놀리식 구조 🏗️

모노레포는 고전적 소프트웨어 개발 방식인 모놀리식 애플리케이션(monolithic application)의 한계에 대한 대안으로 등장했어요. 모놀리식 애플리케이션이란 모듈화 없이 설계된 소프트웨어 애플리케이션을 의미한답니다.

대부분의 초창기 프로젝트들은 모놀리식 시스템으로 서비스를 구현해요. 프로젝트의 크기가 크지 않고, 개발자의 수도 적기 때문에 모든 것을 한 곳에서 처리하는 것이 효율적이거든요! 이 경우 시스템 자체가 분리되지 않고 하나이기 때문에 레포지토리 역시 하나로 관리하게 돼요.

프로젝트 거대화에 따른 마이크로 서비스 구성 🌱🌳

프로젝트가 커짐에 따라 모듈화되지 않은 소스 코드로 구성된 하나의 프로젝트는 여러 문제점을 야기해요. 코드가 서로 직접적으로 의존하며 단 하나의 버전으로 관리되면서 설계, 리팩토링, 배포 등의 작업을 매번 거대한 단위로 처리해야 하므로 개발상 많은 제약과 비효율이 따르게 된답니다 😅

이를 해결하기 위해 개발 조직은 시스템의 각 부분을 도메인별로 분리해서 마이크로 서비스로 구성하기 시작해요. 이때, 개발 조직은 분리된 각 서비스를 하나의 레포지토리에서 관리할지, 각자 다른 레포지토리에서 관리할지 고민하게 되죠!

멀티레포 vs 모노레포 🤔

각각의 개념은 간단해요:

  • 멀티레포(Multirepo): 시스템의 각 모듈을 나눠서 관리해요
  • 모노레포(Monorepo): 모든 모듈을 하나의 저장소에서 관리해요

멀티레포는 분리된 모듈을 고유한 저장소가 있는 독자적인 프로젝트로 관리해요. 그렇기 때문에, 각 프로젝트는 자율성이 높으며 독립적인 개발, 린트, 테스트, 빌드, 게시, 배포 파이프라인이 존재한답니다.

멀티레포 방식에서는 소스코드를 모듈화한 뒤 각 모듈에 독자적인 영역을 부여하고, 버전 관리를 통해 관심사를 분리해서 기능 변경이 다른 레포지토리에 직접 영향을 미치지 않도록 개선했어요. 하지만 각 모듈이 서로 독립된 영역에 존재하기 때문에 코드 단계에서의 재사용이 어려워졌고, 빌드와 배포 과정이 복잡해졌어요. 또한, 프로젝트를 매번 생성하는 것이므로 패키지의 중복 코드가 증가하며, 자연스럽게 관리 포인트가 늘어나게 된답니다 😱

모노레포는 모놀리식 레포지토리와 멀티레포의 장점을 모두 취하고자 등장했어요! 모노레포는 두 개 이상의 프로젝트를 동일한 저장소에 저장해요. 분리된 모듈들은 모노레포에서 여전히 독자적인 프로젝트로 존재하지만, 저장소는 같은 곳을 사용한답니다.

2. 모노레포가 해결하는 문제 🛠️

모노레포는 프로젝트 간의 관계를 효율적으로 관리해주는 도구라고 할 수 있어요. 모노레포가 해결하는 멀티레포의 문제는 다음과 같답니다:

1. 쉬운 프로젝트 생성

멀티레포에서 공유 패키지를 만들 때 다음과 같은 과정을 거쳐요:

저장소 생성 > 커미터 추가 > 개발환경 구축 > CI/CD 구축 > 빌드 > 패키지 저장소에 publish

하지만 모노레포에서는 저장소 생성 및 커미터 추가 과정이 필요 없어요! 개발환경, CI/CD 구축, 빌드 게시 등의 과정은 기존 DevOps를 이용해요. 따라서 새로운 프로젝트 생성에 대한 오버헤드가 없답니다.

2. 더 쉬운 의존성 관리 🧩

전체 서비스의 의존 관계를 한 레포지토리에서 확인 및 설정할 수 있기에 더욱 쉽게 의존성 관리를 할 수 있어요. 이는 특히 여러 프로젝트가 공통 라이브러리를 사용할 때 매우 유용하답니다!

3. 단일화된 관리 포인트 🎯

개발환경 및 DevOps에 대한 업데이트를 한 번에 반영할 수 있어요! 이는 일관된 개발 환경을 유지하는 데 큰 도움이 된답니다.

4. 일관된 개발자 경험 제공 🧑‍💻

애플리케이션을 일관되게 구축하고 테스트할 수 있어요. 개발자는 다른 팀의 애플리케이션에 자신 있게 기여하고, 변경 사항이 안전한지 확인할 수 있답니다.

5. 프로젝트들에 걸친 원자적 커밋 ⚛️

커밋할 때마다 모든 것이 함께 작동해요! 따라서 변경 사항의 영향을 받는 조직에서 쉽게 변화를 확인할 수 있어요. 이는 여러 프로젝트에 걸친 변경 사항을 추적하는 데 매우 유용하답니다.

6. 서로 의존하는 저장소들의 리팩토링 비용 감소 💰

모노레포는 대규모 변경을 훨씬 더 간단하게 만들어요! 100개의 라이브러리로 만든 10개의 앱을 리팩토링하고 변경을 커밋하기 전에 모두 작동하는지 확인할 수 있답니다.

7. 테스트 및 빌드 범위 최소화 🚀

소스 변경 시 모든 프로젝트를 다시 빌드하거나 다시 테스트하지 않아요. 대신 변경 사항의 영향을 받는 프로젝트만 다시 테스트하고 빌드해요! 이는 CI/CD 파이프라인의 효율성을 크게 향상시킨답니다.

모노레포 사용이 적합한 상황 🌟

다음과 같은 상황일 때 모노레포를 사용하는 것이 좋아요:

  • 유사한 제품의 집합을 관리할 때
  • 여러 프로젝트의 변화를 한눈에 파악해야 할 때
  • 호스트 애플리케이션을 플러그인 등으로 확장할 때
  • 공통 기능을 재사용하는 관련된 프로젝트의 집합을 관리할 때
  • 유사한 DevOps로 구성된 프로젝트의 집합을 관리할 때
  • 팀 간 협업이 빈번하게 이루어지는 환경에서

3. 모노레포는 어떻게 사용되고 있는가? 🌍

현재 다양한 기업에서 모노레포 전략을 사용하여 프로젝트를 운영하고 있어요. Google, Facebook, Microsoft, Uber, Airbnb, Twitter와 같은 글로벌 기업부터 라인, 배달의민족, 토스, 콴다, 화해, 마이리얼트립 등 국내 다양한 기업에서도 모노레포를 도입 및 변경을 시도하고 있답니다!

대체적인 후기들을 종합해보면 다음과 같은 장점들을 꼽을 수 있어요:

  • 코드의 일관성: eslint, prettier, typescript 환경 통일로 모든 팀에서 일관되게 사용 가능해요! 😊
  • 코드 리뷰 향상: 각 프로젝트의 작업 사항을 하나의 레포에서 관리하므로 적극적으로 코드 리뷰에 임할 수 있어요
  • 모든 웹 프로젝트의 최신화 상태 유지: 오래 건드리지 않았던 프로젝트들도 함께 관리할 수 있는 환경 구성이 가능해요
  • 지속적인 소스의 무결성 보장: 레포지토리는 항상 모든 서비스가 연동된 올바른 상태를 유지해요
  • 의존성 그래프 시각화: 전체 코드가 트리 구조로 명확히 보여요! 🌳
  • 여러 프로젝트 팀 간의 쉬운 협업: 하나의 레포지토리에서 함께 작업하며, 여러 서비스에 손쉽게 접근 가능해요

모노레포의 단점과 해결 방법 🤔

모노레포에도 몇 가지 단점이 있어요:

  • 저장소 크기 증가: 모든 프로젝트가 하나의 저장소에 있기 때문에 저장소 크기가 커질 수 있어요. 이는 Git의 sparse-checkout 기능이나 부분 클론 기능을 활용하여 해결할 수 있답니다!
  • 권한 관리의 복잡성: 여러 팀이 하나의 저장소를 사용하므로 권한 관리가 복잡해질 수 있어요. 이는 CODEOWNERS 파일이나 세분화된 권한 관리 도구를 사용하여 해결할 수 있어요.
  • 빌드 시간 증가: 모든 프로젝트를 빌드하면 시간이 오래 걸릴 수 있어요. 이는 증분 빌드 도구나 영향을 받는 프로젝트만 빌드하는 방식으로 해결할 수 있답니다! 🚀

4. 모노레포 도구들 🧰

yarn berry와 모노레포의 상관관계

결론부터 말씀드리면, yarn berry는 모노레포를 구축하기 위한 "도구" 중 하나에요! Yarn Berry(Yarn 2.0 이상)는 workspaces 기능을 통해 모노레포를 효과적으로 관리할 수 있게 해준답니다.

주요 모노레포 도구들 🛠️

다양한 도구를 이용해서 모노레포를 구축할 수 있어요:

  • Lerna: JavaScript 프로젝트를 위한 가장 오래된 모노레포 도구 중 하나로, 여러 패키지의 버전 관리와 배포를 자동화해요.
  • Yarn Workspaces: Yarn의 내장 기능으로, 여러 패키지를 하나의 저장소에서 관리할 수 있게 해줘요!
  • npm Workspaces: npm 7부터 지원하는 기능으로, Yarn Workspaces와 유사한 기능을 제공해요.
  • pnpm Workspaces: 디스크 공간을 효율적으로 사용하는 패키지 관리자인 pnpm의 모노레포 지원 기능이에요.
  • Nx: 모노레포를 위한 빌드 시스템으로, 특히 Angular 프로젝트에 최적화되어 있어요.
  • Turborepo: 빠른 증분 빌드를 지원하는 JavaScript/TypeScript 모노레포 빌드 시스템이에요! 🚀
  • Rush: Microsoft에서 개발한 모노레포 관리 도구로, 대규모 프로젝트에 적합해요.

도구 선택 기준 🤓

모노레포 도구를 선택할 때 고려해야 할 사항들이 있어요:

  • 프로젝트 규모: 소규모 프로젝트는 Yarn/npm Workspaces만으로도 충분할 수 있지만, 대규모 프로젝트는 Nx나 Turborepo와 같은 더 강력한 도구가 필요할 수 있어요!
  • 빌드 성능: 빌드 성능이 중요하다면 캐싱과 증분 빌드를 지원하는 Turborepo나 Nx를 고려해보세요! 🏎️
  • 기존 도구와의 통합: 기존에 사용 중인 도구와의 호환성을 고려해보세요.
  • 학습 곡선: 팀의 기술 스택과 학습 의지에 맞는 도구를 선택하는 게 좋아요!

다양한 상황에 따라 적합한 도구를 선택하는 것이 중요해요! 😊