요즘IT
위시켓
최근 검색어
전체 삭제
최근 검색어가 없습니다.

*FEConf2023에서 발표한 <대형 웹 애플리케이션 Micro Frontends 전환기>를 정리한 글입니다. 발표 내용을 2회로 나누어 발행합니다. 1회에서는 HR플랫폼 플렉스(flex) 제품의 기존 문제점과 이를 해결하기 위한 가설 검증을 살펴봅니다. 2회에서는 실제 아키텍처 전환 과정을 살펴보고 성과와 남은 문제점들을 알아봅니다. 본문에 삽입된 이미지의 출처는 모두 이 콘텐츠와 같은 제목의 발표자료로, 따로 출처를 표기하지 않았습니다. 발표자료는 FEConf2023 홈페이지에서 다운받을 수 있습니다.

회원가입을 하면 원하는 문장을
저장할 수 있어요!

다음

회원가입을 하면
성장에 도움이 되는 콘텐츠를
스크랩할 수 있어요!

확인

개발

대형 웹 애플리케이션 Micro Frontends 전환기 (1)

년차,
어떤 스킬
,
어떤 직무
독자들이 봤을까요?
어떤 독자들이 봤는지 궁금하다면?
로그인

*FEConf2023에서 발표한 <대형 웹 애플리케이션 Micro Frontends 전환기>를 정리한 글입니다. 발표 내용을 2회로 나누어 발행합니다. 1회에서는 HR플랫폼 플렉스(flex) 제품의 기존 문제점과 이를 해결하기 위한 가설 검증을 살펴봅니다. 2회에서는 실제 아키텍처 전환 과정을 살펴보고 성과와 남은 문제점들을 알아봅니다. 본문에 삽입된 이미지의 출처는 모두 이 콘텐츠와 같은 제목의 발표자료로, 따로 출처를 표기하지 않았습니다. 발표자료는 FEConf2023 홈페이지에서 다운받을 수 있습니다.

 

FEConf2023에서 발표된 ‘대형 웹 애플리케이션 Micro Frontends 전환기’/김종혁 flex 프론트엔드 엔지니어

 

안녕하세요. ‘대형 웹 애플리케이션 마이크로 프론트엔드 전환기’에 대해 소개하게 된 플렉스 팀의 김종혁입니다. 제가 속해 있는 플렉스 팀은 SaaS 기반 올인원 HR 플랫폼을 만들고 있고, 저는 FE Labs라는 팀에서 프론트엔드 엔지니어로 근무하고 있습니다. FE Labs라는 팀 이름이 특이할 수 있는데, 실험실이라는 이름 그대로 동료 프론트엔드 개발자들이 일을 더 잘할 수 있도록 개발 플랫폼에 관한 업무를 수행하고, 빌드 환경, 인프라 등 제품의 기반이 되는 여러 도구들을 연구하고 개선해나가는 일을 하고 있습니다.

 

이번 글에서는 플렉스 팀이 기존 제품을 마이크로 프론트엔드 아키텍처로 전환했던 8개월간의 과정에 대해서 소개합니다. 왜 플렉스 웹앱을 마이크로 프론트엔드 아키텍처로 전환했는지, 어떤 고난과 역경을 겪었는지 그리고 어떤 방식으로 극복해나갔는지에 대해 이야기하겠습니다.

 

플렉스 팀이 더 잘 일하기 위해, 그리고 더 좋은 제품을 만들기 위해 아키텍처를 바꾸면서 겪었던 그 자세한 내용에 대해 소개하고, 불확실성이 높은 기술을 도입하면서 이를 검증하고 설득하는 과정, 그리고 성공적인 마이그레이션을 위해서 신경 썼던 것들을 위주로 설명하겠습니다.

 

이번 글에서 살펴볼 내용은 다음과 같습니다.

 

1. flex 제품 & 코드 베이스 소개

2. 문제 탐구의 시작

3. Proof of Concepts (PoC)

4. Actions

