pile·
프론트엔드·미리디미리디·

모노레포가 미리캔버스 프론트엔드 아키텍처를 뒷받침 하는 방법 [1/2]

모노레포를 도입하고 처음 몇 달은 좋지만 어느 순간 유틸리티 함수 하나를 고쳤을 뿐인데 CI가 30분 넘게 돌고, 한 팀이 shared 패키지 인터페이스를 조금 바꾸자 다른 팀들의 PR이 줄줄이 막히는 상황에서 출발한다. 미리캔버스 프론트엔드 팀도 최근까지 그 상태였다. 파일은 한 레포에 모여 있지만 코드는 여전히 거대한 덩어리처럼 결합된, 외형은 모노레포지만 내부 아키텍처는 모놀리스인 상태다.

핵심 포인트
  • 모놀리스는 빌드와 배포 관점의 개념이고 모노레포는 저장소 관점의 개념이라 둘은 독립적이다.
  • 멀티레포이면서 모놀리스일 수도 있고, 모노레포이면서 완전히 독립된 패키지들의 집합일 수도 있다.
  • 모노레포의 패키지는 물리적으로 같은 저장소에 있어도 논리적으로는 서로 얽히지 않아야 한다.
  • 모노레포를 모놀리스로 만드는 것은 "공통"이라는 단어이며, 그 함정이 은밀하고 자연스럽게 일어난다.
  • 두 군데에서 비슷한 코드를 보면 반사적으로 공통이 아니냐고 묻게 되고, 그 코드가 shared나 common 패키지로 들어간다.
상세 정리
  • 도입 이유: 여러 서비스에서 코드를 공유하고 패키지를 한 곳에서 일관되게 관리하며 CI/CD 파이프라인을 통일하려는 것으로 대체로 비슷하다.
  • 초기의 이점: 패키지 하나를 수정하면 모든 앱에 즉시 반영되고 공통 컴포넌트를 한 번 고치면 그걸 쓰는 모든 곳이 업데이트된다.
  • 증상 1: 버그 수정을 위해 유틸리티 함수 하나를 고쳤을 뿐인데 CI가 30분 넘게 돈다.
  • 증상 2: 한 팀이 shared 패키지의 인터페이스를 조금 바꾸면 다른 팀들의 PR이 줄줄이 막힌다.
  • 증상 3: 누군가 이게 공통 아니냐고 한마디 하면 별 고민 없이 common 패키지에 코드가 쌓이고, 그 패키지가 3,000줄을 넘기면서 도대체 무엇을 하는 패키지인지 아무도 모르게 된다.
  • 증상 4: 새로 입사한 개발자가 이 패키지를 건드리면 어디까지 영향이 가는지 물었을 때 아무도 자신 있게 답하지 못한다.
  • 모놀리스의 정의: 하나의 거대한 코드베이스가 하나의 빌드 결과물로 패키징되어 배포되는 구조로, 내부 모듈이 강하게 결합돼 한 부분을 바꾸면 전체가 영향을 받는다. 코드를 어디에 두든 빌드와 배포가 하나의 단위면 모놀리스다.
  • 모노레포의 정의: 여러 개의 독립적인 패키지를 하나의 저장소에서 관리하는 방식으로, 패키지들이 물리적으로 같은 레포에 있다는 것일 뿐 서로 어떻게 결합돼 있는지에 대해서는 아무 말도 하지 않는다.
  • 미리캔버스의 상태: 모노레포를 운영하고 있었지만 공유 패키지의 변경사항이 하나의 모놀리스 혹은 N개의 모놀리스 앱으로 공유되는 구조였다.
  • 재사용 본능의 함정: 학교에서, 책에서, 동료에게서 항상 재사용을 강조하는 이야기를 들어왔기 때문에 코드 반복을 제거하려는 반사가 생기고, 그것이 공통 패키지 비대화로 이어진다.
  • 이 글은 2편 구성의 1편으로, 문제를 어떻게 인식하고 어떤 원칙으로 해결했으며 그 과정에서 모노레포의 확장 가능한 구조가 무엇인지 발견한 이야기를 예고한다.
왜 읽나모노레포를 도입했는데 CI 시간과 팀 간 간섭이 오히려 늘었다면, 문제가 저장소 구조가 아니라 패키지 결합도에 있다는 진단과 공통 패키지가 비대해지는 심리적 경로를 확인할 수 있다.
미리디
미리디 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 프론트엔드·여기어때 (GC컴퍼니)여기어때 (GC컴퍼니)·

    항공 프론트엔드 구축기 (7/10): 창구를 하나만 두었습니다

    여기어때 항공 서비스 프론트엔드가 웹과 앱 웹뷰 두 환경에서 동일한 함수 호출로 동작하는 앱 브릿지 추상화 레이어를 설계한 과정을 다룬다. iOS·안드로이드 규약 차이와 "웹에 존재하지 않는 브릿지를 어떻게 호출하나"라는 문제를 단일 추상화 층으로 해결한 구현 사례다.

    요약 이어보기
    #react#typescript#webview+2