Skip to content
⚠️ This article was written in 2021. Some content may be outdated.

微前端架構設計思考:不只是技術選型

今年團隊在推進一個大型 B 端平臺的微前端改造,從最初的單體 Vue 應用拆分成 6 個子應用。技術選型用了 qiankun,但真正讓我學到東西的不是接入過程,而是架構設計階段的決策。

什麼時候該上微前端

微前端不是銀彈。見過太多團隊為了微前端而微前端,最後反而增加了複雜度。我們判斷是否需要微前端的標準:

需要微前端的訊號:
- 團隊 >3 個,各自獨立迭代,釋出週期不同
- 技術棧無法統一(歷史包袱)
- 需要漸進式遷移舊系統
- 子系統間需要保持統一的使用者體驗

不需要微前端:
- 團隊小,能協調發布
- 模組間邊界清晰,獨立部署也行
- 純前端路由的單體應用,用程式碼分割就夠了

我們的情況是:3 個團隊維護 6 個子系統,釋出頻率從每週到每月不等,必須拆分。

應用拆分策略

一開始我們按業務域拆分,效果不好。後來總結出的經驗是按兩個維度考慮:

javascript
// 拆分粒度參考
const splitStrategy = {
  // 維度一:團隊邊界
  teamOwnership: '每個子應用必須有明確的負責團隊',

  // 維度二:獨立性
  independence: '子應用應該能獨立開發、測試、部署',

  // 反模式:按頁面拆分
  antiPattern: '一個路由 = 一個子應用,會導致子應用過多'
}

最終我們按業務域 + 團隊邊界拆分:使用者中心、訂單系統、資料看板、運營後臺、客服工具、基礎元件。

共享層設計

這是最容易踩坑的地方。子應用之間有很多共享的東西:使用者資訊、許可權資料、公共元件、工具函式。我們的方案是分層設計:

javascript
// shared/ 是所有子應用的公共依賴層
// 使用 pnpm workspace 管理

// packages/shared-utils/src/index.ts
export { request } from './request'
export { useAuth } from './auth'
export { formatCurrency, formatDate } from './format'

// packages/shared-components/src/index.ts
export { DataTable } from './DataTable'
export { SearchForm } from './SearchForm'
export { PageContainer } from './PageContainer'

// 子應用通過 pnpm workspace 引用
// apps/order-system/package.json
{
  "dependencies": {
    "@company/shared-utils": "workspace:*",
    "@company/shared-components": "workspace:*"
  }
}

關鍵決策:共享層版本用 workspace:* 固定在最新,所有子應用統一發布,避免版本碎片化。

狀態通訊方案

子應用之間的通訊是最需要剋制的地方。我們的原則是:能不通訊就不通訊,必須通訊走主應用:

javascript
// 主應用:全域性狀態中心
// 用 CustomEvent 實現,不引入額外依賴
class GlobalStore {
  constructor() {
    this.state = {}
    this.listeners = {}
  }

  set(key, value) {
    this.state[key] = value
    window.dispatchEvent(
      new CustomEvent(`store:${key}`, { detail: value })
    )
  }

  get(key) {
    return this.state[key]
  }

  on(key, callback) {
    window.addEventListener(`store:${key}`, (e) => callback(e.detail))
    return () => window.removeEventListener(`store:${key}`, callback)
  }
}

// 子應用中使用
const store = window.__GLOBAL_STORE__
store.on('currentUser', (user) => {
  // 響應使用者資訊變化
  refreshPermissions(user.id)
})

小結

  • 微前端的價值不在技術,在於團隊協作效率的提升
  • 拆分粒度按團隊邊界而非頁面粒度
  • 共享層設計決定後續維護成本,需要嚴格管控
  • 狀態通訊要剋制,優先通過 URL 和共享儲存同步
  • 漸進式遷移比一步到位更安全

MIT Licensed