작업배경

현재 사용하고 있는 프로젝트는 MSA 구조로 되어있었다. Platform 공통 사용 레포가 있고, FE 에서 개발하는 서비스 공통 Component 레포가 있고, 이것을 사용하는 서비스 레포로 계층적인 구조로 나뉘어 있었다.

이렇게 레포들을 나눠놓고 내부 패키지로 배포해서 사용하는 구조로 작업하면, 코드 격리성은 매우 높아지지만 여러 레포를 이동해가며 관리해야 한다는 점이 불편하게 느껴졌다. 패키지 버전 관리 또한 따로 해주거나 복붙해서 관리해야 하며, 하물며 배포하는 CI Script 또한 틀은 거의 비슷하지만 별도로 관리해야 한다.

제일 중요도를 높게 잡았던 개발 생산성 측면에서도 비효율적인 부분이 존재한다. FE 에서 개발하는 서비스는 Role 별로 구분되어 있는데 Role 별로 약간의 특별한 기능이 있거나 제한되는 기능이 있는 걸 제외하면 중복되는 컴포넌트나 기능이 많은 것을 확인할 수 있었다. 이런 부분의 코드도 역시 서비스별로 다 따로 작성해서 로직을 만들어 줘야 한다.

위와 같은 여러가지 문제점 들로 인해, MSA 구조를 거의 찬양하다 시피 했던 시절에는 몰랐던, 속사정을 직접 겪고나니 프로젝트를 이전 해야겠다는 다짐이 섰고, 한번에 모든 프로젝트를 묶기 전에 최상위 레벨의 서비스들 부터 migration 해보고자한다.

Workspace Tool 정하기

Monorepo 를 만드는데 도움을 주는 Tool 은 여러가지가 있다. 시초격인 Lerna, 최신 Monorepo 도구인 Nx, Pants, Turborepo(Vercel) 등 여러가지가 있었는데, 우선 몇가지를 정해서 문서를 읽어 보았다.

Lerna 는 Nrwl 이라는 Nx 를 만든 회사에 인수되었다고 한다. Lerna 가 어떻게 안정적으로 유지보수 될지 모르기 때문에 보류 했다.

Nx 는 최신도구 이며 거의 All-in-one 으로 사용할 수 있게 많은 기능들이 있고 분산 캐싱 등의 강력한 기능을 제공한다. 하지만, 사용은 간단하나 구체적인 이해에 러닝커브가 있고 Nx 도구에 너무 의존적인 구조라 만일의 사태에 레포를 옮겨야 할 경우 비용이 클 것 같아 선택하지 않았다.

그래서 결정한 도구는 Yarn Workspace & Berry 로 정했다. Yarn & Lerna 도 많이 사용하지만, 가장 진입장벽이 낮으면서 심플하게 구성이 가능하면서 CI 구성도 어렵지 않게 기존 구성을 활용할 수 있을 것으로 보여서 결정했다. 팀원들의 프로젝트 On-boarding 시간을 최소화 하기 위한 결정이라고 봐도 될 것이다.

Project 구조

root
	packages
		core
		component
		service1
		service2
		service3

Yarn workspace 는 package.json 에 workspace 구문을 추가하면 쉽게 공간 설정이 가능하다. 때문에 기초적인 구성에 드는 시간이 적었고, 빠르게 테스트 해볼수 있었다.

작업이슈

Yarn Berry 이슈

Berry 로 구성할 때 가장 좋은 부분은 plug & play 기능인데, 프로젝트가 너무 의존성 트리가 깊게 연관되어 있어 의존성 관련 에러가 많이 나왔다. 그래서 프로젝트 세팅에 시간을 많이 잡아먹을것 같아 우선 nodeLinker: node-modules 옵션을 사용하여 pnp 기능은 다음 milestone 으로 넘기기로 했다.

Vite 이슈