← 목록으로

마이크로 프런트엔드, 혹시 '코드 공유' 지옥에 빠지셨나요? 모노레포가 해답입니다!

2026. 3. 28.

마이크로 프런트엔드, 혹시 '코드 공유' 지옥에 빠지셨나요? 모노레포가 해답입니다!

복사-붙여넣기 카오스에서 내부 npm 패키지, 그리고 마침내 '이거다!' 싶은 모노레포로 팀들이 진화하는 이야기.

Hero Image


요약: 마이크로 프런트엔드는 팀에 자율성을 선사하지만, 보이지 않는 코드 공유 문제를 낳습니다. 내부 npm 패키지가 해결책이 될 수 있지만, 이는 곧 배포 오버헤드라는 새로운 짐을 지웁니다. 결국, 모노레포는 훨씬 적은 유지보수 비용으로 압도적인 코드 재사용성을 제공하며 이 모든 문제를 깔끔하게 해결해 줍니다.


🧩 마이크로 프런트엔드의 확장성, 그 이면의 문제

프런트엔드 애플리케이션이 거대해지면, 많은 팀들이 거대한 앱을 마이크로 프런트엔드 단위로 쪼갭니다. 이는 제품의 각 부분이 서로 독립적으로 발전할 수 있도록 하는 효과적인 전략이죠.

예를 들어, 이커머스 플랫폼이라면 대략 이런 식으로 나눌 수 있습니다:

책임 범위
🔐 인증 (Auth)로그인, 회원가입, 세션
🛍️ 상품 카탈로그상품 목록, 검색, 상세 정보
🛒 장바구니 & 결제장바구니 상태 관리, 결제 기능
👤 계정 / 설정프로필, 환경설정

이 방식은 팀의 자율성을 극대화합니다. 각 팀은 서로의 작업에 발목 잡히지 않고 자신들의 영역을 소유하고, 배포하고, 발전시킬 수 있죠. 🚀 제가 처음 마이크로 프런트엔드를 도입했을 때, 이 '자율성'이라는 키워드에 매료되어 망설임 없이 선택했습니다.

하지만 MFE의 수가 늘어날수록, 한 가지 문제가 서서히 수면 위로 떠오릅니다:

⚠️ 숨겨진 비용: 앱은 분리되었지만, 결국 동일한 공유 빌딩 블록에 의존할 수밖에 없습니다. 포매터(formatter), API 클라이언트, 커스텀 훅, 타입 정의, 핵심 비즈니스 로직 같은 것들이죠. 이런 공유 코드를 여러 레포지토리에서 관리하는 것은 생각보다 훨씬 어렵습니다.

보통 공유되는 빌딩 블록은 다음과 같습니다:

// 모든 MFE가 필요로 하는 공통 코드들
가격 & 통화 포매터 (price & currency formatters)
API 요청 헬퍼 (API request helpers)
공유 상품 및 사용자 타입 (shared product and user types)
인증 / 세션 유틸리티 (auth / session utilities)
애널리틱스 트래킹 헬퍼 (analytics tracking helpers)
재사용 가능한 훅 (reusable hooks) // useCart(), useAuth(), useDebounce() 등
비즈니스 로직 (business logic) // 할인, 세금, 재고 확인 등

여기서부터 일이 복잡해지기 시작합니다. 팀들은 보통 두 가지 방식 중 하나로 이 문제를 해결하지만, 둘 다 나름의 단점을 가지고 있습니다.


📦 폴리레포(Polyrepo) + npm 패키지 방식

폴리레포 환경에서는 각 앱이 독립적인 레포지토리에 존재합니다:

auth-app/
product-catalog-app/
cart-checkout-app/
account-app/

코드 중복을 피하기 위해, 공유 코드는 내부 패키지로 추출됩니다:

shared-ui/
shared-hooks/
shared-utils/
shared-types/
api-client/

✅ 이 방법은 확실히 복사-붙여넣기보다는 낫습니다. 공유 코드는 재사용 가능하며, 각 패키지의 경계도 명확하죠.

배포 마찰 문제 (The Release Friction Problem)

하지만 시간이 흐를수록, 또 다른 종류의 오버헤드가 스멀스멀 기어들어 옵니다. 심지어 작은 공유 코드 하나를 수정하더라도 전체 워크플로우를 거쳐야 합니다:

1. 공유 패키지 업데이트
        ↓
2. PR 생성 및 코드 리뷰 진행
        ↓
3. 새로운 버전 npm에 배포 (publish)
        ↓
4. 모든 종속 앱에서 의존성 버전 업그레이드 (bump)
        ↓
5. 각 앱을 독립적으로 재테스트
        ↓
6. 모든 앱을 각각 배포

😓 헬퍼 함수 하나, 훅 하나 바꾸는데 이 많은 과정이라니! 제가 실제로 작은 유틸리티 하나를 고치려다 배포 파이프라인과 씨름하며 하루 종일 씨름했던 기억이 납니다. '이게 맞나?' 싶은 회의감이 들 때가 한두 번이 아니었죠. 공유 코드가 늘어날수록 팀은 단순히 앱만 유지보수하는 것이 아니라, 내부 패키지 생태계 전체를 관리해야 하는 상황에 놓입니다. 코드 공유가 생각보다 훨씬 무겁게 느껴지기 시작하는 순간이죠.


🏗️ 모노레포, 과연 무엇인가?

**모노레포(Monorepo)**는 간단히 말해, 여러 앱과 공유 패키지가 단일 레포지토리 안에 함께 존재하는 구조입니다.

