Journey of a Frontend Monorepo: Here’s What I Learned
이 글에서는 Jotform에서 프론트엔드 아키텍처를 재구성하면서 배운 점에 대해 이야기합니다.
저희는 애자일 크로스 기능 팀을 보유하고 있으며, 트렁크 기반 개발 접근 방식을 따르고 있습니다. 즉, 메인 브랜치에 직접 업데이트를 푸시하고 있습니다. 메인 브랜치는 항상 프로덕션 준비가 되어 있으며 자동화된 테스트를 통해 보호됩니다. 저희의 규모를 고려할 때, 프로덕션 환경은 하루에 거의 300번 업데이트됩니다.
예전에는 모든 애플리케이션에 대해 서로 다른 레포지토리를 만들고 공유 라이브러리를 위해 몇 개의 레포지토리를 더 만드는 폴리레포 구조를 사용했습니다. 모든 레포지토리에는 고유한 구성이 있었습니다. 레포지토리에 소유자가 있는 경우 별도로 관리하기에 좋았습니다. 우리 회사는 빠르게 성장하고 있었기 때문에 레포지토리 소유권을 잘 관리하지 못했습니다. 팀에 더 많은 개발자를 포함시키다 보니 문제가 생겼습니다. 가장 먼저 직면한 문제는 다음과 같습니다.
- 일관성 없는 툴링: 여러 개의 린터, 웹팩, 테스트 및 Github Action 구성이 있었습니다. 서로 다른 레포지토리에서 비슷한 작업을 수행했고 여러 빌드 파이프라인을 사용했습니다.
- 개발 환경의 차이: 모든 팀이 각자의 노력으로 프로젝트의 개발 종속성을 관리했습니다.
- 공유하기 어려운 코드: 여러 팀과 프로젝트에서 코드를 공유하는 것을 목표로 했기 때문에 다른 공유 레포지토리 내에 공통 컴포넌트와 유틸리티를 만들었습니다. 보통 개발 중에 웹팩 구성에서 모듈을 연결하고 다른 애플리케이션에서 사용할 수 있도록 패키지를 비공개 레지스트리에 게시했습니다. 이 과정은 매우 느리고 힘들었기 때문에 코드 중복이 많이 발생했습니다.
- 버전을 관리할 수 없습니다: 코드 공유를 위해 비공개 npm 패키지를 만들고 있었습니다. 공유 라이브러리에 업데이트가 발생하면 모든 애플리케이션을 개별적으로 업데이트했습니다. 하나의 패키지 업데이트를 위해 40개 이상의 서로 다른 레포지토리를 업데이트하는 등 종속 애플리케이션 수가 매우 빠르게 증가했습니다. 안타깝게도 업데이트를 잊어버리거나 일부 애플리케이션을 업데이트하지 않는 경우가 많았습니다. 그 결과 사용자들은 애플리케이션마다 동일한 컴포넌트에 대해 서로 다른 UI를 보게 되었습니다. 이는 사실 트렁크 베이스 개발 접근 방식을 깨는 것이었습니다. 사용 빈도가 낮은 앱을 잊어버리면 해당 앱은 몇 주 동안 오래된 패키지를 사용하게 됩니다.

<aside>
💡 공통을 수정하는 경우 전체에 적용하기까지 많은 시간이 소요되는 구나
</aside>
- 영향을 받는 애플리케이션을 파악하기 어려움: 개발자가 컴포넌트 라이브러리를 업데이트하면 회사 전체에서 영향을 받는 모든 애플리케이션을 확인하기 어려웠고, 이로 인해 대개 기능이 중단되는 경우가 발생했습니다.
- 하드 모드 온보딩: 신규 입사자는 여러 코드베이스에서 관련 컴포넌트를 찾는 데 어려움을 겪었습니다.