모노레포와 Yarn Workspaces를 선택한 이유 - clappingmin/asterum_traveler GitHub Wiki

문서 목적

이 문서는 하나의 프로젝트 내에서 Admin(어드민)과 App(사용자용 앱)을 통합적으로 관리하기 위해 Yarn Workspaces 기반의 모노레포(monorepo) 구조를 도입한 배경과 이유, 구현 방식, 그리고 향후 개선 방향을 정리한 기록이다.


도입 배경 및 목표

해당 프로젝트는 다음과 같은 구조적 특성을 가지고 있었다:

  • 관리자용 (Admin)과 사용자용 앱(App) 두 개의 React 프로젝트가 동시에 필요
  • 두 프로젝트는 다음 요소들을 공통으로 사용함:
    • 타입 정의 (TypeScript 기반 interface, types)
    • UI 컴포넌트 설정 (예: Chakra UI 커스터마이징)

초기에는 각각의 프로젝트를 독립적으로 관리하는 방식도 고려했지만, 다음과 같은 유지보수 및 일관성 문제를 우려하게 되었다:

  • 동일한 타입을 Admin과 App 양쪽에서 중복 정의하거나, 수정 시 양쪽을 동기화해야 하는 번거로움 발생
  • Chakra UI 등의 설정도 중복 구성되며 코드 재사용에 제약
  • React / TypeScript 버전 등의 의존성 차이로 인한 충돌 가능성

이를 해결하기 위해, 하나의 레포지토리 안에서 각 프로젝트를 패키지처럼 분리 관리할 수 있는 모노레포 구조를 도입하고자 했다.


선택 방안: Yarn Workspaces 기반 모노레포

모노레포 구조를 구현하기 위한 여러 도구들 중에서 Yarn Workspaces를 선택한 이유는 다음과 같다.

  • 설정이 상대적으로 간단하다. package.json만으로 구조를 구성할 수 있음
  • 내부적으로 패키지 간의 심볼릭 링크를 자동 관리하여, 공통 코드의 공유가 쉬움
  • Webpack/Vite 등 프론트엔드 빌드 툴과도 호환성 우수

"폼이 덜 들고, 구조가 깔끔하면서도 필요한 기능을 제공하는 방식"을 찾던 중 Yarn Workspaces가 가장 적합한 솔루션으로 판단되었다.


현재 구조 예시

root/
├── apps/
│   ├── asterum_traveler-admin/    # 어드민 프로젝트
│   ├── asterum_traveler-app/      # 사용자용 앱 프로젝트
├── packages/
│   └── shared/        # 공통 타입, 컴포넌트 등
├── package.json       # workspaces 설정 포함
└── yarn.lock
  • shared 패키지에 공통 타입, UI를 관리함으로써 코드 중복 제거
  • Admin과 App은 동일한 버전의 React, TypeScript를 공유하여 의존성 관리가 통일됨

추후 개선 방향

  • shared 패키지를 더 세분화하여 types, components, hooks 등으로 분리할 수 있음
  • CI/CD 파이프라인을 구축하여 패키지 단위 배포/테스트 자동화 연동

정리

  • Admin과 App을 동시에 관리하면서 공통 코드를 효과적으로 공유하고, 버전 및 설정 충돌을 방지하기 위해 yarn workspaces 기반의 모노레포 구조를 도입했다.
  • 이 구조는 유지보수 효율성과 코드 일관성 측면에서 큰 이점을 제공하며, 프로젝트 규모가 확장되더라도 안정적으로 대응할 수 있는 기반을 마련해준다.