모노레포 운영과 트러블슈팅

공통 코드의 선형적 증가에 따른 계층의 필요성 대두

  • changeOrderStatus, autoSignInCheckbox 등은 적절한 프로덕트 단위의 공통 컴포넌트인가?

    • No, 프로덕트 단위가 아닌 도메인 단위이다.

  • Chart, Input, Search, Slider 등 공통의 이름을 가진 것들이 정말 공통이 맞는가?

    • No, 비즈니스 및 페이지 단위의 예외처리가 많이 들어가 있는 페이지 단위의 코드이다.

    • ~~Input 등의 명확하게 네이밍이 설정이 되어있어야 적합하다.

공통의 계층을 더 잘게 쪼개기

프로덕트 단위로 공통의 코드를 제공하는 것이 한 군데 밖에 없다면 더 잘게 쪼개야 한다.

  • 프로덕트 내의 공통의 코드는 원래대로 공통의 역할을 하기도 하지만 코드 응집 및 긴 코드 은닉용으로도 사용된다.

  • 다양한 용도로 사용되는 공통의 코드를 더 분산시킬만한 아키텍처를 사용하여 한 군데에 응집되는걸 막아야 한다.

  • 도메인에 의존적인 컴포넌트가 아닌 도메인을 공통으로 만들어 줄 수 있는 컴포넌트를 만들어야 한다.

    • 컴포넌트를 잘 만들었단 소리를 들을려면 컴포넌트를 레이아웃과 비즈니스를 분리하여 레이아웃을 공통으로 쓰일 수 있도록 만들어야 한다.

  • 응집되는 걸 막기 위한 방안

    • 첫 번째: 컴포넌트는 Atomic Design을 쓰거나 페이지 별로 컴포넌트 폴더를 추가할 수 있다.

      • 컴포넌트 내부에서 쪼개거나, 컴포넌트 위에서 폴더링으로 쪼개거나

    • 두 번째: hooks, utils 등도 페이지, 도메인 별로 폴더를 추가한다.

      • 공통의 코드를 단계별로 확장시킬 수 있는 방안을 고민

    • 세 번째: 추가적으로 각 컴포넌트들을 내릴지 올릴지를 결정하여 지속적으로 위치를 변경시킨다.

      • 올린다는건 공통으로 쓰이는 더 영향력있는 컴포넌트가 된다.

컴포넌트가 잘 만들어졌다. 또는 못만들어졌다가 중요한게 아니다.

비즈니스를 빠르게 작업하기 위한 과거의 히스토리를 생각하고 과거의 코드들의 Respect를 갖고 있어야 한다.

과거 코드들의 히스토리에서 더 좋은 방향으로 나아가는 것들을 제안해야 한다.

공통 코드의 크기에 따른 레이어 구별

  • 위로 갈 수록 더 어려운 등재를 위한 프로세스가 존재

  • 코드에서 시작, 페이지 공통 라이브러리에 추가 된다.

  • 페이지 공통 라이브러리에 등재된 것은 도메인 공통 라이브러리로 등재된다.

  • 도메인 공통 라이브러리에서 프로덕트 공통 라이브러리는 대다수가 떨어진다.

  • 프로덕트 공통 라이브러리에서 전사 공통은 오랜 시간이 걸릴 수 있다.

Product Layer 구조

  • 조금 더 구체적인 계층의 구조도

  • 각 계층별로 공통이라는 영역을 가진 그룹이 존재

  • 각 계층별로 중복해서 쓰이는 것이 많아진다면 상위 라이브러리로 이동

Folder Structure

  • 폴더 단위로 더 상세하게 나뉘게 됨

  • 너무 많은 폴더가 존재하기 때문에 가시적으로 어려울 수 있음

  • 작은 프로덕트는 이러한 구조가 오히려 생산성이 더 안나올 수 있음

    • 모노레포 내 각 도메인 별로 담당자가 붙어있는 상황에 적합