5. 마이그레이션 완료

 

플렉스

먼저 플렉스 웹 제품에 대한 소개를 드리겠습니다. 글의 제목에서 ‘대형 웹'이라고 했으니 얼마나 큰 서비스인지 보셔야겠죠? 아래 그림이 플렉스의 홈 화면입니다. ‘올인원 HR 플랫폼’이라는 플렉스의 가치관을 표방하는 화면입니다.

 

그림1. 플렉스 홈 화면

 

회사 내 인사와 관련된 여러 가지 복잡하고 손이 많이 가는 업무를 내부 구성원과 HR 관리자가 쉽게 처리할 수 있게 도와줍니다. 이로 인해 본질적으로 회사의 성장에 더 집중할 수 있도록 도와주고 있습니다. 올인원 플랫폼을 표방하는 만큼 기능도 많습니다. 홈 화면의 왼쪽에 위치한 것이 GNB라고 부르는 영역인데, 이 영역을 통해 플렉스 제품의 여러 가지 기능들을 넘나들며 사용할 수 있습니다.

 

저희가 만들고 있는 대표적인 기능들은 아래 그림처럼 아주 다양하고, 인사 업무의 여러 영역을 포함하고 있습니다.

 

그림2. 플렉스가 커버하는 생애주기

 

플렉스 제품은 회사 구성원의 생애 주기에서 일어나는 이벤트를 모두 커버합니다. 다시 말하면 구성원의 입사부터 퇴사까지 일어나는 모든 일을 기능으로 만들고 있습니다. 이것을 플렉스 팀에서는 ‘통합의 경험'이라고 말하고 있습니다. 플렉스는 모든 HR 관련 업무를 효과적으로 처리할 수 있는 올인원 HR 플랫폼을 표방하고, 이를 통해 통합의 경험을 제공합니다. 이는 상당히 중요한 컨셉으로, 통합의 경험이 제품에 어떻게 구현되었는지를 자세히 알아보겠습니다.

 

회사가 신규 구성원을 채용했다면 플렉스를 통해 구성원을 초대하고, 구성원이 정보를 입력하면 플렉스에 기록됩니다. 그러고 나면 근로계약서를 생성해 주는 기능을 활용하여 근로 계약을 합니다. 근로 계약까지 마쳤다면 이제 일을 해야겠죠? 그 구성원은 근무를 하기 위해 플렉스 앱을 통해 출퇴근 시간을 기록하고 휴가를 신청합니다. 일을 했으니 급여일에 급여를 받고 연말에는 연말정산도 플렉스 앱을 통해 진행합니다.

 

이 모든 활동들이 플렉스 제품 한곳에서 일어납니다. 이러한 통합의 경험으로 인해 플렉스 제품은 각각의 앱보다 더 많은 가치를 줄 수 있습니다. 왜냐하면 각 과정에서 발생한 데이터들이 또 다른 기능에서도 사용되기 때문입니다. 구성원의 근로계약 정보와 회사의 근무 정책에 따라 근무 기록을 남기고 이 데이터를 바탕으로 급여 정산까지 할 수 있습니다. 즉, 플렉스를 사용하는 고객사는 하나의 앱에서 복잡한 HR 업무를 손쉽게 처리할 수 있습니다.

 

그림3. 플렉스의 통합의 경험

 

그렇다면 엔지니어 입장에서 이 제품의 특성은 어떨까요? 앞서 설명드린 통합의 경험을 제공하기 위해 도메인과 결합된 여러 가지 데이터, UI, 그리고 코드들이 각 기능 여기저기서 상당히 많이 엮이게 됩니다. 가령 근무 계약 정보를 바탕으로 구성원의 근무 유형이 달라지게 되고, 이를 위해 근무 기능에서 계약한 근무 정책에 대한 데이터가 필요합니다. 또 근무하는 시간에 따라서 급여가 달라진다면 급여 기능에서 근무와 관련된 데이터가 필요합니다.

 

