logo
PostsInvestingHomebarArticlesAbout

내가 왜 모노레포를 적용했었나?

2023.06.19 / 10min

Intro

지금은 다니고 있지 않은 직장이지만 많은 걸 고민하고 적용하려고 한 서비스가 있다. 그 당시에 고민한 것은 많았는데 기하지 않으니 잊히고 있었다. 시간이 더 가기 전에 정리해보려고 한다.

이번에는 내가 왜 모노레포를 적용하려고 했는지 작성해보려고 한다.


TOC

모노레포(monorepo)가 떠올랐다.

2021년 11월 한창 코로나로 운영하던 서비스가 양수가 아닌 음수의 수익으로 전환이 되면서 내부적으로 많은 일들이 있었다. 이에 프론트엔드 개발자로는 혼자 남게 되었는데 새로운 서비스도 피벗 해야 하는 일이 생겼다.

오히려 이 시기는 기회라고 생각하고 새로운 것을 많이 해보려고 했다.

약간의 반항(?)으로 이전에 사용하던 Vue를 버리고 React를 사용하려고 했으나, React를 너무나 많이 사용하던 시기에 나는 React 말고 Preact를 실서비스에 적용해서 선두 주자가 될 거야 라는 꿈을 품고 시작하였다. 역시나 나중에 꿈은 접고 Next.js를 도입해서 더 개발하기 좋은 환경으로 변경되었다^^

피벗팅에 성공하여 서비스를 제대로 만들려고 하면서 나중에 어떻게 프로젝트가 커지게 될까 생각해봤다. 현재은 임대인을 위한 서비스이지만 시간이 지날수록 임차인, 중개인을 위한 서비스가 만들어질 것을 생각할 수 있었다.

더불어 Preact + Multi Repo(Design System, 임대인 서비스)로 구성하였더니 혼자서 레포를 옮겨가면서 개발, 배포, 적용하는 과정이 기능을 만드는 데 엄청난 시간을 낭비한다는 걸 알게 되어 이걸 쉽게 관리하면서 개발할 수 있지 않을까 라는 생각했다.

이런 생각을 하는 와중에 Toss의 아키텍쳐발표를 보고 모노레포에 대해서 관심을 가지게 되었고 당장 내가 적용할 수 있는 Tools를 찾아봤다.


모노레포(monorepo)는 무엇인가?

모노레포(monorepo) 구조는 두 개 이상의 프로젝트가 같은 저장소에 저장되는 소프트웨어 개발 전략이다. 분리된 모듈들은 모노레포에서 여전히 독자 프로젝트로 존재하지만, 저장소는 같은 곳을 사용하는 것이다.


경험기반 모노레포 장단점

모든 내용은 경험기반으로 작성되어서 부족한 면이 있을 수 있습니다.

임대인 서비스가 이미 만들어져 있었다. 여기에 추가로 임차인, 중개인, 어드민 프로젝트가 추가되었을 때, 기존에 느껴보지 못한 속도감을 느낄 수 있었다. 프로젝트가 추가될 때마다 하던 초기 세팅과 컴포넌트 구성을 하지 않고 이미 만들어진 세팅과 컴포넌트 사용이 가능했다.

세팅, 컴포넌트뿐만 아니라 Type, Util, API등 동일하게 쓰이는 모든 코드가 공유될 수 있었다.

프로젝트를 운영하고 리팩토링하는 과정에서 잘못되는 것을 확인, 수정하게 되면 사용되는 곳에 동일하게 반영되어 버그가 해결될 수 있다. 그러나 버그를 해결할 수도 있지만 다른 문제를 야기하는 일도 있었다.

만약 멀티레포로 가져가게 되었다면, 개발하는 데 필요한 레포들에 하나하나 커밋을 해야하지만 모노레포로 가져가게 되면서 관련된 작업을 하나의 커밋으로 만들어서 관리할 수 있다.

서로 같은 코드 베이스에서 일하고 있으므로 변경 사항이 있거나 협업할 일이 있으면 보다 유연하게 코드를 관리할 수 있었다. 임대인 서비스 관련된 코드이지만 임차인과 동일에도 동일하게 적용할 때에 서로 물어보면서 문제가 있으면 같이 해결할 수 있는 구조를 가져갈 수 있다.

몇 가지 아쉬운 점도 있었다.

