Programming Languages/Typescript & NestJS

[NestJS] Monorepo로 구축하기 1 : pnpm workspace

9Jaeng 2025. 5. 25. 20:19
728x90

기존의 프로젝트는 모든 기능이 하나의 단일 코드베이스에서 관리되는 모놀리식 아키텍처(Monolithic Architecture)를 사용하고 있는 거대한 레거시였다.

CSAP 인증을 받기 위해 테이블구조도 큰 변경이 필요했고 서비스가 커지면서 개발 유지보수를 힘들게 만드는 현재의 구조를 변경하기 위해 모노레포 아키텍처로 코드베이스를 변경하기로 논의가 되었다.

이번 블로그는 모노레포를 구성하면서 조사했던 것들에 대해 정리를 해보고자 한다.

첫 번째로, mono repo 구축을 위한 package workspace에 대해 간단히 정리를 해보았다

Monorepo를 구축하는 방법 : pnpm workspace 

monorepo를 구축하는 방법으로는 yarn worskapce와 같은 package workspace 나 lerna , Turborepo 등과 같은 도구를 사용하는 방법이 있다.

나는 그중 pnpm workspace를 선택하였는데, 이유는 다음과 같다

1. pnpm workspace는 기본적으로 모노레포를 지원한다. 

2. yarn , npm은 phantom dependency문제가 있다

3. 현재 사용 중이라 러닝커브가 높지 않다

 phantom dependency란?

여기서 phantom dependnency란, A워크스페이스에서 설치하지 않는 의존성을 사용할 수 있게 된다거나 원래 사용 중이던 의존성을 갑자기 찾지 못한다는 경우를 말한다.

의존성 호이스팅 : yarn classic과 npm의 경우 package설치의 중복을 줄이기 위해 의존성이 호이스팅 된다

아래의 그림을 보면, package-1 은 A, C를 의존성으로 갖고 A, C는 각각 하위 의존성으로 B(1.0), B(2.0)을 갖는다. yarn은 이런 의존성들을 호이스팅 하여 root node_modules에서 관리한다. (평탄화라고 부르는 것 같다)

이때 package-1 은 B(1.0)을 설치하지 않았지만 호이스팅 되어 B(1.0)을 사용할 수 있다. 만약 B(1.0)을 의존하던 것이 없어진다면 node_modules에 B(1.0)이 등록되지 않기 때문에 not found module 이슈가 발생할 것이다.

pnpm의 공식문서 pnpm vs npm과블로그를 참고해 보자

 

그렇다면, pnpm의 구조는 어떤가?

pnpm은 symlink를 통해 package를 참조하는 방식을 사용한다.

 Symlinked `node_modules` structure

 

Symlinked `node_modules` structure | pnpm

This article only describes how pnpm's node_modules are structured when

pnpm.io

위의 공식문서에 따르면, pnpm 은 symlink를 사용하여 중첩된 종속성 트리를 만든다.

node_modules 안에 있는 모든 패키지의 모든 파일은 content-addressable stora라는 전역 저장소에 대한 hard link를 갖는다.

hard link란, 파일시스템의 기능 중 하나로, 하나의 파일 데이터를 여러 위치에서 참조할 수 있도록 하는 방식. 즉, 동일한 파일 내용을 여러 경로에서 접근할 수 있게 하되, 실제로는 디스크 상에 하나의 데이터만 존재한다.

https://pnpm.io/symlinked-node-modules-structure

위와 같이 하드 링크가 구축되면, 중첩된 종속성 그래프 구조를 구축하기 위해 simlink를 생성한다.

https://pnpm.io/symlinked-node-modules-structure

위의 경우 foo는 bar를 의존하는데, node_modules/. pnpm/foo@1.0.0/node_modules의 bar는. pnpm에 있는 bar를 simlink로 참조한다.  이런 방식을 사용함으로써 순환참조, self 의존의 경우도 문제없이 가능하다.

npm이나 yarn classic과 같이 호이스팅을 하지 않아 phantom dependency는 발생하지 않는다.

pnpm의 saveing disk 전략

pnpm은 위와 같은 content-addressable storage 방식을 사용함으로써 disk 공간 절약에도 좋다

https://pnpm.io/motivation

만약 npm이라면, 하나의 의종성을 100개의 패키지에서 의존성으로 갖는다면, 100개가 복사될 것이지만 pnpm은 store에 한 번만 저장하고 다른 패키지들이 참조를 하도록 하여 디스크를 절약할 수 있다. 만약 의존성의 버전이 올라가면 올라간 버전이 새로 저장되는 방식을 취함으로써 버전별 관리가 가능하다는 장점이 있다.

이런 이유로 pnpm workspace를 사용하게 되었다.

다음 포스팅으로는, nestjs와 pnpm으로 monorepo를 구축했던 방법에 대해서 작성해보고 발생했던 tsconfig관연 이슈에 대해 작성해보조가 한다.

728x90