모듈 페더레이션(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 방식처럼 앱 심사 없이 수정이 가능한 장점도 취하고 있습니다.
이처럼 모듈 페더레이션은 프로젝트의 요구사항과 상황에 맞게 다양한 방식으로 활용할 수 있습니다. 여러분도 비슷한 문제 해결이 필요할 때 이 내용이 도움이 되길 바랍니다 🚀
댓글