(번역)Benefits of Module Federation in a Monorepo

김형태·2025년 2월 11일

module federation 번역

목록 보기
1/2

원문: https://module-federation.io/practice/monorepos/index.html

Module Federation은 애플리케이션 간 코드를 공유할 수 있게 해주는 강력한 도구다. 이를 통해 더 모듈화되고, 유지보수가 용이하며, 확장 가능한 애플리케이션을 구축할 수 있다. 이 가이드에서는 모노레포(Monorepo)에서 모듈 연합을 사용하는 이점에 대해 살펴본다.

마이크로 프런트엔드 개발에서 조직적 문제를 해결하기 위해 다중 저장소(Polyrepo)가 오랫동안 표준으로 사용되어 왔다. 그러나 다중 저장소는 코드 공유, 종속성 관리, 버전 관리, 팀 자율성 등의 측면에서 더 많은 조직적 문제를 유발한다.

마이크로 프런트엔드를 통해 팀 자율성을 높이려는 시도는 본의 아니게 다중 저장소 구조를 지향하게 했다. 각 팀이 자체 저장소를 보유하며, 고유 코드베이스를 관리하도록 하는 방식은 협업 부족과 투명성 결여를 비롯한 다양한 문제를 야기했다.

모노레포를 선택하면 여러 저장소를 관리할 필요 없이 모듈 연합의 모든 이점을 누릴 수 있을 뿐 아니라, 코드 공유와 종속성 관리 측면에서 추가적인 이점도 얻을 수 있다. 이 가이드는 모노레포에서 모듈 연합을 사용하는 이점을 이해하고, 이러한 방식이 조직적 문제를 어떻게 해결하는지 설명한다.


Potentail Drawbacks of a Polyrepo Approach

팀에게 완전한 독립성은 매우 매력적일 수 있지만, 특히 Module Federation과 함께 사용할 경우 여러 한계와 문제를 동반한다. 모듈 연합 시스템을 사용할 때, 최종적으로 사용자에게 제공되는 결과물이 단일 애플리케이션이라는 사실을 잊기 쉽다. 따라서 단일 애플리케이션을 구성하는 Polyrepo들이 기술적 결정에서 완전한 독립성과 자율성을 가지게 되면, 사용자에게 전달되는 최종 경험에서 일관성이 부족해질 수 있다.

이제 폴리레포 방식에서 발생하는 다른 문제들에 대해 살펴보자.

Feedback Loops

Polyrepo 방식은 투명성과 피드백 루프 부족을 초래할 수 있다. 이는 특히 Module Federation 시스템을 사용할 때 더욱 문제가 될 수 있다.

한 팀이 애플리케이션의 자신이 맡은 부분을 변경하면, 해당 변경 사항이 애플리케이션의 다른 부분에 어떤 영향을 미칠지 이해하기 어려울 수 있다. 런타임 문제나 호환성 깨짐(breaking changes)에 대한 알림은 배포가 이루어진 후에야 발견될 수 있다.

프로덕션에 도달하기 전에 변경 사항의 안전성을 보장하기 위한 품질 보증 프로세스가 마련되어 있더라도, 피드백 루프가 느리고 방해를 초래할 수 있다. 이는 팀이 새로운 기능을 추가하는 대신 변경 사항을 되돌리거나 발생한 문제를 빠르게 수정해야 하는 상황에 놓이게 만들 수 있다.

Shared Code Strategies

Polyrepo 간의 코드 공유는 어렵다. 이는 대개 어떤 형태로든 사설 패키지 레지스트리를 생성하고 유지관리하는 작업을 수반한다. 공유 코드는 빌드되어 이 레지스트리에 배포되고, 다른 Polyrepo에서 이를 사용한다. 공유 코드에 변경이 생기면 반드시 레지스트리에 릴리스해야 한다.

이는 시간이 많이 걸리고 오류가 발생하기 쉬운 과정이다! 특히 공유 코드의 PR(풀 리퀘스트)을 레지스트리에 릴리스해야만 작업을 진행할 수 있는 팀이 있을 경우, 새로운 기능 개발에 장애물이 될 위험이 있다.

