turborepo + pnpm 모노레포 사용기 (설정)

김정민·2023년 5월 29일
3

turborepo를 이용해 모노레포 설정하는 작업을 포스팅해보려합니다.

turborepo와 모노레포 방식은 익숙치않고 또 처음 작업을 해보는거라 설명이 미흡하거나 잘못된 부분이 있을 수 있습니다.
댓글로 코멘트주시면 감사하겠습니다!

들어가기에 앞서 이번 포스팅에 주제인 모노레포를 설명하겠습니다.

모노레포는 단일 리포지터리에 여러 개의 서브 프로젝트가 존재하는 방식입니다.

주로 사용하던 방식인 멀티레포도 같이 장단점을 알아보자면

장점

  • 각 프로젝트가 고유의 저장소를 가지게 됨으로써, 다른 프로젝트와의 의존성을 가지고 있지 않아 독립적으로 빠르게 개발이 가능합니다
  • 비교적 크기가 가벼워 프로젝트 관리 면으로 수월합니다.

단점

  • 각 프로젝트의 코드 컨벤션이 통일하기가 어려워질 수 있음
  • 각 프로젝트별로 사용하는 모듈 및 버전 스택이 달라질 수 있음
  • 오랫동안 건드리지 않은 프로젝트의 관리가 힘들어지며, 시간이 지날수록 해당 프로젝트의 Legacy 파악이 어려워질 수 있음
  • 팀원별 컨텍스트 공유가 서로 원활하지 않을 수 있음
  • 코드 재사용이 쉽지 않으므로, 중복 코드 가능성이 높아짐

모노레포는 이런 멀티레포의 단점을 보완하는 장점들을 많이 가지고 있습니다.

대표적으로 이룰 수 있는 효과는

  • 팀 컨벤션 통일 및 업무 능률 더욱 활성화시킬 수 있는 코드리뷰 환경을 제공
  • 더 쉬운 프로젝트 생성 (밑에 부가설명)
  • 더 쉬운 의존성 관리
  • 서로 의존하는 저장소들의 리팩터링 비용 감소

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

이런 모노레포를 형성시킬 수 있는 패키지 중 대표적으로 turborepo 존재합니다.

해당 turborepo 사이트에서도 설명해주지만, 큰 특징 9개를 나열해보겠습니다.

1. Incremental builds
작업 진행을 캐싱해 이미 계산된 내용은 건너 뛰는 것을 의미합니다. 빌드는 딱 한 번만 하는 것을 목표로 합니다.

2. Content-aware hasing
타임스탬프가 아닌 콘텐츠를 인식하는 방식으로 해싱을 지원합니다. 이를 통해 모든 파일을 다시 빌드하는 것이 아니라 변경된 파일만 빌드합니다.
3. Cloud caching
클라우드 빌드 캐시를 팀원 및 CI/CD와 공유합니다. 이를 통해 로컬 환경을 넘어 클라우드 환경에서도 빠른 빌드를 제공합니다.
4. Parallel execution
모든 코어를 사용하는 병렬 실행을 목표로 합니다. 지정된 태스크 단위로 의존성을 판단해 최대한 병렬적으로 작업을 진행합니다.

5. Task Pipelines
태스크 간의 연결을 정의해서 빌드를 언제 어떻게 실행할지 판단해 최적화합니다.
6. Zero Runtime Overhead
런타임 코드와 소스 맵을 다루지 않기 때문에 런타임 단계에서 파악하지 못한 리스크가 불거질 위험이 없습니다.
7. Pruned subsets
빌드에 필요한 요소만으로 모노 레포의 하위 집합을 생성해 PaaS 배포 속도를 높입니다.
8. JSON configuration
별도의 코드 작업 없이 JSON 설정으로 터보를 사용할 수 있습니다.
// turbo.json { "baseBranch": "origin/main", "pipeline": { "build": { ... } } }
9. Profile in browser
빌드 프로필로 빌드 과정을 시각화하면 병목 지점을 쉽게 찾을 수 있습니다.

설정 방법

설정하는 법을 차례대로 알아보겠습니다.

npx create-turbo@latest

해당 키워드로 설치를 진행하면, 패키지 매니저 선택하는 항목이 나타납니다.


저는 pnpm으로 설정을 하겠습니다.

짜잔~ ✨
설치완료가 되면 기본 모노레포 형식의 폴더 구조를 만들어줍니다.

구성을 보면 apps, packages, modules가 보입니다.

apps는 Nextjs with Typescript로 레포가 형성되어있습니다.

packages는 공유되는 라이브러리나 컴포넌트 등이 형성되어있습니다.

공유되는 컴포넌트가 존재하는 ui 폴더로 이동하면

이렇게 Button 컴포넌트가 존재하고 또한 이걸 사용하는 apps - docs로 이동하면

해당 Button을 서로 다른 레포인 docs에서 쉽게 접근해서 사용하는 것을 확인할 수 있습니다.


./apps/docs/package.json 에서 dependecies를 확인해보면 다음과 같은 부분을 볼 수 있습니다. 이는 docs 프로젝트가 ./packages/ui 패키지를 의존하고 있음을 나타냅니다.

다음 포스팅에는 새로운 레포를 추가하는 방법과 작업 공간을 하나만 선택해서 실행하는 방법을 알아보겠습니다.

출처

0개의 댓글