Lee Seona
NAVER Pay Dev Blog
Published in
9 min readMar 7, 2024

--

안녕하세요, 네이버페이 내자산&회원FE에서 프론트엔드 개발하는 이선아입니다.

저희 팀이 담당하는 일은 원용님의 아래 글에 잘 정리되어 있습니다.

내자산: 마이데이터 자산 조회 by wonyong01.kim

이 글에서는 코드 관리의 관점에서, 모노레포에 대해 간략히 알아보고 기존에 있던 두 레포를 하나로 통합하는 과정과 진행하면서 생겼던 고민거리와 느낀 점을 공유하려 합니다.

개편 이전의 코드 관리

저희 팀에서는 내자산 서비스뿐만 아니라, 신용점수, 송금, 간편결제 등의 서비스도 담당하고 있는데, 각 서비스에서 다뤄야 할 기능이 많다 보니 서비스 별로 레포를 분리해서 코드를 관리하고 있습니다.

그리고 공통으로 사용해야 하는 부분을 패키지로 뽑아 패키지용 레포를 따로 두고 있었습니다. 패키지에는 범용적으로 사용되는 코드를 모아둔 utils 패키지나 원용님께서 설명해 주신 Session IO를 사용하기 위한 패키지 등이 있습니다.

저희 팀에서 관리하는 레포가 늘어나다 보니, 패키지만 따로 뽑아둔 레포는 개발 스택 업데이트에서 누락되는 등 관리가 안 되는 문제가 발생했습니다. 서비스 코드 작업이 더 급하다 보니 패키지 코드 개선은 후순위로 밀리는 경우가 많았습니다.

또한 패키지는 카나리 배포를 해야 코드 동작을 확인할 수 있다보니, 작업을 위한 컨텍스트 스위칭에 피로도가 높아졌습니다.

결정적으로 배포 프로세스가 변경되었는데 패키지 레포에서도 이를 새로 적용해야 했고, 이전의 불편사항을 개선하기 위해 패키지 레포와 서비스 레포를 합쳐 모노레포로 관리하기로 결정했습니다.

모노레포란?

잠깐 모노레포에 대해 설명하자면, 여러 프로젝트의 코드를 하나의 레포에서 저장, 관리하는 소프트웨어 개발 전략을 뜻합니다.

기존에도 패키지들을 하나의 레포에서 관리하고 있었으니 해당 레포는 모노레포 전략을 취하고 있었다고 볼 수 있습니다. 이전에 패키지들만 모아서 관리하던 레포에서 패키지들을 옮겨와 하나의 레포에서 코드를 관리할 수 있도록 변경했습니다.

Repo before & after

turbo repo란?

모노레포를 구성하기 위해서 저희는 turbo repo를 사용했습니다.

turbo repo는 자바스크립트 또는 타입스크립트로 된 프로젝트를 대상으로 하는 고성능의 빌드 시스템입니다.

turborepo

모노레포를 구성하는 많은 방법 중에서 선택할 때에 저희의 기준은 두 가지였는데요, 적용 및 사용하기 어렵지 않을 것과 빌드 속도가 크게 저하되지 않을 것이었고, 결론적으로 저희 팀은 만족하며 사용하고 있습니다.

turbo repo 알아보기

turbo repo 사용법을 간략하게만 설명하려 합니다. turbo에서는 `turbo.json` 파일에서 설정을 명시하여 사용합니다.

{
"$schema": "https://turbo.build/schema.json",
"pipeline": {
"build": {
"cache": false,
"dependsOn": ["^build"]
},
"deploy": {
"cache": false,
"dependsOn": ["^build"]
},
"start": {
"dependsOn": ["^build"]
},
"lint": {}
}
}

pipeline은 turbo로 실행할 스크립트의 이름을 키로 가지는 객체입니다. `turbo run`으로 실행할 수 있으며 각 package.json에서 일치하는 스크립트가 있으면 실행시켜줍니다. 예를 들어 `turbo run build`를 실행하면 레포 내의 모든 패키지와 서비스를 빌드 할 수 있습니다.

pipeline 별로 설정을 다르게 할 수 있습니다. turbo에서는 빠른 실행을 위해 캐싱을 지원하고 있는데, 스크립트를 실행한 결과를 저장해두어 다시 실행했을 때에 캐시 되어있던 결과가 있다면 그대로 사용합니다. 프로젝트를 빌드 할 때에는 캐싱 된 결과를 사용하지 않도록 cache로 설정을 제어할 수 있습니다. 스크립트 간에 의존성이 있을 경우에는 dependsOn으로 설정합니다.

패키지 이관하기

패키지 레포에 있는 코드들을 이관하고 turbo로 실행할 수 있도록 스크립트를 정리해 주었습니다.

그리고 패키지 매니저인 pnpm에서 제공하는 기능으로, 서비스 코드에서 배포된 버전이 아닌 같은 레포에 있는 코드를 바라볼 수 있도록 package.json을 수정해 주었습니다.

{
// ...
"dependencies": {
"@mydata/packageA": "workspace:*",
"@mydata/packageB": "workspace:*"
}
}

배포 프로세스 정리하기

코드 이관 후에는 github actions를 이용하여 패키지 버전관리와 배포 프로세스를 정리했습니다. 우선 패키지의 버전 관리와 changelog 작성을 쉽게 하도록 도와주는 Changesets를 도입했습니다.

