모노레포 운영과 트러블슈팅
공통 코드의 선형적 증가에 따른 계층의 필요성 대두
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