
마이크로 프론트엔드에만 통용되는 개념은 아니지만 마이크로 프론트엔드의 구현의 하나로 볼 수 있습니다. 각 번들링되어 모듈화 된 앱을 각각의 모듈 단위로 찢어서 배포할 수 있는 방법을 제공하기 때문입니다.
하나의 앱을 독립적인 배포가 가능한 모듈 단위로 나누어 브라우저 런타임에 합체시키는 개념. Apollo GraphQL의 Federation 개념을 Zack Jackson이 JS 모듈에 적용한 개념입니다. Module Federation을 통해 해결하고자 한 것들은 아래와 같습니다.
해당 글에서는 Vite의 Module Federation을 사용합니다. Webpack의 모듈 페더레이션 설정과는 조금 다를수 있으나 핵심 개념과 사용되는 용어는 동일합니다.
Module Federation을 사용하기 위해서는 아래의 핵심 개념들을 이해해야 합니다.
Module Federation을 사용하면 애플리케이션이 어떠한 방법으로 런타임에 통합이 되고 동작하게 되는건지 이해가 필요합니다. 통합시 의존관계에 따라 로드될때 사용되는 용어가 Container & Container Reference 입니다.
다른 어플리케이션에서 로드가능한 단위를 말합니다.

위 그림처럼 Host Application에서 A-Remote App와 B-Remote App를 로드해왔다면 A-Remote와 B-Remote는 Container가 됩니다.
특정 어플리케이션에서 다른 어플리케이션을 불러와 사용하는경우, 해당 어플리케이션에 대한 Container Reference가 존재한다라고 합니다.
위에 설명한 Container와 Container Reference가 되기 위해선 Module Federation의 설정 필드인 expose, import 그리고 shared 필드에 대한 이해가 필요합니다.
컨테이너가 외부에 노출한 원격 모듈의 목록을 나타내는 설정입니다. 하나의 어플리케이션에서 여러개의 모듈을 내보낼수 있습니다. 해당 설정이 되어 있는 어플리케이션은 앞서 설명한 Container가 됩니다.
{
"filename": "cart-mfe-entry.js",
"name": "cart-mfe",
"exposes": {
"./Pages/Cart" : "./src/pages/cart/Index.vue",
"./Store": "./src/stores"
}
}
위의 코드처럼 exposes 필드에 {"모듈이름": "로컬경로'} 선언을 통해서 여러 모듈들을 내보낼수 있습니다.
컨테이너 레퍼런스가 될 어플리케이션에 import 설정을 통해 Container를 불러올수 있습니다. 해당 설정이 되어 있는 어플리케이션은 import 선언한 컨테이너의 레퍼런스를 갖게 됩니다.
{
"name": "main-app",
"filename": "main-app-entry.js",
"shared": ["vue", "vue-router", "pinia"],
"remotes": {
"cart-mfe": "http://localhost:5101/assets/cart-mfe-entry.js",
"product-mfe": "http://localhost:5102/assets/product-mfe-entry.js",
"user-mfe": "http://localhost:5103/assets/user-mfe-entry.js",
}
}
위의 코드처럼 remotes 필드를 통해 여러개의 컨테이너 레퍼런스를 갖을수도 있습니다.
공유 모듈설정은 여러 컨테이너에서 같이 사용하는 모듈을 말하며 런타임에 한번만 로딩되도록 처리됩니다. 예를들어 여러 컨테이너에서 Vue가 사용된다면 Vue의 로딩은 한번만 이뤄지게 됩니다. 마이크로 앱간에 의존성 공유를 할 때 공유 의존성에 대한 설정, 버전을 체크하고 이를 설정한 대로 로드될수 있도록 처리합니다.
{
"name": "main-app",
"filename": "main-app-entry.js",
"shared": ["vue", "vue-router", "pinia"],
"remotes": {
"cart-mfe": "http://localhost:5101/assets/cart-mfe-entry.js",
"product-mfe": "http://localhost:5102/assets/product-mfe-entry.js",
"user-mfe": "http://localhost:5103/assets/user-mfe-entry.js",
}
}
위의 코드처럼 shared 필드에 배열로 설정가능하며, 해당 값으로 모듈이름을 넣어주면 됩니다. 샘플 프로젝트에서는 vue와 상태관리를 위한 pinia가 공통으로 사용됩니다.
호스트(Host)
원격 모듈을 소비하는 애플리케이션입니다. 호스트는 원격 모듈을 동적으로 로드하여 자신의 코드 베이스에 통합합니다.
원격(Remote)
공유되는 모듈을 제공하는 애플리케이션입니다. 원격 애플리케이션은 자신의 일부 코드를 외부에서 사용할 수 있도록 공개합니다.
호스트 어플리케이션이 소비지가 직접 접근하는 어플리케이션이라고 생각하면 되고 해당 어플리케이션에서 공통부분의 처리라던가, 사용자 인증과 같은 통합 서비스에서 공통으로 이뤄지는 작업들을 처리하고 라우팅과 같은 처리를 담당합니다.
다음 글에서는 앞서 설명된 내용을 토대로 구성된 샘플 프로젝트기반으로 마이크로프론트엔드의 동작과 실무에 사용하기 위해 고민해야 할것들에 대한 내용을 다루겠습니다.
Micro Frontend by Michael Geers
Micro Frontend by Cam Jackson
Webpack 5 Module Federation - Zack Jackson