Module Federation
- webpack5에 도입된 고급 모듈 통합 기능
- 서로 다른 애플리케이션이 런타임에 필요한 코드를 공유할 수 있게 해 준다.
- 각각의 애플리케이션들이 서로 독립적으로 개발되고 배포될 수 있다.
- 필요한 코드만 실시간으로 로드하기 때문에 애플리케이션의 성능을 최적화할 수 있다.
- https://webpack.kr/concepts/module-federation/
Module Federation 구성요소
Host
- 다른 애플리케이션(remote)으로부터 모듈을 로드하고 사용하는 주체이다.
Remote
- Host에 로드될 수 있는 모듈을 제공한다.
- 독립적으로 배포 및 업데이트가 될 수 있다.
Shared
- Host와 Remote 애플리케이션 간에 공유되는 의존성을 의미한다.
- 중복된 코드의 로딩을 방지하고, 일관된 종속성 관리를 가능하게 한다.
MonoRepo - Module Federation Example
워크스페이스 설정
- gugbab-main-app : Host App
- gugbab-compont-app : Remote App
packages:
- 'apps/gugbab-component-app'
- 'apps/gugbab-main-app'
프로젝트 생성
- create mf-app : 기본 설정의 module federation app을 쉽게 생성할 수 있다.
Module Federation 설정하기
플러그인 구성
- 웹팩 설정 파일에서 ModuleFederationPlugin을 사용하여 host, remote 애플리케이션 설정을 정의한다.
- ex) apps/gugbab-component-app/webpack.config.js
- name : 노출되는 이름
- filename: 생성되는 entry 파일 명
- expose : 노출되는 모듈 정보
module.exports = (_, argv) => ({
... 생략
plugins: [
new ModuleFederationPlugin({
... 생략
name: "gugbab_component_app",
filename: "remoteEntry.js",
exposes: {
"./Button": "./src/components/Button",
},
}),
],
});
원격 엔트리 파일 생성
- Remote 애플리케이션에서 자체적인 빌드 과정을 통해 remote 엔트리 파일을 생성한다. (ex. remoteEntry.js)
- 엔트로 파일로 Remote 애플리케이션의 인터페이스 역할과, Host 애플리케이션에서 접근할 수 있게 해 준다.
모듈 노출
- expose옵션을 통하여 Host 애플리케이션에서 로드할 수 있게 모듈을 노출시킨다.
- ex) apps/gugbab-main-app/webpack.config.js
- remotes : import 할 모듈 정보
- Ex) [import시 불러올 변수명] : "[RemoteApp정의된 name]@[RemoteApp주소]/[RemoteApp Entry파일명]"
module.exports = (_, argv) => ({
... 생략
plugins: [
new ModuleFederationPlugin({
name: "gugbab_main_app",
filename: "remoteEntry.js",
remotes: {
gugbab_component_app:
"gugbab_component_app@http://localhost:3001/remoteEntry.js",
},
}),
],
});
```
동적모듈 연결
- Host 애플리케이션은 Remote 애플리케이션의 remoeteEntry를 참조하여 모듈을 동적으로 로드한다.
- 주로 import() 문으로 로드하여 코드베이스에 통합한다.
const Button = React.lazy(() => import("test/Button"));
const App = () => (
<div className="container">
<Button>Gugbab Module Federation Test Button</Button>
</div>
);