이러한 기능 단위의 엮임은 엔지니어 입장에서는 엔지니어링 난이도를 상당히 증가시키는 지점입니다. 근태, 급여 등의 각 개별 기능 개발 난이도도 복잡해 보이는데, 이게 서로 엮여 있으니 제품의 코드 베이스는 아주 방대해지고 의존성이 복잡해질 수밖에 없습니다. 게다가 이 모든 기능이 하나의 앱을 쓰는 것처럼 인식되어야 하기 때문에 개발 난이도가 더욱 증가합니다.

 

그림4.엔지니어 관점에서의 특성

 

위와 같은 상황을 토대로, 플렉스 제품의 프론트엔드 엔지니어들이 개발하는 앱은 17개의 Next.js 앱이 있었고, 모노레포 위에 앱의 개수 보다 훨씬 많은 공용 패키지를 사용하고 있었습니다. 제품 전체를 다 합치면 200개 이상의 URL과 페이지를 가지고 있고, 모노레포 코드 베이스는 의존성 관련한 파일들을 제외하면 8.7기가 바이트의 용량을 가지고 있었습니다.

 

그림5. 방대한 크기의 기존 플렉스

 

이렇게 제품 하나하나가 엄청 크고 복잡하기 때문에 각 하나의 제품들은 각 제품에 대한 오너십을 가진 디자이너, 엔지니어, PM으로 구성된 스쿼드 조직에서 문제를 풀어나가고 있습니다.

 

그림6.스쿼드 조직

 

 

플렉스의 문제

그렇다면 플렉스 제품에는 무슨 문제가 있었을까요? 기존 아키텍처는 각각 제품에 해당하는 여러 Next.js 앱들이 존재하고 이를 인프라 레벨에서 라우팅해주는 형태였습니다. 아래 그림처럼 time-tracking이라는 URL로 접속하면 근무 앱으로 접속되고, digicon이라는 URL로 접속하면 전자계약 앱으로 접속되는 방식입니다.

 

그림7. 기존 아키텍처

 

처음의 플렉스 앱은 모놀리식 Next.js 앱이었지만 앱이 점점 커짐에 따라 빌드 배포 시간이 아주 오래 걸리게 되었습니다. 이로 인해 앱을 나눠서 개발할 필요성을 느꼈고, 각 스쿼드에서 페이지 별로 앱을 나눠서 개발했습니다. 앞서 설명한 GNB와 같은 모든 앱에 공통적으로 들어가는 UI들은 빌드 과정에 포함해 같이 배포되고 있었습니다. 다시 말하면 페이지 묶음별로 전체 앱이 나눠져 있었다고 보면 될 것 같습니다.

 

이런 아키텍처에는 다음 두 가지 문제가 있습니다.

 

  1. 유저에게 하나의 앱을 쓰는 경험을 전달할 수 없다.
  2. 스쿼드 독립적, 효율적인 개발이 힘들다.

 

하나의 앱을 쓰는 경험을 전달하기 어렵다

첫 번째 문제부터 살펴보겠습니다. 각각의 앱은 모두 HTML, 자바스크립트 번들, CSS와 같은 모든 리소스를 가지고 있고, 다른 앱으로 접속하면 또다시 모든 리소스를 가져오는 형태입니다. 즉, 플렉스 제품 내에서 다른 기능으로 넘어간 것뿐인데, 모든 자원을 다시 가져와야 합니다.

 

그림8. 페이지 이동시 모든 리소스를 다시 준비하는 플렉스

 

물론 페이지에 존재하는 공통 UI들은 다른 앱으로 넘어가도 유지되기도 하지만, 다른 앱의 기능으로 넘어갈 때마다 로딩 서클을 다시 보게 되고, 이전 앱의 기능에서 사용한 기능들도 다시 불러와 사용하게 됩니다. 이런 상황은 최적화와 거리가 멀었고, 하나의 앱을 사용하는 완벽한 경험을 줄 수 없었습니다. 

 