Changesets

Changesets를 활용한 버전 관리 과정을 짧게 설명하면, PR 생성 시에 패키지에 변경사항이 있는지를 감지하여 코멘트를 달아줍니다.

코멘트에서 major, minor, patch 중 어떤 버전을 bump할 것인지 선택하고 changelog를 작성하면 임시 파일을 추가해 줍니다. 해당 PR이 특정 브랜치인 develop에 머지 되면 이를 감지해서 임시파일의 내용으로 버전 업데이트와 changelog를 추가하여 새로운 PR를 생성해주며, 패키지 작업이 모두 완료되었을 때에 작업자가 머지합니다.

여기에 나아가서 develop에서 패키지 버전에 변경이 있었을 때에 자동으로 publish를 실행하도록 했습니다. 배포가 정상적으로 완료되면 메신저로 알람을 보내 배포 결과를 공유합니다. 작성한 publish actions 코드를 발췌한 내용입니다.

name: Release Publish

on:
push:
branches:
- develop

jobs:
publish:
runs-on: air-fe

steps:
- name: Checkout Repo
uses: actions/checkout@v2

- name: install dependencies
run: pnpm install --frozen-lockfile

- name: Create Release Pull Request
id: changesets
uses: common-fe/changeset-actions@main
with:
title: "🚀 version changed packages"
publish: pnpm run publish

- name: Publishing success!
if: steps.changesets.outputs.published == 'true'
uses: actions/github-script@v6
with:
script:
# 배포 성공한 경우 사내 메신저인 works 발송

마지막으로, 작업 중 카나리 배포를 쉽게 할 수 있도록 PR 코멘트에서 canary-publish를 인식하여 카나리 배포를 자동화했습니다.

자동화 작업할 때에는 한주님이 작성해 주신 FinFE Bot을 많이 활용했습니다. 처음 소개해 주신 글보다 지금은 더 많은 기능을 고도화하여 제공하고 있지만, 읽어보시면 자동화에 대한 인사이트를 얻을 수 있습니다!

반복적이고 귀찮은 일은 Bot에게! by 이한주

불편한 점 개선하기

배포 프로세스까지 정리하고 나니 “해야 하는 일”은 다 끝난 상태였고, 약간의 불편한 부분이 남은 상태였습니다.

첫 번째로 CI/CD에 걸리는 시간이 길어진 것이었습니다. PR 생성 시에 작성한 코드에 이상이 없는지 확인하는 CI가 걸려있는데, 코드를 모두 빌드 하는 단계가 포함되어 있었습니다. 패키지에 비해 서비스 빌드 시간이 더 길었는데, 패키지 코드를 조금만 고쳐도 긴 서비스 빌드 시간을 기다려야 했습니다.

이런 문제를 해결하기 위해서 빌드 스크립트를 분리하고 패키지 변경 시에는 서비스 코드에 대한 테스트를 건너뛸 수 있도록 github actions를 보완했습니다.

두 번째로는 브랜치 관리가 이슈가 되었습니다. 패키지 코드 작업과 서비스 코드 작업에 의존 관계가 있어서 문제 되는 부분이 있었습니다.

처음에는 패키지 수정 시에 패키지 쪽만 수정해서 PR을 작성하여 changelog에서 쉽게 확인할 수 있도록 하려 했는데, 서비스 코드에서 이를 참조하고 있어서 에러가 발생할 수 있습니다. 브랜치가 잘못 관리 되면 다른 브랜치로 에러가 전파될 수 있어서 브랜치 관리 전략을 새로 논의해야 했습니다.

장단점 분석해보기

모노레포로 전환하고 몇 달간 사용해 보면서 느낀 장단점을 분석해 봤습니다.

장점은

- 한 레포에서 관리하다 보니, 패키지 작업이 수월해졌습니다.
- 개발 스택 업데이트할 때에 누락되는 경우가 적어졌습니다.
- 코드 검색과 관리가 쉬워졌습니다.

단점은

- 브랜치 관리 방법이 더 복잡해졌습니다.
- 팀원 모두 빌드 시스템에 대한 공부가 더 필요했습니다.

전체적으로 봤을 때에 코드 작업 측면에서는 모노레포를 사용하는 것이 유리하지만, 환경 설정이나 브랜치 관리가 복잡하여 피로해진 부분도 있었습니다.

마치면서

작업 착수 전에는 코드 이동만 하면 되려나 했는데, 실제로 작업하면서는 빌드 시스템부터 github actions까지 다양하게 공부해 볼 수 있었습니다.

제 경험기가 모노레포 전환을 고려하시는 분들께 조금이나마 도움이 되었으면 좋겠습니다.

이번 모노레포 전환 작업을 진행하면서 시행착오도 많이 하고 고민도 많이 하면서 한 뼘 더 성장할 수 있었습니다. 작업 중 막힐 때마다 함께 고민해 주신 팀원분들 덕분에 무사히 마무리할 수 있었습니다.
저희 네이버페이 내자산&회원FE에서는 팀원들의 지속적인 성장을 독려하고 있습니다. 저희와 함께하실 열정적인 분들을 언제나 기다리고 있습니다!
채용: https://recruit.naverfincorp.com/

--

--