또한 피드백 루프 문제로 다시 돌아가게 된다. 팀들은 레지스트리가 업데이트될 때까지 기다려야만 자신들의 변경 사항이 어떤 영향을 미치는지 확인할 수 있으며, 경우에 따라서는 팀 간 격리로 인해 그 영향을 전혀 확인하지 못할 수도 있다. 이는 다른 팀에 영향을 미치는 호환성 깨짐(breaking changes)을 무심코 도입하게 만들 수도 있다.

공유 코드를 사용하는 팀 또한 사용 중인 공유 패키지의 버전을 적극적으로 업데이트해야 모듈 연합 시스템 내에서 호환성을 보장할 수 있다. 그렇지 않으면 런타임에서 호환성 깨짐 문제가 발생할 위험이 있다.

Dependancy Management

Polyrepo는 종속성 관리 문제를 야기할 수도 있다. 각 팀이 독립적으로 자신들의 저장소에서 작업할 경우, 서로 다른 종속성을 사용하거나 종속성의 버전이 다를 수 있다. 이는 충돌, 버전 관리 문제, 또는 중복된 종속성으로 인한 번들 크기 증가와 같은 더 심각한 문제를 초래할 수 있다.

예를 들어, 한 팀이 React 18을 사용하고 있는데 다른 팀이 React 19로 업데이트하기로 결정했다고 가정해보자. 이러한 변경 사항이 프로덕션에 배포되면, 애플리케이션의 다른 부분이 React 19를 지원하지 않을 경우 코드의 호환성 문제가 발생하거나 런타임 오류가 발생할 가능성이 크다.

Polyrepo 환경에서는 React 19로의 업데이트가 다른 팀의 작업을 방해할 수 있다는 점을 즉각적으로 알리지 않는다. 이는 많은 좌절감을 불러일으킬 수 있으며, 변경 사항을 되돌려야 하는 상황으로 이어질 수 있다.

Testing Strategies

팀들이 서로 독립적으로 작업할 경우, 동일한 테스트 전략이나 도구를 사용하지 않을 수 있다. 이는 시스템 전반에서 테스트의 일관성을 떨어뜨려 애플리케이션의 전체적인 품질에 문제가 생길 수 있다.

또한 QA 프로세스를 더 어렵게 만든다. QA 팀은 각각의 마이크로 프런트엔드를 개별적으로 테스트하거나, 모든 마이크로 프런트엔드를 통합하여 테스트해야 한다.

개별 마이크로 프런트엔드를 테스트하는 것은 애플리케이션 전체 품질에 대한 동일한 수준의 신뢰를 제공하지 못한다. 통합 지점이나 공유 컨텍스트를 테스트하지 않기 때문이다.

이 방법은 또한 애플리케이션 전체의 특정 레이어를 모킹(Mock)할 수 있는 테스트 프레임워크를 구축해야 한다는 것을 의미하며, 이 테스트 프레임워크가 애플리케이션의 다른 부분과 동기화되도록 유지보수해야 하는 부담을 초래한다.

반면, 애플리케이션 전체를 테스트하면 더 높은 수준의 신뢰를 제공할 수 있다. 그러나 Polyrepo 환경에서는 각 마이크로 프런트엔드의 최신 버전을 배포할 수 있는 설정 가능한 테스트 환경을 구축해야 한다. 이는 시간이 많이 소요되고, 클라우드 자원에 비용이 들며, 테스트 중 발생한 문제에 대한 피드백이 지연되어 전체적인 반복 속도가 감소하는 결과를 초래한다.


How does a Monorepo address these drawbacks?

모노레포(Monorepo)는 프로젝트의 모든 코드를 하나의 저장소에 담는 방식이다. 이는 프로젝트 전체에 대한 단일한 진실의 출처(single source of truth)가 된다. 앞서 언급한 각 문제를 자세히 살펴보고, 모노레포가 이를 어떻게 해결할 수 있는지 알아보자.

Feedback Loops