스쿼드 독립적, 효율적인 개발이 힘들다

모든 앱의 빌드에 포함되는 GNB와 같은 UI들도 불편함이 있습니다. 기존 아키텍처에서는 GNB 패키지를 기능 내부 패키지에서 임포트 문을 통해 각 앱들에 모두 넣어주는 형태입니다. 따라서 여러 개의 앱을 한 번에 배포할 때 GNB에 문제가 있다면 해당 버전의 GNB가 포함된 모든 앱을 롤백 해야 했습니다.

 

그림9. 기존 아키텍처의 문제

 

복잡한 UI들이 임포트 문으로 빌드 타임에 통합되는 문제 때문에 각 스쿼드가 독립적으로 개발하기 힘들었습니다. GNB가 수정되면 모든 앱에 영향을 미치기 때문에 한 스쿼드에서 진행한 변경이 너무 쉽게 다른 앱에 영향을 미치게 되는 것입니다.

 

마이크로 프론트엔드 아키텍처

위에서 소개한 두 가지 문제들에 대해 마이크로 프론트엔드 아키텍처가 문제를 해결할 수 있는 가능성이 있어 보였습니다. 저희가 검토한 기술은 모듈 번들러인 웹팩이 플러그인으로 기능을 제공하는 ‘모듈 페더레이션'입니다.

 

모듈 페더레이션

모듈 페더레이션은 마이크로 프론트엔드 아키텍처의 구현 방식 중 하나로, 하나의 앱을 독립적인 배포가 가능한 모듈 단위로 나누어 브라우저의 런타임 시점에 통합하는 방식입니다.

그림10. 모듈 페더레이션

 

이는 빌드 타임이 아닌 런타임에 각각의 분리된 앱을 합치는 방식으로, 분리된 앱들이 각각의 개발 프로세스를 거쳐서 자바스크립트 번들 형태로 배포됩니다. 각각의 마이크로 앱들은 호스트라고 불리는 앱에서 번들 형태로 로드되어 각각 따로 렌더링 됩니다.

 

이러한 아이디어를 활용한다면 앱 단위가 아니라 화면에 보이는 모든 UI들을 컴포넌트 단위로 배포할 수 있게 됩니다. 또, 앱 전환 시 모든 자원을 처음부터 다시 불러올 필요가 없게 되고, 런타임 환경에서 하나의 앱을 사용하는 것처럼 만들 수 있습니다.

 

그림11. 모듈 페더레이션 워크플로우

 

실제 플렉스 앱에서 홈페이지를 예로 들면 아래와 같은 구조라고 생각하면 될 것 같습니다.

 

12. 플렉스와 모듈 페더레이션

 

배포 단위를 호스트, GNB 그리고 홈이라는 3가지로 나누고, 각각의 앱들은 따로 개발되어 빌드, 배포될 수 있는 환경을 만듭니다. 실제 브라우저에서는 앱의 초기 로딩 시에 먼저 호스트가 로드 되고, 호스트가 각각 따로 배포된 UI 컴포넌트인 GNB와 홈을 런타임에 로드하여 렌더링 되는 방식입니다.

 

 

플렉스와 마이크로 프론트엔드

마이크로 프론트엔드, 모듈 페더레이션은 저희가 겪고 있던 두 가지 문제를 모두 해결할 수 있는 솔루션이라고 생각했습니다. 배포 단위는 분할되지만 런타임에 하나의 앱으로 합쳐져 유저에게 하나의 앱을 쓰는 경험을 전달할 수 있습니다. 그리고 배포 단위를 페이지 이하의 단위로 쪼개서 필요한 부분만 개발하고 배포하는 방식으로 바꾼다면 빌드 타임에 통합되는 복잡한 UI로 인해 스쿼드 독립적인 개발이 힘들다는 점을 해결할 수 있습니다.

 

