Error

[Error]ModuleFederation Shared module is not available for eager consumption(웹팩 모듈 페더레이션과 즉시 로딩: react 모듈 사용 시 발생하는 오류 해결하기)

kind1230 2024. 2. 4. 15:05

에러 발생

애플리케이션 개발 중, 웹팩의 모듈 페더레이션 기능을 사용하여 react 모듈을 공유하려 할 때 다음과 같은 오류 메시지가 나타났다.

Error: Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react

에러 발생 소스

이 오류는 웹팩의 ModuleFederationPlugin을 사용하여 마이크로프론트엔드 아키텍처에서 공유 모듈(react 및 react-dom 등)을 설정할 때 발생했다. 특히, react 모듈을 애플리케이션의 다른 부분에서 "즉시(eagerly)" 사용하고자 할 때 이 문제가 나타났다.

웹팩 설정 예제:

 plugins: [
    new ModuleFederationPlugin({
      name: "kumcheok_mf_test",
      filename: "remoteEntry.js",
      remotes: {
        mfApp: "mfApp@http://localhost:4000/remoteEntry.js",
      },
      exposes: {
        "./Button": "./src/components/Button",
      },
      shared: {
        ...deps,
        react: {
          requiredVersion: deps.react,
        },
        "react-dom": {
          requiredVersion: deps["react-dom"],
        },
      },
    })

에러 원인

이 오류의 근본 원인은 react 모듈이 애플리케이션 초기 로드 시점에 사용 가능한 상태가 아니었기 때문이다. 모듈 페더레이션에서는 공유 모듈이 필요한 시점에 로드되도록 기대하지만, eager 옵션이 명시되지 않았을 때, 해당 모듈의 사용 가능 여부를 즉시 확인할 수 없어 발생하는 문제였다.

해결 방법

1. webpack.config > eager: true

장점:

  • 즉각적인 사용 가능: eager: true를 설정하면 해당 모듈은 애플리케이션의 초기 로드 시 바로 사용 가능하다. 이는 의존성이 필수적이고, 시작 시점부터 필요한 경우 유용하다.
  • 간단한 설정: 모듈을 즉시 사용하도록 설정하는 것은 구성이 간단하며, 추가적인 로딩 로직을 작성할 필요가 없다.

단점:

  • 성능 영향: 모든 필수 모듈이 초기 로드에 포함되므로, 애플리케이션의 시작 시간이 길어질 수 있다. 특히 크기가 큰 모듈이나 많은 수의 모듈을 사용하는 경우 더욱 길어진다.
  • 리소스 낭비: 사용자가 실제로 사용하지 않는 기능에 대한 모듈도 로드되므로, 리소스 사용이 비효율적일 수 있다.
shared: {
  react: {
    singleton: true,
    requiredVersion: deps.react,
    eager: true, // 추가
  },
  "react-dom": {
    singleton: true,
    requiredVersion: deps["react-dom"],
    eager: true, // 추가
  },
},

2. bootstrap.js 파일 사용

장점:

  • 로딩 제어: 애플리케이션의 초기화 과정을 더 세밀하게 제어할 수 있다. 모듈 로딩 순서나 조건을 지정하여 성능을 최적화할 수 있다.
  • 동적 로딩 지원: 필요에 따라 모듈을 동적으로 로드하는 로직을 bootstrap.js에 구현할 수 있다. 이를 통해 사용자의 실제 요구에 맞춰 리소스를 효율적으로 로드할 수 있다.

단점:

  • 구현 복잡성: 초기화 과정을 직접 관리해야 하므로, bootstrap.js 파일을 설정하고 관리하는 데 추가적인 노력이 필요하다.
  • 로딩 지연: 동적 로딩을 사용하는 경우, 모듈이 실제로 필요한 순간까지 로딩이 지연될 수 있다. 이는 특정 기능의 응답성에 영향을 줄 수 있다.

index.js

import('./bootstrap');

bootstrap.js

 import React from 'react';
 import ReactDOM from 'react-dom';
 import App from './App';
 ReactDOM.render(<App />, document.getElementById('root'));

bootstrap 사용 전
bootstrap 사용 후