테마
공유 라이브러리 설정
shared 설정은 Module Federation에서 앱 간 공통 의존성의 중복 로드를 방지하는 핵심 메커니즘으로, singleton, requiredVersion, eager 등의 옵션을 통해 정밀한 버전 호환성 관리가 가능하다.
학습 목표
- shared 설정의 세 가지 표기법(배열, 문자열 값 객체, 상세 객체)을 구분하고 사용할 수 있다
- singleton, requiredVersion, eager, strictVersion 옵션의 동작 원리를 이해한다
- 여러 마이크로앱에서 동일 라이브러리의 버전이 다를 때의 동작을 예측할 수 있다
- React 같은 핵심 라이브러리의 중복 로드를 방지하는 최적 설정을 구성할 수 있다
- 모노레포 내부 패키지를 shared로 관리할 때 주의할 점을 파악한다
1. shared 설정의 동작 원리
shared 설정은 Module Federation이 여러 앱 간에 동일한 라이브러리를 한 번만 로드하도록 지시한다. Webpack 런타임은 로드된 공유 모듈을 추적하고, 이미 호환 가능한 버전이 있으면 재사용한다.
shared가 없을 때 vs 있을 때:
| 상황 | 번들 크기 | React 인스턴스 수 | 문제점 |
|---|---|---|---|
| shared 미설정 | 각 앱이 React를 별도 번들링 | 앱 수만큼 중복 | 번들 비대, 상태 격리, Hook 에러 |
| shared 설정 | React를 한 번만 로드 | 1개 | 없음 (정상 동작) |
2. shared 설정의 세 가지 표기법
2.1 배열 표기법 (가장 간단)
js
shared: ["react", "react-dom", "lodash"]- package.json의 버전 정보를 자동으로 참조
- 옵션을 세부 조정할 수 없음
- 빠른 프로토타이핑에 적합
2.2 문자열 값 객체 표기법
js
shared: {
react: "18.2.0",
"react-dom": "18.2.0",
lodash: "^4.17.0",
}- 버전을 명시적으로 지정 가능
- 시맨틱 버전 범위 표기 지원 (
^,~,>=등) - 추가 옵션은 지정 불가
2.3 상세 객체 표기법 (프로덕션 권장)
js
shared: {
react: {
singleton: true,
requiredVersion: "^18.0.0",
eager: false,
strictVersion: false,
},
"react-dom": {
singleton: true,
requiredVersion: "^18.0.0",
},
lodash: {
requiredVersion: "^4.17.0",
},
}3. shared 주요 옵션 상세
3.1 singleton
동일 라이브러리의 인스턴스를 전체 앱에서 하나만 사용하도록 강제하는 옵션이다.
js
shared: {
react: { singleton: true },
}| singleton 값 | 동작 |
|---|---|
false (기본) | 버전이 다르면 각각 별도 로드 |
true | 버전이 달라도 하나만 로드, 불일치 시 콘솔 warning |
React는 반드시 singleton: true로 설정해야 한다. React가 여러 인스턴스로 로드되면 Hook이 정상 동작하지 않는 심각한 버그가 발생한다.
3.2 requiredVersion
이 앱이 요구하는 라이브러리의 최소 버전을 지정한다. 시맨틱 버전 범위를 사용할 수 있다.
js
// 앱 A: lodash 4.17.21 설치, 정확한 버전 요구
shared: { lodash: { requiredVersion: "4.17.21" } }
// 앱 B: lodash 4.17.20 설치, 4.x 이상 허용
shared: { lodash: { requiredVersion: "^4.17.0" } }버전 일치 시나리오:
| 앱 A 설정 | 앱 B 설정 | 결과 |
|---|---|---|
"4.17.21" | "4.17.21" | 하나만 로드 |
"4.17.21" | "4.17.20" | 각각 별도 로드 |
"4.17.21" | "^4.17.0" | 하나만 로드 (B가 A의 버전 수용) |
3.3 singleton + requiredVersion 조합
js
shared: {
lodash: {
singleton: true,
requiredVersion: "4.17.20",
},
}- singleton이 true이므로 무조건 하나만 로드
- 공유받은 버전이 requiredVersion과 다르면 콘솔에 warning 표시
- 동작은 정상적으로 수행됨 (에러가 아닌 경고)
3.4 eager
js
shared: {
react: { singleton: true, eager: true },
}| eager 값 | 동작 |
|---|---|
false (기본) | 비동기 로드, bootstrap 패턴 필요 |
true | 초기 번들에 포함, 즉시 사용 가능 |
eager: true는 초기 번들 크기를 증가시키므로 신중하게 사용해야 한다. 일반적으로는 bootstrap.js 패턴으로 비동기 로드하는 것이 권장된다.
3.5 strictVersion
js
shared: {
react: {
singleton: true,
requiredVersion: "18.2.0",
strictVersion: true, // 불일치 시 에러 발생
},
}false(기본): 버전 불일치 시 콘솔 warning만 표시true: 버전 불일치 시 런타임 에러 발생, 앱 로딩 실패
4. package.json dependencies 자동 참조
create-mf-app이 생성하는 기본 설정은 package.json의 dependencies를 shared에 자동 주입한다.
js
// webpack.config.js
const deps = require("./package.json").dependencies;
new ModuleFederationPlugin({
shared: {
...deps, // 모든 dependencies를 shared로 등록
react: { singleton: true, requiredVersion: deps.react },
"react-dom": { singleton: true, requiredVersion: deps["react-dom"] },
},
});주의사항: 이 방식으로 모노레포 내부 패키지(workspace: 프로토콜)가 포함되면, 시맨틱 버전이 아닌 workspace:* 문자열이 requiredVersion에 들어가 Webpack 에러가 발생한다.
js
// 해결: 내부 패키지는 별도로 shared 설정
shared: {
...deps,
react: { singleton: true, requiredVersion: deps.react },
"shared-library": { singleton: true }, // 버전 지정하지 않음
},5. 실전 버전 관리 전략
프로덕션 권장 설정 예시
js
shared: {
// 핵심 런타임: singleton 필수
react: { singleton: true, requiredVersion: "^18.0.0" },
"react-dom": { singleton: true, requiredVersion: "^18.0.0" },
// 상태 관리: singleton 권장
"react-redux": { singleton: true, requiredVersion: "^8.0.0" },
// 유틸 라이브러리: 범위 버전으로 유연하게
lodash: { requiredVersion: "^4.17.0" },
// 모노레포 내부 패키지: singleton으로 단일 인스턴스 보장
"shared-library": { singleton: true },
}핵심 정리
| 항목 | 내용 |
|---|---|
| shared 역할 | 앱 간 공통 의존성의 중복 로드 방지 |
| singleton | true로 설정하면 전체 앱에서 하나의 인스턴스만 사용 (React 필수) |
| requiredVersion | 시맨틱 버전 범위로 호환 가능한 버전 지정 |
| eager | true면 초기 번들에 포함, false면 비동기 로드 (기본) |
| strictVersion | true면 버전 불일치 시 에러 발생 (기본은 warning) |
| 모노레포 주의 | workspace: 프로토콜이 shared에 유입되지 않도록 별도 처리 필요 |
| 버전 전략 | 프로젝트의 배포 정책과 팀 구조에 따라 전략 선택 |
다음 단계
- 상태 공유 - Context와 Redux에서 React Context와 Redux Store를 여러 마이크로앱에서 공유하는 패턴과 주의점을 학습한다