문제 해결 외에 매력적인 장점도 많았습니다. 첫 번째로, 앱 내의 리액트 컴포넌트를 쪼개서 배포 단위를 만들고 번들로 빌드 하여 배포하면 앱 내부에서는 코드 스플리팅을 한 것처럼 자연스럽게  통합할 수 있습니다. 또, iframe과 같은 통합을 위한 수단이나 상태 공유 방법에 대한 고려가 필요 없고, 컴포넌트를 쪼개듯 배포 단위를 쪼갤 수 있다는 점도 장점이었습니다. 플렉스 팀은 배포 단위를 더 잘게 나누고 동시에 하나의 앱을 사용하는 경험을 제공하고자 했고, 이는 굉장히 좋은 선택으로 보였습니다.

 

13. 런타임 통합 마이크로 프론트엔드 아키텍처의 장점

 

PoC ( 검증 )

저희 팀은 모듈 페더레이션 관련 리서치 내용을 바탕으로 모노레포 코드 베이스 안에 아래와 같이 디렉토리를 하나 만들어 실행시켜 볼 수 있는 작은 SPA 앱을 만들어 ‘체험존 개장’이라는 문서를 통해 프론트엔드 엔지니어들에게 공유했습니다. 이 체험존 앱은 모노레포 내부에 있기 때문에 플렉스 제품에서 사용하는 공용 패키지들을 가져와서 사용할 수 있고, 기존 플렉스의 GNB와 유사하게 만들어서 페이지를 이동할 때 모듈이 어떻게 동적으로 로드 되는지, 유저는 어떻게 앱을 사용할 수 있는지에 대한 정보를 제공합니다.

 

14.모듈 페더레이션 체험 앱

 

기존 아키텍처와 모듈 페더레이션

기존 아키텍처에서 모듈 페더레이션을 사용할 수 있는지 확인하기 위해, 기존의 Next.js 앱과 모듈 페더레이션의 궁합을 보는 PoC도 진행했습니다. Next.js에서 모듈 페더레이션을 사용할 수 있게 해주는 플러그인이 있었고, 이를  플렉스 앱에 적용해 봤습니다. 앱이 동작하는 것은 확인했지만, Next.js의 기타 레포지토리에 이슈가 발생했고, 리서치 결과 Next.js에서는 공식적으로 마이크로 프론트엔드 아키텍처에 대해 모듈 페더레이션 방식을 지원할 계획이 없다고 판단되었습니다. 또한 플렉스라는 커다란 서비스를 검증되지 않은 커뮤니티 기반의 플러그인에 의존하는 것은 리스크가 크다고 생각했습니다. 따라서 Next.js와 모듈 페더레이션을 함께 사용할 수 없다는 판단을 내렸습니다.

 

15.Next.js와 모듈 페더레이션

 

Next.js와의 이별, SPA로 전환

플렉스 팀은 마이크로 프론트엔드 아키텍처를 구현하기 위해 Next.js를 뜯어내게 되고, 플렉스 앱을 SSR 없이 CSR만 사용하는 SPA로 전환하기로 결정했습니다. Next.js와 같은 프레임워크를 사용하면서 누릴 수 있는 가장 큰 장점은 SSR를 통해 서버 리소스를 쉽게 활용할 수 있다는 점입니다. Next.js를 사용하지 않으면 당장은 이러한 기능 사용도 힘들어집니다. 그렇다고 마이그레이션 과정에서 SSR을 직접 구현하기에는 시간과 리소스도 부족했습니다.

 

그러나 B2B SaaS라는 플렉스 제품 특성상 Next.js의 SSR 방법의 이점인 SEO 등에 대한 중요성이 적었고, 일부 기능에서만 SSR을 사용했기 때문에 여러 요소를 감수하고 전면 SPA로 전환하는 결론을 내릴 수 있었습니다.

 

16. Next.js 분리

 

아키텍처 변경에 대한 트레이드 오프