모노레포(Monorepo)에서는 모든 코드가 동일한 저장소에 있기 때문에 피드백 루프가 단순화된다. 이는 각 팀이 변경한 내용이 다른 팀과 마이크로 프런트엔드에 어떤 영향을 미치는지 즉시 알 수 있음을 의미한다. 이를 통해 수동 릴리스가 필요 없으며, 호환성 깨짐(breaking changes) 위험이 줄어든다.

개발자는 변경 사항을 만들 때 그 영향에 대한 정보를 즉시 받을 수 있어, 영향을 최소화하기 위한 필요한 수정 작업을 수행할 수 있다.

Shared Code Strategies

Nx와 같은 모노레포(Monorepo) 툴링을 사용하면, 팀들이 중앙 패키지 레지스트리를 필요로 하지 않고도 코드를 공유할 수 있다. 이는 팀들이 레지스트리에 변경 사항을 수동으로 릴리스할 필요성을 없애주며, 충돌 및 버전 관리 문제의 위험을 줄인다.

이 방식은 공유 코드의 별도 저장소를 업데이트하고, 중앙 레지스트리의 새로운 릴리스를 기다린 후, 소비자 코드에 새 버전을 설치하는 과정을 생략하여 개발 속도를 크게 향상시킨다.

공유 코드에 대한 모든 변경 사항은 이를 사용하는 코드와 동일한 저장소에서 이루어질 수 있다. 이는 팀 간 협업과 투명성을 높이고, 품질을 개선하며(변경 사항이 즉각적인 피드백을 제공), 호환성 깨짐(breaking changes)의 위험을 줄인다.

또한, 의존성 그래프와 IDE 지원을 통해 공유 코드를 사용하는 항목에 대한 가시성(observability)이 증가한다. 이는 개발자가 변경 사항의 영향을 더 잘 이해하고 신중한 결정을 내릴 수 있도록 돕는다.

Dependancy Management

모노레포(Monorepo)에서는 React나 Angular와 같은 주요 종속성의 버전 업그레이드가 모든 소비자에 동시에 적용된다. 이는 시스템 전반에서 최대한의 호환성을 보장하며, 호환성 깨짐(breaking changes) 위험을 줄인다.

물론, 이러한 업그레이드를 수행할 시점에 대해 팀 간의 협업과 조율이 필요하지만, 이는 최종 사용자에게 더 높은 신뢰성과 호환성을 제공하는 결과로 이어진다.

팀들은 여전히 date-fns나 lodash와 같은 다른 소규모 종속성에 대해 자신의 버전을 사용할 수 있다. 이는 각 팀의 package.json에 종속성을 정의하거나, 루트 package.json에서 별칭(alias)을 지정함으로써 가능하다.

Testing Strategies

모노레포(Monorepo)에서는 테스트 전략도 간소화된다. 시스템의 모든 부분이 동일한 저장소에 있기 때문에 테스트가 더 쉽고 일관성이 높아진다. 로컬 서버를 조율하여 시스템에 대해 자동화된 E2E 및 통합 테스트를 실행하는 작업이 간편해지며, 저장소에는 항상 각 마이크로 프런트엔드의 최신 상태가 반영된다.

이러한 자동화된 테스트는 CI/CD 파이프라인에서 실행될 수 있으며, 모노레포의 변경 사항에 의해 트리거된다. 이를 통해 시스템 전체가 항상 테스트되며, 이전에는 식별하기 어려웠던 문제(마이크로 프런트엔드 간 통합 지점)를 조기에 발견할 수 있다.

테스트 스위트는 최종 배포된 애플리케이션을 실제 사용자 관점에서 사용하는 방식에 더 가깝게 작성될 수 있어, 최종 제품의 품질을 향상시킨다.


Where does Nx fit?

Nx는 개발자 생산성을 향상시키고, CI 성능을 최적화하며, 코드 품질을 유지하기 위한 도구와 기법을 제공하는 강력한 오픈 소스 빌드 시스템이다. 특히 모노레포(Monorepo)와 잘 작동하며, Angular와 React 프로젝트를 위한 Module Federation에 대한 내장 지원을 제공한다.

profile
번역 전용

0개의 댓글