Pnpm으로 Monorepo 구축하기 - 1. 도입 배경

YI·2024년 7월 31일
0
post-thumbnail

개인 프로젝트를 Monorepo 구조로 관리하게 된 이유와 pnpm을 선택한 이유, 그리고 이를 어떻게 구축했는지에 대한 경험을 공유하려고 합니다.

1️⃣ Monorepo 도입 배경

지금까지 회사, 개인 프로젝트, 팀 프로젝트들은 모두 멀티레포 방식으로 관리했습니다. 멀티레포 구조를 사용할때 편리한 점도 있었지만 다음과 같은 문제들도 마주했습니다.

멀티레포 방식에서 마주한 문제점

1) 새로운 프로젝트 구축 비용

  • 새로운 프로젝트를 생성할 때마다 서비스 환경을 반복적으로 설정해야 했습니다.
  • 공통적으로 사용하는 UI 컴포넌트와 유틸 함수도 매번 별도로 추가하고 설정해야 했습니다.

2) 프로젝트 관리의 어려움과 증가하는 중복 코드

  • 공통적으로 사용하는 UI 컴포넌트 등에 변경 사항이 발생하면 이를 사용하는 모든 레포지토리에서 각각 수정해야 했습니다.
  • Boilerplate 레포지토리를 사용하는 경우, Boilerplate 자체도 별도의 프로젝트로 관리해야 하며, 이를 지속적으로 업데이트하고 유지보수해야 했습니다.

위와 같은 문제들로 인해 프로젝트를 시작하고 관리하는 데 있어 효율성이 떨어지고, 관리 부담이 커졌습니다.

2️⃣ Monorepo 도입

그래서 개인 프로젝트들을 가능한 빠르게 시작하고, 최소한의 리소스로 관리하기 위해 모노레포를 선택했습니다.

모노레포 도입을 통해, 다음과 같은 이점을 얻을 수 있었습니다.

1) 일관성 있는 코드베이스와 코드 공유, 재사용 용이

모노레포는 재사용되는 패키지들을 하나의 레포지토리에서 관리합니다. 이렇게 하면 모든 프로젝트에서 동일한 패키지를 공유하게 되어, 중복 작업을 줄이고 코드의 일관성을 유지할 수 있습니다. 모노레포 내의 각 프로젝트는 동일한 코드베이스를 참조하기 때문에 패키지 업데이트나 버그 수정이 모든 프로젝트에 자동으로 반영됩니다.

2) 자동화된 프로젝트 생성

Scaffolding을 사용하면 새로운 프로젝트 생성과 초기 설정 과정도 자동화할 수 있습니다. 프로젝트 템플릿과 구성 요소를 미리 정의해 놓으면, 새로운 프로젝트를 시작할 때 반복적인 설정 작업을 줄이고 신속하게 개발을 시작할 수 있습니다.

3️⃣ pnpm 도입 배경

모노레포 구조를 사용할 수 있도록 도와주는 도구들이 여러가지 있는 데, 그 중 저는 아래와 같은 이유로 pnpm workspace를 선택했습니다.

  • 모노레포 구조 지원
  • npm, yarn의 유령 의존성 문제
  • 효율적인 의존성 관리

1) 모노레포 구조 지원

  • npm은 7부터 워크스페이스 기능이 도입되었고, yarn berry와 pnpm에 비해 기능이 부족(패키지 의존성 관리, 캐싱 등)
  • yarn classic(v1)은 workspace 지원하지 않고, berry(v2+)는 workspace를 지원하지만 일부 패키지들이 berry를 지원하지 않음
  • 반면, pnpm은 처음 출시되었을 때부터 workspace 지원, 간편한 설정, 효율적인 의존성 관리 지원하기 때문에 pnpm을 선택했습니다.

2) npm, yarn의 유령 의존성 문제

npm 및 yarn classic에서는 중복해서 설치되는 node_modules를 아끼기 위해 Hoisting을 사용합니다.

위와 같은 의존성 트리가 있다고 가정하면,

왼쪽 트리처럼 [A(1.0)][B(1.0)] 패키지가 2번 설치되면 디스크 공간이 낭비되기 때문에, 이러한 일을 방지하기 위해 npm과 yarn classic은 오른쪽 트리처럼 트리를 변경합니다.

오른쪽 트리와 같이 의존성을 끌어올리면 package-1에서는 원래 참조 수 없었던 [B(1.0)] 라이브러리를 직접 참조할 수 있게 됩니다.

이렇게 Hoisting에 따라 직접 의존하고 있지 않은 라이브러리를 참조할 수 있는 현상을 "유령 의존성"이라고 합니다.

유령 의존성이 존재하면 package.json에 직접 명시되지 않은 라이브러리를 직접 참조할 수 있어 의존성 관리 시스템에 혼란을 초래할 수 있습니다.

3) 효율적인 의존성 관리

반면 pnpm은 의존성 관리를 위해 전역 캐시와 심볼릭 링크를 사용합니다. 모든 의존성을 중앙 캐시에 저장하고, 패키지 간 의존성을 심볼릭 링크로 연결하여 중복된 설치를 방지합니다. 또한 package.json에 직접 명시되지 않은 라이브러리에 대한 참조를 금지합니다. 이를 통해, pnpm을 사용하면 유령 의존성 문제가 발생하지 않고, 각 패키지의 의존성이 명확하게 관리됩니다.

4️⃣ 마무리

다양한 아이디어들은 있지만 늘 프로젝트를 시작하는 것에 어려움을 겪어서 어떻게 하면 이러한 문제를 해결할 수 있을 지에 관심이 많았습니다. 그러던 중 모노레포에 대해 알게 되면서, 이를 구축하기 위해 정말 많은 것을 공부하고, 정말 많은 시행착오를 겪었습니다. 그 수많은 시행착오 끝에 개인 프로젝트에 pnpm을 사용한 모노레포를 도입한 뒤 프로젝트 관리와 개발 효율성이 크게 향상되었습니다. 이러한 제 경험이 비슷한 고민을 가진 개발자들에게 도움이 되길 바라며 이번 시리즈를 준비했습니다.

다음 글에서는 pnpm을 통해 실제 모노레포를 어떻게 구축하는 지 그 과정과 팁을 상세히 공유해보려고 합니다.

많은 관심 부탁드립니다!

참조
모노레포 이렇게 좋은데 왜 안써요?
Turborepo 및 Pnpm을 사용하여 Monorepo 구축
Yarn 대신 pnpm으로 넘어간 3가지 이유
Managing a full-stack, multipackage monorepo using pnpm

profile
Junior Frontend Developer

0개의 댓글