微前端架構概覽
什麼是 Micro-Frontend、為什麼需要它,以及主流架構模式的比較
Overview##
想像一個電商網站:首頁、商品頁、購物車、結帳、會員中心。在傳統的 monolithic frontend 架構下,這些全部打包在同一個 SPA 裡,由同一個團隊、同一個 repo、同一個 CI/CD pipeline 管理。
當團隊從 5 人長到 30 人,問題就來了:
- 一個人改了購物車的程式碼,整個網站都要重新 build 和部署
- 三個團隊要同時 merge 到同一個
mainbranch,衝突不斷 - 想把商品頁從 React 15 升級到 React 19,但購物車還沒準備好,只能一起等
Micro-Frontend 就是把後端微服務的概念搬到前端:每個功能區塊是獨立的應用,可以由不同團隊獨立開發、測試、部署。
Architecture##
核心原則###
graph TD
subgraph Monolith
A[Single SPA] --> B[Homepage]
A --> C[Product Page]
A --> D[Cart]
A --> E[Checkout]
end
subgraph Micro-Frontend
F[Shell / Host] --> G[Team A: Homepage]
F --> H[Team B: Product Page]
F --> I[Team C: Cart + Checkout]
end
Micro-Frontend 的核心原則:
| 原則 | 說明 |
|---|---|
| 獨立部署 | 每個 micro-frontend 可以單獨 build 和 deploy,不影響其他部分 |
| 團隊自治 | 每個團隊擁有自己的 repo、CI/CD、技術選型 |
| 技術無關 | Team A 用 React、Team B 用 Vue,甚至 Team C 用 Svelte 都行 |
| 隔離性 | 一個 micro-frontend 的 bug 不該讓整個網站崩潰 |
Note
Micro-Frontend 不是銀彈。它解決的是組織規模化的問題,不是技術問題。如果你的團隊只有 3-5 人,monolith 幾乎一定是更好的選擇。架構的複雜度應該匹配組織的複雜度。
主流整合模式###
實現 Micro-Frontend 有多種方式,每種都有不同的取捨:
1. iframe####
最古老也最簡單的方式 — 每個 micro-frontend 放在一個 <iframe> 裡。
<!-- Shell application -->
<nav><!-- global navigation --></nav>
<main>
<iframe src="https://team-a.example.com/product-page" />
</main>
優點: 完全隔離,技術完全無關,每個 iframe 是獨立的瀏覽器 context。
缺點: 效能差(每個 iframe 載入完整的 HTML/CSS/JS)、無法共享 state、SEO 困難、使用者體驗差(無法跨 iframe 做動畫或共享樣式)。
2. Web Components####
每個 micro-frontend 包裝成 Custom Element,透過 Shadow DOM 實現樣式隔離。
// Team B: Product Card as Web Component
class ProductCard extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: 'open' });
const productId = this.getAttribute('product-id');
shadow.innerHTML = `
<style>
.card { border: 1px solid #e5e7eb; padding: 16px; }
</style>
<div class="card">
<h3>Product ${productId}</h3>
<slot name="actions"></slot>
</div>
`;
}
}
customElements.define('product-card', ProductCard);
<!-- Shell: use the Web Component -->
<product-card product-id="42">
<button slot="actions">Add to Cart</button>
</product-card>
優點: 瀏覽器原生支援、樣式天然隔離、框架無關。
缺點: SSR 支援有限、跨 micro-frontend 共享狀態需要額外方案(Custom Events 或 shared store)、Shadow DOM 的樣式隔離有時反而讓全域主題很難套用。
3. Module Federation####
Webpack 5 / Rspack 內建的功能。每個 micro-frontend 是一個獨立的 webpack build,在 runtime 動態載入彼此的模組。
// Team A: expose a component
// webpack.config.ts
new ModuleFederationPlugin({
name: 'productApp',
filename: 'remoteEntry.js',
exposes: {
'./ProductCard': './src/components/ProductCard',
},
shared: {
react: { singleton: true, requiredVersion: '^18.0.0' },
'react-dom': { singleton: true, requiredVersion: '^18.0.0' },
},
});
// Shell: consume the remote component
const ProductCard = React.lazy(
() => import('productApp/ProductCard')
);
function App() {
return (
<React.Suspense fallback={<div>Loading...</div>}>
<ProductCard productId="42" />
</React.Suspense>
);
}
優點: 可以共享依賴(React 只載入一份)、開發體驗接近 monolith(直接 import)、支援 TypeScript 型別。
缺點: 綁定 webpack / Rspack 生態系、設定有學習門檻、shared dependency 版本衝突需要仔細管理。
模式比較###
| 維度 | iframe | Web Components | Module Federation |
|---|---|---|---|
| 隔離性 | 最強(獨立 context) | 強(Shadow DOM) | 中(shared scope) |
| 效能 | 差(重複載入) | 好 | 最好(共享依賴) |
| 共享狀態 | 困難 | Custom Events | 直接 import |
| 技術無關 | 完全 | 完全 | 限 webpack 生態 |
| 開發體驗 | 差 | 中 | 好(接近 monolith) |
| SSR | 困難 | 有限 | 支援 |
| 學習曲線 | 低 | 中 | 高 |
Tip
如何選擇? 如果團隊技術棧差異極大(React + Angular + jQuery legacy),用 iframe 或 Web Components。如果團隊都在 webpack 生態系內,Module Federation 是最佳選擇 — 效能最好、開發體驗最接近 monolith。
通訊模式###
不管用哪種整合方式,micro-frontend 之間總需要溝通。常見的做法:
graph LR
A[Product Page] -->|CustomEvent| B[Event Bus]
B -->|CustomEvent| C[Cart]
D[Shell] -->|Props / Attributes| A
D -->|Props / Attributes| C
E[Shared Store] <-->|subscribe| A
E <-->|subscribe| C
| 方式 | 適用場景 | 範例 |
|---|---|---|
| Props / Attributes | 父 → 子的單向資料流 | Shell 傳 userId 給子應用 |
| Custom Events | 鬆耦合的跨應用通知 | Product Page 發出 add-to-cart event |
| Shared Store | 需要同步的全域狀態 | 登入狀態、購物車數量 |
| URL / Router | 頁面級的導航 | Shell 統一管理路由 |
Warning
避免讓 micro-frontend 之間產生太多通訊。如果兩個 micro-frontend 需要頻繁交換資料,通常代表它們不該被拆開。Micro-Frontend 的邊界應該對齊業務邊界,而不是技術邊界。
Summary##
- Micro-Frontend 是前端的微服務架構。 每個功能區塊獨立開發、測試、部署,解決大型團隊的協作瓶頸。
- 三種主流整合模式: iframe(最隔離)、Web Components(瀏覽器原生)、Module Federation(最佳效能與開發體驗)。
- 選擇標準看團隊,不看技術。 如果團隊都在 webpack 生態系,Module Federation 是首選。
- 通訊越少越好。 如果兩個 micro-frontend 需要頻繁溝通,代表邊界切錯了。
- 不要為了架構而架構。 小團隊用 monolith,大團隊才需要 Micro-Frontend。
留言 (0)
登入後即可留言