물론 아키텍처 변경에 대한 우려도 존재했습니다. SPA로 전환하게 되면 렌더링에 필요한 리소스를 유저의 브라우저에서 로드하기 때문에, 초기 렌더링 속도가 늦어집니다. 즉, LCP(Largest Contentful Paint, 사용자가 URL을 요청한 시점부터 페이지 내에서 시각적으로 가장 큰 콘텐츠를 그리는데 걸리는 시간) 등의 성능 지표에 악영향을 미칠 가능성이 컸습니다. 플렉스 서비스의 유저는 명확한 목적을 가지고 앱을 사용하기 때문에, 앱에 접근하는 초기 렌더링 성능 못지않게 앱을 사용하는 경험도 중요합니다. 따라서 하나의 앱을 사용하는 경험을 제공해 서비스 사용 경험을 매끄럽게 만든다는 목표를 명확하게 정했습니다. SSR 이외의 성능 병목도 이미 제품에서 존재하고 있었기 때문에 성능 개선은 아키텍처 변경과 별개로 진행할 테스크라고 판단했습니다.

 

또, 단기적으로는 SSR을 사용하지 않는 선택을 했지만, 추후에는 필요할 수도 있다는 점을 인식했습니다. 추후에 SSR을 사용하기 위해 Next.js처럼 클라이언트 리소스를 전달하는 서버를 같이 구현하는 방법으로 확장성을 고려하여 아키텍처 변경을 진행하기로 했습니다.

 

17.아키텍처 변경에 따른 트레이드 오프

 

아키텍처 변경에 대한 불확실성과 걱정

검증 단계와 의사결정 단계에서 많은 시간을 사용했지만, 여전히 불확실성은 높았습니다. 모듈 페더레이션에 대한 기술 레퍼런스가 부족했고, 널리 검증된 기술이 아니었기 때문에 예상한 그대로 동작한다는 보장이 없었습니다. PoC를 통해 모든 위험을 해소했다고 할 수도 없었습니다.

 

이러한 걱정은 ‘플렉스 팀이 도입하는 것은 모듈 페더레이션이 아니라 마이크로 프론트엔드다', ‘앞으로 플렉스 앱은 계속해서 커질 것이기 때문에 결국 우리 제품은 마이크로 프론트엔드라는 구조로 가야 한다' 와 같이 목표를 명확히 인식하는 것으로 극복했습니다. 즉, 모듈 페더레이션이 실패하더라도 다른 방법을 찾아서 적용하면 된다고 생각하면서 아키텍처 변경을 계속해서 진행할 수 있었습니다.

 

그리고 의사 결정 트리를 만들어 계획이 잘 되었을 때는 계속해서 진행하고, 실패했을 때는 다른 방법을 찾을 수 있도록 했습니다. 즉, 대안을 미리 세워두고 팀원들과 공유하는 방법으로 업무를 가시화 하였고. 이 의사 결정 과정에 따라 실패 하게 되면 빨리 다른 방법을 찾을 수 있도록 로드맵을 설정하여 진행했습니다.

 

다음 글에서는 위 검증을 바탕으로 실제 마이크로 프론트엔드 마이그레이션 실행 과정에 대해 알아보겠습니다.

 

FEConf

편집 오신엽 객원 에디터

좋아요

댓글

공유

공유

댓글 0
FEConf
485
명 알림 받는 중

작가 홈

FEConf
485
명 알림 받는 중
프론트엔드 컨퍼런스 FEConf 공식 계정입니다.

좋아요

댓글

스크랩

공유

공유

지금 회원가입하고,
요즘IT가 PICK한 뉴스레터를 받아보세요!

회원가입하기
요즘IT의 멤버가 되어주세요! 요즘IT의 멤버가 되어주세요!
요즘IT의 멤버가 되어주세요!
모든 콘텐츠를 편하게 보고 스크랩해요.
모든 콘텐츠를 편하게 보고 스크랩 하기
매주 PICK한 콘텐츠를 뉴스레터로 받아요.
매주 PICK한 콘텐츠를 뉴스레터로 받기
로그인하고 무료로 사용하기