Published on

monorepo 개념

모놀로식(Monolithic) 애플리케이션

소프트웨어 엔지니어링에서 모놀리식 애플리케이션은 모듈화 없이 설계된 소프트웨어 애플리케이션을 말한다.

거대 서비스를 개발할 때, 소스 코드가 모듈화 없이 하나의 프로젝트로 구성된다면 어떻게 될까? 코드가 서로 직접적으로 의존하며 단 하나의 버전으로 관리되면서 관심 분리(separation of concerns)가 어려워지고, 설계, 리팩터링, 배포 등의 작업을 매번 거대한 단위로 처리해야 하므로 개발상 많은 제약과 비효율이 있을 것이다.

모듈화와 재사용성

이러한 모놀리식 구조의 한계는 모듈화(modularity)를 통해 해결할 수 있다.
일반적으로 모듈식 프로그래밍(modular programming)은 애플리케이션 로직의 일부를 재사용할 수 있도록 지원하고 전체 교체 없이 애플리케이션의 일부를 수정 또는 교체할 수 있게 해 유지 관리를 용이하게 한다.

그런데 이렇게 만든 모듈이 다른 애플리케이션에도 사용될 수 있다면 소스를 어디에 위치시켜야 할까? 아마도 해당 모듈을 위한 독자적인 저장소가 있다면 좀 더 관리하기 쉬울 것이다. 이 구조가 바로 멀티레포(multirepo)다.

멀티레포 (폴리레포)

앞서 분리된 각 모듈은 고유한 레포지토리 를 갖는 독자적 프로젝트가 된다.

멀티레포의 자율성

  • 각 프로젝트는 높은 자율성을 가지며 독립적인 개발, 테스트, 빌드, 배포 파이프라인을 갖게 된다.
  • 멀티레포는 현재 대부분의 애플리케 이션을 개발하는 표준적인 방법
  • 업계는 팀의 자율성이라는 큰 이유 때문에 이 방식을 선호한다.

멀티레포의 문제

  1. 번거로운 프로젝트 생성

    • 새로운 공유 패키지를 구성할때마다 리포지토리 생성 > 커미터 추가 > 개발 환경 구축 > CI/CD 구축 > 빌드 > 패 키지 저장소에 publish
    • 단지 공통 기능을 분리하고 싶었을 뿐 인데 번거로운 과정을 반복
  1. 패키지 간의 중복 코드 가능성

    • 앞선 1번 문제를 피하기 위해 공통 요소를 자체적으로 작성하려는 경향 (Util, Common, ...)
    • 시간이 지날 수록 보안 및 품질관리 부담 증가
  1. 관리 포인트 증가

    • 레포지토리 증가에 따라 DevOps 관리 부담도 늘어난다
  1. 일관성 없는 개발자 경험(DX)

    • 각 프로젝트는 DevOps를 위해 고유한 명령 집합을 사용 (yarn start, yarn run dev, yarn run build:dry)
    • 프로젝트 간에 사용할 명령을 기억 해야하는 정신적 오버헤드
  2. 다른 패키지의 변경 사항 파악

    • 관련 패키지 변화를 놓치기 쉬움
  3. 레포지토리 간 리팩터링 비용

    • 여러 레포지토리에 걸쳐 변화를 반영 하는 것은 어려운 일
    • 리팩터링 후 각 패키지들의 버전은 어떻게 관리해야 할까

그렇다면, 모듈화로 관심 분리를 이루면서, 동시에 모듈을 쉽게 참조하고, 개발 파이프라인도 쉽게 구축할 수는 없을까?
이제 모노레포가 출동할 시간이다.

모노레포

모노레포란?

두 개 이상의 프로젝트가 동일한 레포지토리에 저장되는 소프트웨어 개발 전략이다.

모노레포의 또 다른 중요한 특징 중 하나는 프로젝트 간의 관계다.
단순히 여러 프로젝트가 하나의 저장소를 사용한다고 해서 모노레포 구조라고 부르기에는 부족하다.
흔히 모노레포에서는 프로젝트 사이에 의존성이 존재하거나 같은 제품군이거나 하는 정의된 관계가 존재한다.

모노레포가 해결하는 멀티레포의 문제들

  1. 더 쉬운 프로젝트 생성

    • 멀티레포에서 공유 패키지를 만들 때 다음과 같은 과정을 거친다.
      저장소 생성 > 커미터 추가 > 개발환경 구축 > CI/CD 구축 > 빌드 > 패키지 저장소에 publish
      모노레포에서는 저장소 생성 및 커미터 추가 과정이 필요 없고, 개발 환경, CI/CD, 빌드, 게시 등의 과정에 기존 DevOps를 이용하므로 새 프로젝트 생성에 대한 오버헤드가 없다.
  2. 더 쉬운 의존성 관리

    • 의존성 패키지가 같은 저장소에 있으므로 버전이 지정된 패키지를 npm registry와 같은 곳에 publish할 필요가 없다.
  3. 단일화된 관리 포인트

    • 개발환경 및 DevOps에 대한 업데이트를 한번에 반영
  4. 일관된 개발자 경험 제공

    • 애플리케이션을 일관되게 구축하고 테스트할 수 있다. 개발자는 다른 팀의 애플리케이션에 자신 있게 기여하고 변경 사항이 안전한지 확인할 수 있다.
  5. 다른 프로젝트 변경사항 파악

    • 변경사항의 영향을 받는 조직에서 쉽게 변화를 확인
  6. 교차 저장소 리팩터링 비용 감소

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

다른 팀이 내가 모르는 사이에 내 코드를 변경한다면?

GitHub의 CODEOWNERS file 기능을 사용하면 폴더 기반으로 소유권을 구성할 수 있다.

# 이 레포지토리에 대한 모든 PR을 소유자에게 리뷰받아야 머지할 수 있습니다.
@global-owner1 @global-owner2

# todo-api 경로는 john과 jane에게 리뷰 받아야 합니다.
packages/todo-api/* @john @jane

# i18n은 michael에게 리뷰 받아야 합니다.
packages/i18n/* @michael

모노레포가 멀티레포보다 항상 나은 방법인가?

그렇지 않다. 멀티레포의 단점이 모노레포의 장점이고 장단점이 교차하기 때문에 적절한 상황에서 사용해야 한다.
모노레포가 적절한 상황은 다음과 같다.

  • 유사한 제품의 집합
  • 여러 프로젝트의 변화를 한 눈에 파악해야 할 때
  • 호스트 애플리케이션을 플러그인 등으로 확장할 때
  • 공통 기능을 재사용하는 관련된 프로젝트들의 집합
  • 유사한 DevOps 로 구성된 프로젝트들의 집합

모노레포를 구축할 때 고려할 측면들

참고 : https://monorepo.tools/#monorepo-features


참조