공통 코드 등재의 프로세스 만들기

공통 코드로 올려보낼 수록 더 많은 사람이 존재를 알게하기 위해 공유 프로세스를 거쳐야 한다.

  • 공통으로 올리는 것처럼, 팀 내부에서도 이러한 프로세스 구축이 필요

  • 자동화된 프로세스 (슬랙, 지라 티켓 등 연동)을 통해 모두가 쉽게 접근하고 알 수 있도록 제공

정리

  • 공통의 코드 증가로 인해 코드량이 절대적으로 많아지면서 생기는 문제 발생

  • 이러한 문제를 해결하기 위해 점진적으로 레이어를 분리

  • 레이러를 분리하고 그 안에 폴더 구조를 새로 확립하면서 공통의 코드를 여러 군데서 활용하는 상황이 생기면 에스컬레이션을 진행한다.

  • 그러면서 협업의 구조가 변화하고 공통 코드가 풍부해지면서 생산성은 증가한다.

DX 개선의 필요성 대두

Developer Experience 모노레포를 운영하다보면 DX의 한계에 다다를 시점이 다가온다.

  • 속도, 이해도, 관리 세 가지 측면에서 터보레포 프레임워크를 사용해야 한다.

  • 지금까지 모노레포를 단순히 workspace 개념으로만 사용됨

    • 어느 일정 수준이되면 수많은 라이브러리 빌드 및 런타임 사용으로 vs code나 툴의 메모리 초과로 shutdown 되는 현상이 생긴다.

    • 더불어 실행 속도가 저하되면, 용량 자체도 무거워지는 경우가 생김

  • 이러한 부분은 개발 속도를 저하시키며, 빠른 비즈니스 개발을 하고자 모노레포를 썻던 이유를 퇴색시킨다.

CRA가 표준에서 없어진 이상, Next를 사용하는 경우가 많을 것으로 판단

Next와 궁합이 잘맞는 Turborepo

  • Turborepo를 써야하는 9가지 이유

  • 우리가 사용할 빌드 최적화 등을 잘 사용할 수 있는 기술 존재

  • Cloud caching, Incremental builds, zero runtime overhead, parallel execution 등,

간단한 설정

turbo.json

  • cache, dependsON 등의 키워드 이용

  • 터보레포의 파이프라인은 script의 명령어와 매칭된다.

복잡한 프로세스를 Turborepo로 이관하기

  • web에서 여러 라이브러리를 참조하면, web을 배포 전 여러 라이브러리를 빌드하고 배포하는 여러 과정이 필요하다.

  • 첫 번째: TypeCheck, lint stage를 거쳐서 코드상의 문제를 체크한다.

  • 두 번째: common과 apis를 병렬 빌드를 진행한다.

    • 원래되로라면 &&로 진행되어 각 각 5분씩 걸린다면(병렬X) 10분이 걸리게 되어 속도면에서 손해가 된다. -> 병렬 빌드로 최적화 가능

  • 세 번쨰: web 빌드를 하고 실제 프로덕션 배포를 진행한다.

Turborepo를 통해 기대하는 것

  • 병렬 빌드 실행: turborepo를 이용해 빌드 시간을 병렬로 실행하여 단축시킴

  • 캐싱을 통한 빌드 실패 시 시간 보완: web 빌드 타임때 실패를 했어도 성공한 빌드는 캐싱이 되어 남아있는다.

  • 배포 프로세스 시각화: turborepo의 그래프 기능을 통한 의존 관계를 확인할 수 있음

정리

  • monorepo의 운영이 오래될 수록 DX 개선이 필요해지는 시기가 오게된다.

  • 여러 라이브러리의 빌드에서의 실패 혹은 디버깅, 실행 시 시간의 오래걸림으로 생산성 약화

  • 그러한 부분을 turborepo 등으로 이관하여 효율적인 DX를 챙길 수 있음

Last updated