내게 맞는 monorepo 찾기

모노레포 도입 배경

개발을 하다보면 여러 프로젝트에 공통적으로 사용되는 함수나, 컴포넌트들이 있습니다. 처음에 사용한 방법은 gist에 코드들을 올려두고 사용했습니다. 하지만 gist는 일일이 찾아봐야한다는 번거로움이 있었고, 코드를 수정하거나 업데이트 하는 것이 불편했습니다.

그래서 시도한것이 패키지 매니저툴에 배포를 하는 것이었습니다. Klaytn프로젝트를 하던 당시 caverjs를 내가 사용하기 쉽게 만들어서 npm에 배포를 했습니다. npm패키지로 코드를 배포하면 사용할때에는 편했지만, 코드를 수정하거나 업데이트 하는 것이 불편했습니다. 또한 의존성 없이 여러 함수들의 코드 조각을 만들고 싶었는데, npm 배포 세팅을 하여 모든 함수들을 개별로 배포해서 사용할수도 없는 문제가 있었습니다.

그래서 각 도메인별로 멀티레포로 구성을 해서 사용을 하려던중에 monorepo를 알게 되어서 여러 프로젝트에 공통적으로 사용될수 있는 함수들을 관리하고자 했습니다.

모노레포 선정

모노레포는 패키지 매니저와 라이브러리를 사용하여 구성을 할 수 있었습니다. 처음으로 사용해본 모노레포는 Lerna였습니다.

1. Lerna

JS 트랜드 통계를 볼 수 있는 stateofjs 사이트에서 모노레포 사용률이 상위권이 있어서 선택했습니다.

모노레포의 도입 이유가 간편하게 여러 패키지를 관리하려 했었는데, Lerna의 경우 초기 세팅이 시간이 오래 걸렸고, 하나의 패키지를 추가할때마다 새로 세팅을 해야하는 번거로움이 있었습니다.

2. Nx

Nx의 경우 회사에서 도입한 모노레포 였습니다. Nx의 경우 vsCode의 Extention을 사용해서 명령어로 패키지를 추가하거나 삭제하는 것이 편리했습니다. 예를 들어 Nextjs + storybook을 설치하려면 Next를 설치하고 storybook을 따로 세팅을 해주어야 했지만, Nx의 명령어로 간편하게 설치할 수 있었습니다.

하지만 Nx도 라이브러리에 의존성이 강해서, Nextjs의 최신 버전을 사용을 하려 했지만 Nx에서 최신 버전 지원을 하지 않는 다면 사용을 할 수 없는 문제가 있었습니다.

3. Turborepo

Turborepo의 경우 Nextjs를 개발한 Vercel팀에서 만든 모노레포 라이브러리입니다. 해당 라이의 경우 이제것 사용해봤던 lerna와 Nx와 다르게 라이브러리 의존성이 가장 적어서 마음에 들었습니다. 또한 지금것 모노레포 라이브러리 문서중 가장 깔끔하게 정리되어 있어서 사용하기 편했습니다.

다만 아직 Turborepo에 대한 정보가 너무 적고, 라이브러리 모노레포틑 이전에 lerna와 Nx를 사용해보면서 격었던 이슈들때문에 도입해보기가 껄끄러웠습니다.

4. Yarn Berry Workspaces

위에 Lerna, Nx, Turborepo를 사용해보고 나서 느꼇던 점으로는 라이브러리를 사용해서 모노레포를 구축하게 되면 모노레포 라이브러리에 대한 의존성때문에 관리해야할 부분이 늘어난다는 것이었습니다.

그래서 라이브러리를 사용하지 않고, 패키지 매니저의 yarn berry를 사용하여 모노레포를 구축하기로 했습니다.

기존에 작성한 yarn berry에서 yarn berry에 구축 방법에 대해 확인하실수 있습니다.

yarn berry의 특징으로는 zero install을 지원하여, 패키지를 설치할때마다 node_modules에 설치를 하지 않고, yarn의 cache에 저장을 하여 빠르게 설치할 수 있습니다.

zero install을 사용하게되면, 빠르게 설치하고 사용할 수 있긴하지만 모든 패키지를 지원하지 않으며 github에 코드를 올릴경우 파일의 용량이 너무 커지는 문제가 있었습니다.

yarn 버전을 2.X이상 버전으로 올려서 yarn berry를 사용하려고 보니, 기존에 yarn 1.X로 사용하던 프로젝트들을 실행할때 오류가 나왔었습니다. 찾아보니 yarn berry와 node_modules의 구조가 다르기 때문에 오류가 나는 거였는데, 프로젝트마다 yarn 버전을 다르게 사용하게 되면 yarn의 버전 관리가 어려워지는 문제가 있었습니다.

5. PNPM

그래서 yarn berry의 문제점으로 인해서 결국에는 pnpm을 사용하기로 했습니다. pnpm은 yarn berry보다 더 빠르게 패키지를 설치하며, yarn berry에서는 지원하지 않는 오래된 패키지더라도 지원하고 있습니다.

그리고 코드가 실행하기전에 모든 패키지의 무결성 을 확인하여 yarn berry와 같이 기존의 npm과 yarn classic에서 있던 패키지 호이스팅으로 인한 문제를 해결할 수 있습니다.

기존에 작성한 PNPM에서 pnpm 구축 방법에 대해 확인하실수 있습니다.



결론

주기적으로 패키지에 관리에 대한 필요성이 느껴질때마다 모노레포에 대해 찾아보게 되었는데, 결국에는 PNPM을 사용하기로 했습니다.

효율적으로 패키지를 관리하여 효율적으로 디스크를 관리하며 PNPM 밴치마크를 보면 성능 면에서도 상당히 우수한 편입니다.

무엇보다도 모노레포를 구축해서 사용하려면 팀원 모두가 학습을하고, 초기 구축시 많은 시간을 할애해야하는데, pnpm은 러닝 커브가 낮고 구축이 간단하다는 점에서 계속해서 사용하기로 했습니다.