팀마다 백오피스가 따로 있어 운영자는 여러 URL과 로그인을 오갔고,
하나로 합치자니 한 줄 변경에도 전체 빌드 25분을 기다려야 했습니다.
Module Federation으로 화면은 런타임에 합치고, 빌드·배포는 팀별로 분리했습니다.
자비스앤빌런즈(삼쩜삼) · 플랫폼 설계·구축·운영 (기여도 90%) · 온보딩 체계 설계 — 프론트엔드 개발자가 아닌 구성원들이 어드민 10여 개 직접 제작
⚠ 합치면? 한 팀의 한 줄 변경에도 전체 빌드 25분 + 배포 대기 줄
색점 하나가 팀(remote) 하나 — 화면은 하나지만 배포는 여전히 팀별, 변경된 앱만 3분
Host가 인증·레이아웃·라우팅·권한을 소유하고, Remote는 ./App 진입점 하나만 노출합니다.
공유 싱글턴 4개: react react-dom react-router react-query — 열 개의 앱이 하나의 React 트리·라우터·쿼리 캐시를 씁니다
점선 remote는 프론트엔드 팀 밖에서 개발·배포되는 어드민 — 레포가 달라도 같은 화면에서 동작합니다
모든 remote는 host 없이 단독 실행도 가능합니다 — 각 팀은 자기 앱만 띄워서 개발합니다
remoteEntry.jsno-cachechunk-[hash].js장기 캐시변경 없는 청크는 그대로 재사용Remote마다 Error Boundary로 감싸 로드 실패·렌더 에러를 그 화면 안에 가둡니다.
공유 싱글턴 4개 — React 트리·라우터·쿼리 캐시가 전부 같은 상속 구조입니다.
대표 사례가 QueryClient입니다: Host 안에서는 상속해 캐시를 공유하고, 단독 실행이면 자체 생성합니다.
// remote App.tsx — 자기 Provider보다 위의 Context를 읽는다 const standaloneQueryClient = new QueryClient() const App = () => { // Host 안이면 Host의 클라이언트를 상속해 캐시 공유, standalone이면 자체 생성 const queryClient = useContext(QueryClientContext) ?? standaloneQueryClient return <QueryClientProvider client={queryClient}>...</QueryClientProvider> }
단, 조건이 하나 있습니다 — Host와 Remote가 같은 react-query 인스턴스를 써야 합니다. 인스턴스가 다르면 Context도 달라서 상속이 끊기기 때문입니다.
⚠ Remote의 훅이 Host의 Provider를 찾지 못합니다 — 서로 다른 Context를 보고 있기 때문
MF shared의 본질은 버전 협상이 아니라 모듈 인스턴스 공유입니다
열 개의 remote가 공통으로 부르는 API(유저·권한·공통 코드)가 화면을 오갈 때마다 다시 호출되던 것이, 상속 후에는 한 번의 요청과 캐시 재사용으로 바뀝니다.
자기 도메인 키만 무효화하는 컨벤션으로 관리하고, 진짜 격리가 필요한 앱은 shared 미등록으로 opt-out합니다.
실제 사고를 겪으며 만든 규칙들입니다. 지키는 일은 사람의 주의가 아니라 CI와 설정에 맡겼습니다.
^1.8.1로 선언했습니다. 캐럿은 "1.x 최신이면 아무거나"라는 뜻이라, 설치 시점에 1.20이 깔렸습니다.| 장치 | 지키는 것 |
|---|---|
| 버전 불일치 차단 | 모노레포 앱들은 루트 pnpm.overrides로 버전을 한 곳에서 통일하고, 프론트 팀이 직접 관리하지 않는 별도 레포는 CI가 검사해 어긋나면 빌드 실패 + 슬랙 알림 (사고 2건 후 원칙화) |
| remoteEntry no-cache | remote를 배포해도 구버전이 로드되는 함정 — 엔트리만 캐시 제외, 청크는 해시로 장기 캐시 |
| 브랜치 프리뷰 + 자동 회수 | 브랜치를 올리면 그 브랜치만의 프리뷰 주소가 자동으로 생기고, 브랜치를 지우면 프리뷰와 배포 리소스도 자동으로 정리됩니다 (CloudFront Multi-Tenant) |
플랫폼이 공통 문제를 미리 풀어두면, 각 팀에게 남는 일은 자기 화면뿐입니다.
그 결과 프론트엔드 개발자가 아닌 구성원들이 10개에 달하는 어드민을 대부분 질문 없이 직접 만들었고, 회사 전체 구성원이 사용하고 있습니다.