개발, 실행에 필요한 환경을 구성하는데 투자해야 한다. 모노레포에서는 디펜던시를 추가하는가 쉽다 보니, 별생각 없이 라이브러리를 다운받고 그냥 놔두거나, 옛날에 썼지만 어쩌다 보니 안 쓰게 된 디펜던시들이 많이 생겨서 주기적으로 관리할 필요가 있었다.

서비스, 시스템, 모듈, 컴포넌트 등의 소유권은 단일 개발팀에 속해야 한다고 생각하는 개발자도 있다. 각 코드에 대한 소유권, 변경 사항에 대한 책임이 모두 소유자에게 있도록 하는 것이 코드 관리에 더 도움이 된다는 뜻이다. 그러나 구글에선 장점이라고 했던 유연한 소유권이 코드 관리를 더 어렵게 할 수도 있다는 의견이 있다. 개인적인 경험으로도 소유권이 애매해져서 문제가 생기면 내가 고치는 일이 많아지기도 했다.


그래서 무엇을 사용했나?

현재를 기준으로는 모노레포를 구성할 수 있는 라이브러리들이 많다. 처음에는 yarn workspace를 사용해서 구성하려고 생각했으나 현실적인 어려움이 있어서 사용하지 못했다.

피벗팅 이후 실서비스 런칭 이후 빠른 속도로 다른 서비스(임차인, 중개인 등)를 구성해서 만들어야 했다. 이에 나에게 주어진 시간은 1~2주였다. 그러다 보니 주어진 상황을 만족할 라이브러리를 선택해야 했다.

그전에 몇 가지 라이브러리에 대해서 간단하게 살펴보자.

Nx

  • 다양한 시각화 기능을 제공한다(graph, affected 등등).
  • CLI를 통해서 패키지 구성이 쉽다(Next.js, NestJS 등 여러 패키지를 사용할 수 있다).
  • workspace 생성 시 Cypress, Jest 등을 기반으로 한 테스트 환경까지 설정해 준다.
  • Cloud 서비스를 통해서 빌드 캐싱을 제공한다.
  • 해치를 벗어나는 순간 아주 힘들다.

Yarn Workspaces

  • 나에게 맞는 워크플로우를 구성할 수 있다.
  • yarn의 내장 기능이기 때문에, 별도의 설치가 필요없어 사용하기가 용이하고, 러닝커브도 거의 없는 편이다.
  • 패키지의 의도하지 않은 호이스팅을 허용하지 않을 수 있다.
  • 완전 초기에 세팅과 설정에 할 일이 많다.

Turborepo

  • 증분 빌드(incremental build)가 가능하다.
  • 원격 캐싱, 병렬 처리 기법을 통해 빌드 성능을 끌어올릴 수 있다.
  • Pipeline의 쉬운 설정과 profiling, trace 등 다양한 시각화 기능을 제공한다.

후기

결국 혼자서 모노레포를 구성하고 쉴틈없이 여러 프로젝트를 추가해 개발해야 하는 상황이다. 그래서 제일 중요하게 생각했던건 쉽게 구성할 수 있는지와 개발의 편의성이었다. 이에 Nx를 사용했다.

Nx를 사용하면서 CLI를 통해서 React, Next.js App을 구성하고, 임대인 서비스내에 있는 임대장부, 커뮤니티와 같은 기능을 Package로 구성했다. 이걸 모두 CLI만으로 구성하고 이전하였다.

이후 추가되는 임차인과 중개인 서비스가 생기는 경우도 CLI만으로 만들 수 있었으며, 디자인시스템과 같은 공통 패키지도 쉽게 구성하였다. 또한 graph, affected 같은 기능으로 의존성을 분석해서 문제가 되는 부분을 쉽게 찾아서 해결할 수 있었다.

그러나 시간이 지나고 여유가 생기게 되어서 Lint와 같은 것을 커스텀하려고 햐고 하거나 Nx에서 지원하지 않는 플러그인을 사용하려는 경우(Next.js 최신 버전을 지원하지 않는 경우가 있었다) 아쉬웠다. 나중에 다시 모노레포를 구성해야한다면, Nx가 아닌 다른 것을 사용해보려고 한다.


Reference


avatar
snyungSoftware Engineer(from. 2018)
social-mailsocial-githubsocial-facebooksocial-book