MSA

[MFA] Module Federation란? Basic Example

차노도리 2024. 1. 7. 23:04

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'

 

프로젝트 생성

 

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>
);