본문 바로가기
개발

모듈 페더레이션(Module Federation) 이해하기

by 개발과 운동, 그리고 책장 2025. 1. 26.

모듈 페더레이션(Module Federation)이란?

 

모듈 페더레이션은 여러 개의 독립적인 애플리케이션이 런타임에서 서로의 코드를 동적으로 공유하고 실행할 수 있게 해주는 아키텍처

→ 레고 블록에 비유해서 필요한 모듈을 조립하여 사용한다고 표현 

  • 기존 마이크로프론트엔드 접근 방식들과의 비교
특징 Module Federation 기존 마이크로프론트엔드
상호작용 Remote 및 Host 간에 런타임 의존성을 동적으로 로드하고, 즉시 호출 및 상태 공유가 가능. 상태와 데이터를 공유하려면 명시적 API 또는 전역 이벤트 버스를 사용하는 등 추가적인 설계가 필요함.
구성 가능성 런타임에 필요한 모듈만 불러오는 방식으로 동적 구성 가능. 대부분 정적인 구성이며 빌드 타임에 모든 애플리케이션이 이미 정의됨.
독립성 모듈 간 적절히 의존성을 나눌 경우 독립성과 통합이 균형 있게 유지됨. 각 애플리케이션이 완전히 독립적이며 통합에 추가적인 작업 필요.
장점 - 런타임에 모듈을 동적으로 로드하여 최신 상태 유지.
- 공통 라이브러리 및 코드를 효율적으로 공유 가능.
- 재사용성 증가.
- 애플리케이션 간의 강한 독립성.
- 다양한 프레임워크 및 기술을 독립적으로 사용할 수 있음.

 

  • 모듈 페더레이션의 등장 배경
  • 대규모 애플리케이션의 복잡성 증가 : 여러 팀이 각각의 기능을 개발하는 경우가 많아짐 
  • 마이크로프론트엔드의 한계 : 각 애플리케이션이 모든 의존성을 포함하므로 코드가 중복되고, 앱 크기가 커질 수 있음
  • 사용성과 업데이트의 문제 : 공통으로 사용하는 컴포넌트를 수정해야 할 때, 모든 프로젝트를 다시 빌드하고 배포해야 하는 불편함

 

모듈 페더레이션의 주요 특징  

  • 동적 로딩 
    • 앱 실행 중에 필요한 코드만 불러옴
    • 코드 업데이트 시 전체 앱을 재배포하지 않고 해당 모듈만 교체 가능
    • 초기 로딩 시간 단축 및 메모리 효율성 향상
  • 공유와 재사용 (한번 만들어서 여러 곳에서 사용 가능) 
    • 공통 UI 컴포넌트를 여러 프로젝트에서 실시간 공유
    • 라이브러리 중복 설치 방지 (각 프로젝트마다 따로 설치하지 않음 ex : react , vue router 등등)
    • 버그 수정 시 한 곳만 수정하면 모든 프로젝트에 적용
  • 독립성과 유연성
    • 여러개의 프로젝트를 선호하는 기술 스택으로 개발 가능 (React 팀과 Vue 팀의 협업)
    • 팀별로 자유로운 배포 일정 관리
    • 새로운 기능이나 서비스를 기존 시스템에 쉽게 통합

 

간단한 구현 예제 

프로젝트는 간단하게 구현하였으며, Vue Project 4개로 분리하여 작성하였습니다 

 

 

프로젝트는 다 동일하게 설정하였고 각각 A B C에 맞추어 각각 컴포넌트만 구성했습니다.



 
 

 

프로젝트 생성

1
2
3
4
5
6
7
# Host 프로젝트 생성
npm create vite@latest HostProject -- --template vue
 
# Remote 프로젝트들 생성
npm create vite@latest RemoteProjectA -- --template vue
npm create vite@latest RemoteProjectB -- --template vue
npm create vite@latest RemoteProjectC -- --template vue
cs

 

모듈 페더레이션 패키지 설치

1
npm i @originjs/vite-plugin-federation
cs

 

 

Remote 프로젝트 설정

 

//vite.config.js
// A B C 모두 설정 
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import federation from '@originjs/vite-plugin-federation'
export default defineConfig({
 plugins: [
   vue(),
   federation({
     name: "remoteA",           // Remote 프로젝트의 고유 이름
     filename: "remoteA.js",    // 빌드될 Remote 진입점 파일명
     exposes: {
       // 외부로 노출할 컴포넌트 설정
       "./compA": "./src/components/compA.vue",
     }
   })
 ]
})​

 

 

exposes 설정 상세

 

exposes: {
 // "외부에서 접근할 경로": "실제 파일 경로"
 "./Button": "./src/components/Button.vue",    // 단일 컴포넌트 노출
 "./utils/*": "./src/utils/*",                 // 디렉토리 전체 노출
 "./feature": "./src/features/index.js"        // 모듈 노출
}

 

Host프로젝트 설정

 

//vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import federation from '@originjs/vite-plugin-federation'

export default defineConfig({
 plugins: [
   vue(),
   federation({
     name: "host",
     remotes: {
       // Remote 프로젝트 연결 설정
       remoteA: "http://localhost:5180/remoteA.js",
       remoteB: "http://localhost:5181/remoteB.js",
       remoteC: "http://localhost:5182/remoteC.js"
     },
     shared: ["vue"]  // 공유할 디펜던시
   })
 ]
})

 

remotes 설정 상세

remotes: {
 // "프로젝트별칭": "Remote 프로젝트 URL/빌드파일명"
 remoteA: {
   external: "http://localhost:5180/remoteA.js",
   format: "esm",            // 모듈 포맷
   from: "vite"             // 빌드 도구
 },
 // 간단한 문자열 형태도 가능
 remoteB: "http://localhost:5181/remoteB.js"
}

 

컴포넌트 사용 예시 

<script setup>
// Remote 프로젝트의 컴포넌트 import
import compA from "remoteA/compA"
import compB from "remoteB/compB"
import compC from "remoteC/compC"
</script>

<template>
  <div>
    <h1 class="host">Host Project</h1>
    <compA />
    <compB />
    <compC />
  </div>
</template>

 

각각 Remote Project 실행 화면 

 

Host 실행 화면 

 

결론 

해당 글에서는 매우 간단한 적용 예제만 넣어놨지만 , Module Federation은 프론트엔드 개발에서 팀 간의 협업, 코드 재사용, 독립적인 배포를 상황에 따라 문제해결에 도움을 줄수 있습니다.

 

 

제가 회사 프로젝트에서 모듈 페더레이션의 활용 사례를 예로 들자면, 공통적으로 여러 프로젝트에서 사용할 수 있는 특정 프로젝트가 모듈 페더레이션으로 적용되어 있어 재사용의 장점을 가지고 있고, Vue + Capacitor로 구성되어 있는 네이티브 앱을 Host Project로 설정하고 페이지를 구성하고 있는 Remote Project로 분리하여 WebView 방식처럼 앱 심사 없이 수정이 가능한 장점도 취하고 있습니다.

 

이처럼 모듈 페더레이션은 프로젝트의 요구사항과 상황에 맞게 다양한 방식으로 활용할 수 있습니다. 여러분도 비슷한 문제 해결이 필요할 때 이 내용이 도움이 되길 바랍니다 🚀

 

 

댓글