f8b21af4be
10_Wiki/Topics 대규모 정리: - 오류 캡처/미완성 stub 문서 227개 제거 - 교차폴더 중복 43클러스터 병합 (63파일 → redirect) - 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건 - 카테고리 MOC 6개 신규 생성 - Graph 섹션 미해결 related-keyword 링크 10,058건 제거 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.9 KiB
7.9 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-micro-frontends | Micro frontends | 10_Wiki/Topics | verified | self |
|
none | A | 0.9 | applied |
|
2026-05-10 | pending |
|
Micro frontends
매 한 줄
"매 microservices 매 frontend 적용 — 매 large UI 매 independent deployable team-owned vertical slices 매 분할". ThoughtWorks Tech Radar (2016) 매 이름 채택, 매 Webpack 5 Module Federation (2020) 매 mainstream 진입, 매 2026 매 large enterprise frontend (Spotify, IKEA, DAZN) 매 standard, 매 Vite Module Federation + Native Federation 매 modern stack.
매 핵심
매 핵심 가치 (vs monolith)
- Independent deploy: 매 team 매 자기 slice 매 release pipeline.
- Tech heterogeneity: 매 React + Vue + Svelte 매 공존 (단 cost ↑).
- Team scalability: 매 vertical team ownership — 매 Conway's law 매 align.
- Incremental migration: 매 legacy → modern 매 점진적 교체.
매 cost
- Bundle duplication: 매 framework 매 여러 번 load.
- Cross-MFE state: 매 shared store 매 design.
- Routing coordination: 매 shell + child route 매 sync.
- Versioning skew: 매 shared dep 매 version conflict.
- DX overhead: 매 dev 매 multi-repo / multi-server.
매 composition strategies
- Build-time: npm package — 매 monorepo + 매 publish (closest to monolith).
- Server-side: SSI/ESI/Tailor — 매 edge composition (Podium, Mosaic).
- Run-time iframe: 매 ultimate isolation — 매 worst UX.
- Run-time Web Components: 매 framework-agnostic embed.
- Run-time Module Federation (Webpack 5 / Vite): 매 sharing dep + dynamic import — 매 dominant 2026.
- Run-time Single-SPA: 매 lifecycle orchestration framework.
매 응용
- Large e-commerce (header/cart/product/checkout 매 별도 team).
- Multi-tenant SaaS (workspace + apps marketplace).
- Legacy modernization (strangler fig pattern).
- White-label platforms (per-customer customization).
💻 패턴
Webpack Module Federation — host (shell)
// shell/webpack.config.js
const { ModuleFederationPlugin } = require('webpack').container
module.exports = {
plugins: [
new ModuleFederationPlugin({
name: 'shell',
remotes: {
cart: 'cart@https://cart.example.com/remoteEntry.js',
product: 'product@https://product.example.com/remoteEntry.js',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
}),
],
}
Module Federation — remote (cart MFE)
// cart/webpack.config.js
new ModuleFederationPlugin({
name: 'cart',
filename: 'remoteEntry.js',
exposes: {
'./CartWidget': './src/CartWidget',
'./useCart': './src/hooks/useCart',
},
shared: {
react: { singleton: true },
'react-dom': { singleton: true },
},
})
Host consume (React lazy)
// shell/App.tsx
import React, { lazy, Suspense } from 'react'
const CartWidget = lazy(() => import('cart/CartWidget'))
export function App() {
return (
<div>
<Header />
<Suspense fallback={<div>Loading cart…</div>}>
<CartWidget />
</Suspense>
</div>
)
}
Vite Module Federation
// cart/vite.config.ts
import federation from '@originjs/vite-plugin-federation'
export default {
plugins: [
federation({
name: 'cart',
filename: 'remoteEntry.js',
exposes: { './CartWidget': './src/CartWidget.tsx' },
shared: ['react', 'react-dom'],
}),
],
build: { target: 'esnext', minify: false, cssCodeSplit: true },
}
Single-SPA root config
// root-config/index.ts
import { registerApplication, start } from 'single-spa'
registerApplication({
name: '@org/cart',
app: () => System.import('@org/cart'),
activeWhen: ['/cart'],
})
registerApplication({
name: '@org/product',
app: () => System.import('@org/product'),
activeWhen: ['/products'],
})
start()
Single-SPA child lifecycle
// cart-app/src/main.ts
import { h, createApp } from 'vue'
import singleSpaVue from 'single-spa-vue'
import Root from './Root.vue'
const lifecycles = singleSpaVue({
createApp,
appOptions: { render: () => h(Root) },
})
export const bootstrap = lifecycles.bootstrap
export const mount = lifecycles.mount
export const unmount = lifecycles.unmount
Web Components 매 framework-agnostic embed
// cart-mfe.ts
class CartElement extends HTMLElement {
connectedCallback() {
const root = this.attachShadow({ mode: 'open' })
// mount React/Vue/Svelte into shadow DOM
mountReact(<CartWidget />, root)
}
disconnectedCallback() { unmountReact(this.shadowRoot!) }
}
customElements.define('app-cart', CartElement)
<!-- 매 host page (any framework) -->
<script src="https://cart.example.com/cart.js" type="module"></script>
<app-cart></app-cart>
Cross-MFE communication — Custom Events
// 매 publish
window.dispatchEvent(new CustomEvent('cart:item-added', {
detail: { sku: 'A123', qty: 1 },
}))
// 매 subscribe
window.addEventListener('cart:item-added', (e) => {
console.log('item added:', (e as CustomEvent).detail)
})
Shared shell store (BroadcastChannel)
const channel = new BroadcastChannel('app-state')
// MFE A
channel.postMessage({ type: 'auth/login', user })
// MFE B
channel.onmessage = ({ data }) => {
if (data.type === 'auth/login') updateLocalState(data.user)
}
CSS isolation strategies
1. Shadow DOM (Web Components 매 자동 scope)
2. CSS Modules (build-time hash)
3. CSS-in-JS (runtime scope, e.g., styled-components)
4. PostCSS namespace plugin (legacy)
5. Tailwind prefix per MFE: `tw-cart-`, `tw-product-`
매 결정 기준
| 상황 | Approach |
|---|---|
| Single team, single product | Monolith (MFE overkill) |
| Multiple teams, shared shell | Module Federation |
| Legacy → React migration | iframe → Web Components → MF |
| Framework heterogeneity | Web Components / Single-SPA |
| Maximum isolation (security) | iframe (last resort) |
| Tight budget (LCP critical) | Build-time composition |
| SSR + MFE | Server-side composition (Tailor, Mosaic) |
| Vite stack | Native Federation / vite-plugin-federation |
기본값: 매 React/Vue 균일 stack 매 Module Federation, 매 framework 혼재 매 Single-SPA + Web Components.
🔗 Graph
- 부모: 프론트엔드_및_UIUX_표준 · Microservices
- 변형: Module-Federation · Web-Components
- Adjacent: Monorepo · Vite
🤖 LLM 활용
언제: 매 large team (50+ FE devs), 매 independent deploy 필요, 매 legacy modernization, 매 multi-tenant white-label. 언제 X: 매 small team (<10), 매 single-page simple SPA, 매 LCP-critical landing — 매 monolith 적합.
❌ 안티패턴
- 매 component-level MFE: 매 button 매 MFE — 매 latency overhead — 매 vertical slice 매 단위.
- Shared global state via window: 매 race condition + 매 hidden coupling.
- Framework version skew: 매 React 17 + 18 매 host — 매 hooks 깨짐.
- No design system: 매 visual inconsistency — 매 shared tokens/components 필수.
- Synchronous load chain: 매 cascade waterfall — 매 lazy + 매 parallel 매 host.
- MFE 매 small team 매 도입: 매 over-engineering — 매 monolith + 매 module boundary 매 충분.
🧪 검증 / 중복
- Verified (ThoughtWorks Tech Radar, micro-frontends.org, Module Federation docs).
- 신뢰도 A.
🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — composition strategies + MF/Single-SPA/WC patterns + comm matrix |