버전 관리 시스템에선 ‘모노레포(Monorepo)’라는 개념이 있습니다. ‘모노레포’란 ‘단일(single)’을 뜻하는 ‘모노’와 저장소(repository)의 줄임말 ‘레포(repo)’가 결합된 용어로, 여러 프로젝트의 코드를 같은 저장소에 보관하는 소프트웨어 개발 전략을 의미합니다. 이러한 관행은 적어도 2000년대 초에 거슬러 올라가며, 공유 코드베이스라고 불리기도 했습니다. 구글, 메타, 마이크로소프트, 우버, 에어비앤비, 트위터 등은 서로 다른 전략을 활용하면서도 방대한 코드량과 일상적인 변화를 가진 매우 큰 모노레포를 사용하고 있습니다.

모노레포와 관련된 개념으로는 모놀리스(monolith) 애플리케이션이 있지만, 모노레포는 하나의 큰 프로젝트로 서브 프로젝트들을 결합하는 모놀리스(monolith )와 달리, 여러 독립적인 프로젝트들을 포함할 수 있습니다.

장점

모노레포는 각각의 저장소를 사용하는 것에 비해 다양한 잠재적 장점이 있습니다.

코드 재사용 용이성

비슷한 기능이나 통신 프로토콜은 공유 라이브러리로 추상화되어, 프로젝트들이 의존성 패키지 관리자 없이 바로 포함할 수 있습니다.

간단한 의존성 관리

여러 프로젝트들이 제3의 의존성에 의존하는 다중 저장소 환경에서 해당 의존성은 여러 번 다운로드되거나 빌드될 수 있습니다. 모노레포에서는 같은 코드베이스에서 참조되는 의존성들 때문에 빌드를 쉽게 최적화할 수 있습니다.

원자적 커밋

함께 작동하는 프로젝트들이 서로 다른 저장소에 있으면, 한 프로젝트가 다른 프로젝트와 어떤 버전이 호환되는지를 동기화해야 합니다. 큰 프로젝트에서는 의존성 간 호환 가능한 버전을 관리하는 것은 ‘의존성 지옥(dependency hell)’이 될 수 있습니다. 모노레포에서는 개발자들이 여러 프로젝트를 원자적으로 변경할 수 있기 때문에 이 문제를 해소할 수 있습니다.

대규모 코드 리팩토링

개발자들이 전체 프로젝트에 접근할 수 있으므로, 리팩토링 후 모든 프로젝트 부분이 계속해서 기능하는지 확인할 수 있습니다.

팀 간 협업

원천 의존성(소스에서 컴파일된 의존성)을 사용하는 모노레포에서는 한 팀이 다른 팀이 작업 중인 프로젝트들을 개선할 수 있습니다. 이러한 접근은 코드 소유권의 유연성을 이끌어냅니다.

단점과 제한점

버전 정보 상실

반드시 그런 것은 아니지만, 몇몇 모노레포 빌드는 저장소 내의 모든 프로젝트에 걸쳐 하나의 버전 번호를 사용합니다. 이는 프로젝트별 의미 있는 버전 관리를 상실하게 만듭니다.

프로젝트별 접근 제어 부족

분할된 저장소를 사용할 때, 필요에 따라 저장소에 대한 접근을 부여할 수 있습니다. 모노레포는 프로젝트 전체에 대한 읽기 접근을 허용하여 잠재적인 새로운 보안 문제를 제기할 수 있습니다. 버전 관리 시스템에 따라 이러한 제한은 문제가 되지 않을 수 있습니다. 예를 들어, 서브버전을 사용할 때는 저장소의 일부분(하나의 디렉토리까지도)만을 다운로드할 수 있고, 경로 기반 인증을 통해 저장소 일부분에 대한 접근을 제한할 수 있습니다.

기본적으로 더 많은 저장 공간이 필요

분할된 저장소에서는 기본적으로 관심 있는 프로젝트만을 가져옵니다. 하지만 모노레포에서는 기본적으로 모든 프로젝트를 체크아웃하게 되어 상당한 저장 공간을 차지할 수 있습니다. 모든 버전 관리 시스템은 부분 체크아웃을 할 수 있는 메커니즘을 가지고 있지만, 이를 수행하는 것은 모노레포의 몇 가지 장점을 무효화할 수 있습니다.

확장성 문제

큰 프로젝트를 가진 회사들은 모노레포와 관련하여 빌드 도구와 버전 관리 시스템의 문제에 부딪혀왔습니다. 세계에서 가장 큰 모노레포로 추정되는 구글의 모노레포는 초대형 시스템의 하나로 분류되며, 하루에 수만 개의 contribution를 80테라바이트가 넘는 저장소에서 처리해야 합니다.

버전 관리 소프트웨어 확장

구글은 10년 이상 단일 기계에 호스팅된 퍼포스에 의존했습니다. 2005년 구글의 빌드 서버는 최대 10분 동안 멈출 수 있었습니다. 구글은 이를 2010년에 30초에서 1분 사이로 개선하였습니다. 확장성 문제로 인해 구글은 결국 자체 분산 버전 관리 시스템인 파이퍼를 개발했습니다.

페이스북은 버전 관리 시스템 머큐리얼의 성능 문제에 부딪혔으며, 클라이언트에 기여를 했습니다. 2014년 1월에는 기존의 깃 솔루션보다 더 빠르게 만들었습니다.

2017년 5월에 마이크로소프트는 윈도우 엔지니어들이 거의 모두 깃 모노레포를 사용하고 있다고 발표했습니다. 전환 과정에서 마이크로소프트는 깃 클라이언트에 상당한 기여를 하여 불필요한 파일 접근을 제거하고, 깃 가상 파일 시스템으로 큰 파일의 처리를 개선했습니다.

빌드 소프트웨어 확장

모노레포에서 잘 작동하는 빌드 도구는 드뭅니다. 체크인 시 전체 저장소에 대한 빌드와 연속적인 통합 테스트를 수행하는 흐름은 성능 문제를 초래할 것입니다. 방향성 그래프 빌드 시스템인 버크, 바젤, 팬츠, 플리즈와 같은 도구들은 개발의 활성 영역에 대해 빌드와 테스트를 분리함으로써 이 문제를 해결합니다.

결론

모노레포 (Monorepo)는 모든 프로젝트가 한 저장소에 있기에 빌드와 배포 시 버전 충돌 및 빌드 실패 같은 문제를 해결할 수 있으며 모든 프로젝트가 같은 공유 라이브러리를 사용함으로서 공유 라이브러리 버전 충돌 및 중복 저장를 방지 할 수 있습니다. 하지만 그로 인해 각 프로젝트 별로 권한 설정이 어렵고 기본적으로 총 프로젝트 용량이 커서 체크아웃 시 많은 시간이 필요하며 필요한 프로젝트만 체크아웃 하기 어렵습니다. 또한 한 프로젝트가 버전 업데이트 시 전체 프로젝트가 버전 업데이트해야 하는 문제가 있습니다.