apps/
  auth-app/
  product-catalog-app/
  cart-checkout-app/
  account-app/

packages/
  shared-ui/
  shared-hooks/
  shared-utils/
  shared-types/
  api-client/

앱들은 공유 코드를 깔끔하게 사용합니다. 마치 일반적인 패키지처럼요. 단, 배포(publish) 과정이 없습니다.

import { Button, Modal }     from '@repo/shared-ui'
import { useCart, useAuth }  from '@repo/shared-hooks'
import { formatCurrency }    from '@repo/shared-utils'
import { apiClient }         from '@repo/api-client'
import type { Product }      from '@repo/shared-types'

💡 핵심 인사이트: 더 이상 모든 공유 추상화를 재사용하기 위해 npm 패키지로 배포할 필요가 없습니다. 이 한 가지 변화가 개발자 경험을 완전히 뒤바꿉니다.


✅ 모노레포가 문제를 해결하는 방식

팀들이 모노레포로 전환하자마자, 공유 코드는 드디어 자연스러운 보금자리를 찾게 됩니다. 모든 재사용 가능한 조각들을 개별적으로 배포된 패키지로 강제하는 대신, 코드는 내부 워크스페이스를 통해 로컬에서 공유됩니다.

새로운 워크플로우

1. 공유 코드 업데이트
        ↓
2. 모든 앱이 즉시 사용 가능
        ↓
3. 모든 것을 함께 테스트
        ↓
4. 단일 PR로 배포 ✅

이 덕분에 팀은 두 가지 최고의 이점을 모두 누릴 수 있게 됩니다:

패키지처럼 공유하고, 단일 시스템처럼 관리한다. 모듈화된 코드 구성, 명확한 경계, 앱 전반에 걸친 재사용 — 이 모든 것을 배포 및 버전 관리 오버헤드 없이!

이제 공유 유틸리티, 훅, 또는 API 클라이언트가 변경되면:

  • 모든 종속 앱이 즉시 최신 코드를 사용할 수 있게 됩니다.
  • 변경 사항들을 함께 테스트할 수 있습니다.
  • 리팩토링이 훨씬 쉬워집니다.
  • 버전 불일치 문제가 사라집니다.

🎯 팀이 얻는 핵심 가치

가장 큰 이득은 단순히 깔끔한 코드가 아닙니다. 바로 일상적인 개발에서 마찰이 줄어든다는 점입니다.

🧹 중복 감소

공유 코드는 명확하고 단일한 위치에 존재합니다. 더 이상 복사-붙여넣기로 인한 코드 발산이 없습니다.

⚡ 개발 속도 향상

작은 공유 변경에도 publish-bump-retest 사이클을 거칠 필요가 없습니다.

🔧 리팩토링 용이성

공유 코드와 이를 사용하는 앱들이 함께, 원자적으로 진화할 수 있습니다.

🎯 일관성 향상

모든 앱이 항상 동일한 구현을 따르며 정렬된 상태를 유지합니다.

📉 오버헤드 감소

더 이상 늘어나는 작은 내부 패키지 레포지토리 생태계를 관리할 필요가 없습니다.

🔍 가시성 증대

모든 시스템을 검색하고, 검토하고, 이해하는 단일한 장소가 생깁니다.


☝️ 한 가지 중요한 교훈

모노레포는 강력하지만, 코드를 의도적으로 공유할 때만 그 빛을 발합니다. 무조건적인 공유는 오히려 독이 될 수 있습니다.

다음과 같은 경우에만 코드를 공유 패키지로 추출하세요:

  • 두 개 이상의 앱에서 사용될 때 (단순히 한 앱만을 위한 것이 아님)
  • ✅ 시스템 전체에서 일관성을 유지하는 것이 중요할 때
  • ✅ 잦은 변경 없이 안정적으로 중앙 집중화할 수 있을 만큼 성숙할 때

📌 만약 코드가 특정 앱에만 국한된다면, 로컬에 그대로 두세요. 과도한 추출은 또 다른 종류의 혼란을 야기합니다. 아무도 정확히 소유하지 않는 공유 패키지는 또 다른 골칫덩이가 될 수 있죠. '의도적인 공유'야말로 모노레포를 건강하게 유지하는 핵심입니다.


📊 빠른 비교: 세 가지 접근법

접근법장점단점
복사-붙여넣기초기에는 빠름중복, 버그 확산, 일관성 부족
내부 npm 패키지재사용 가능, 모듈화배포 오버헤드, 버전 불일치, 느린 개발
모노레포 워크스페이스재사용 + 빠른 개발 + 원자적 리팩토링초기 설정 비용, 팀의 규율 필요

💭 마무리하며

"최고의 아키텍처는 가장 많은 패키지를 가진 것이 아니라, 가장 적은 마찰을 가진 것이다."

마이크로 프런트엔드는 실제 확장성 문제를 해결하는 훌륭한 해법입니다. 하지만 앱이 성장함에 따라, 코드 공유 전략은 앱 경계 설정만큼이나 중요해집니다.

대부분의 팀에게 모노레포는 잃어버린 마지막 퍼즐 조각이 됩니다. 패키지 스타일의 모듈성을 유지하면서도 배포 오버헤드를 없애주기 때문이죠. 이것이 바로 개발자들의 일상적인 경험에 엄청난 차이를 만들어냅니다. 🚀


원문: https://dev.to/dhinesh_ks_9db13f15d64f7/micro-frontends-the-hidden-code-sharing-problem-4j90 수집일: 2026-03-28 05:15:38