Skip to content

noni2she/web-microfrontend

Repository files navigation

Web Microfrontend Framework

一個基於 Node.js 的通用微前端架構框架,支援多框架應用程式整合(React、Vue、Nuxt、Angular 等)。

🌟 特色功能

  • 🔌 多框架支援: 無縫整合不同前端框架(React、Vue、Nuxt、Angular 等)
  • 📡 事件通訊系統: 應用程式間的發布/訂閱事件通訊機制
  • 🔄 狀態同步: 跨框架的狀態管理同步(支援 Zustand、Pinia、Redux 等)
  • 🚦 路由管理: 智能路由分配和導航系統
  • 🐳 Docker 支援: 開發和生產環境的容器化部署
  • 🔧 TypeScript: 完整的類型支援和類型安全
  • 🏗️ 可擴展架構: 易於擴展和客製化的模組化設計

📁 專案結構

web-microfrontend/
├── src/                      # 核心框架原始碼
│   ├── core/                 # 核心功能模組
│   │   ├── EventCommunicator.ts    # 事件通訊系統
│   │   ├── RouteNavigator.ts       # 路由導航系統
│   │   ├── constants.ts            # 常數定義
│   │   └── stateSync/             # 狀態同步系統
│   │       ├── types.ts           # 類型定義
│   │       ├── StatePersistence.ts # 狀態持久化
│   │       ├── StoreAdapter.ts    # Store 適配器
│   │       ├── StoreRegistry.ts   # Store 註冊表
│   │       ├── StateSynchronizer.ts # 狀態同步器
│   │       ├── StatusProvider.ts  # 狀態監控
│   │       └── StoreSyncFacade.ts # 統一 API 門面
│   └── index.ts              # 主要匯出點
├── apps/                     # 應用程式目錄
│   ├── config/              # 共享配置
│   │   ├── routes.ts        # 路由配置
│   │   ├── events.ts        # 事件類型定義
│   │   └── state-mappings.ts # 狀態映射配置
│   ├── app1/                # 應用程式 1 (例如 React)
│   └── app2/                # 應用程式 2 (例如 Nuxt/Vue)
├── docker/                   # Docker 配置
│   ├── nginx.dev.conf       # 開發環境 Nginx 配置
│   ├── nginx.prod.conf      # 生產環境 Nginx 配置
│   ├── default.dev.conf.template  # 開發環境模板
│   ├── default.prod.conf.template # 生產環境模板
│   └── start.sh             # 啟動腳本
├── scripts/                  # 建構和工具腳本
│   ├── build.sh             # 建構腳本
│   ├── stop.sh              # 停止腳本
│   └── generate-nginx-config.js # Nginx 配置生成器
├── package.json             # 專案配置
├── tsconfig.json            # TypeScript 配置
├── compose.yaml             # Docker Compose 配置
├── Dockerfile               # Docker 映像定義
└── README.md                # 本文件

🚀 快速開始

前置需求

  • Node.js >= 18.0.0
  • pnpm >= 8.0.0
  • Docker (可選,用於容器化部署)
  • Docker Compose (可選,用於開發環境)

安裝

# 複製專案
git clone <repository-url>
cd web-microfrontend

# 安裝依賴
pnpm install

配置

1. 配置路由 (apps/config/routes.ts)

定義哪些路由應該由哪個應用程式處理:

export const app1Routes: string[] = ["/admin", "/dashboard"];

export const app2Routes: string[] = ["/shop", "/products"];

export const externalDomains: string[] = ["https://external-site.com"];

2. 定義事件類型 (apps/config/events.ts)

為應用程式間通訊定義自訂事件:

import { BaseEventTypes } from "@web-microfrontend/core";

export const AppEvents = {
  ...BaseEventTypes,
  USER_LOGIN: "app:user-login",
  USER_LOGOUT: "app:user-logout",
  NAVIGATION: "app:navigation",
} as const;

3. 配置狀態同步 (apps/config/state-mappings.ts)

定義應用程式間的狀態同步映射:

import type { StateMapping } from "@web-microfrontend/core";

export const stateMappings: StateMapping[] = [
  {
    sourceStore: "userStore",
    targetStore: "appStore",
    syncDirection: "bidirectional",
  },
];

開發

方式 1: 使用 Docker Compose(推薦)

# 開發模式
pnpm run dev

# 這會啟動:
# - Nginx (http://localhost)
# - App1 Dev Server (http://localhost:5173)
# - App2 Dev Server (http://localhost:8091)

方式 2: 本地開發

# 同時啟動兩個應用程式
pnpm run dev:local

# 或分別啟動
pnpm run dev:app1
pnpm run dev:app2

生產建構

# 建構生產版本
pnpm run build

# 或指定環境
./scripts/build.sh production
./scripts/build.sh qat
./scripts/build.sh uat

停止服務

# 停止開發環境
pnpm run stop

# 或停止特定環境
./scripts/stop.sh production
./scripts/stop.sh qat

📚 核心 API

EventCommunicator

應用程式間的事件通訊系統。

import { createCommunicator } from "@web-microfrontend/core";
import { AppEvents } from "./apps/config/events";

const communicator = createCommunicator<typeof AppEvents>();

// 發送事件
communicator.emit(AppEvents.USER_LOGIN, { userId: 123 });

// 監聽事件
const unsubscribe = communicator.on(AppEvents.USER_LOGIN, (data) => {
  console.log("User logged in:", data);
});

// 取消訂閱
unsubscribe();

RouteNavigator

智能路由管理和導航。

import { createRouteNavigator } from "@web-microfrontend/core";
import { app1Routes, app2Routes, externalDomains } from "./apps/config/routes";

const navigator = createRouteNavigator({
  app1Routes,
  app2Routes,
  externalDomains,
});

// 檢查路由歸屬
if (navigator.isApp1Route("/admin")) {
  // 由 App1 處理
}

// 執行導航
navigator.nativeNavigate("/admin");

// 在新分頁開啟
navigator.nativeNavigate("/external", { openInNewTab: true });

StoreSyncFacade

跨框架狀態同步系統,支援 Zustand、Pinia、Redux 等。

import { createGlobalStoreSyncFacade } from "@web-microfrontend/core";
import { stateMappings } from "./apps/config/state-mappings";

const syncFacade = createGlobalStoreSyncFacade(stateMappings);

// 註冊 stores (React with Zustand)
syncFacade.registerSource("userStore", useUserStore);

// 註冊 stores (Vue with Pinia)
syncFacade.registerTarget("appStore", useAppStore());

// 手動同步
syncFacade.sync("userStore", { user: { id: 1 } }, "source");

// 查看狀態
console.log(syncFacade.getStatus());
console.log(syncFacade.getStoreDetails());

// 持久化管理
syncFacade.saveState("userStore");
syncFacade.restoreState("userStore");
syncFacade.clearPersistedState();

// 清理
syncFacade.cleanup();

🏗️ 建立新的微前端應用程式

1. 建立 App1 (React 範例)

cd apps/app1
pnpm create vite . --template react-ts
pnpm install

在你的 React 應用中整合框架:

// main.tsx
import {
  createCommunicator,
  createRouteNavigator,
} from "@web-microfrontend/core";
import { AppEvents } from "../config/events";
import { app1Routes, app2Routes, externalDomains } from "../config/routes";

// 初始化通訊器
export const communicator = createCommunicator<typeof AppEvents>();

// 初始化路由導航器
export const navigator = createRouteNavigator({
  app1Routes,
  app2Routes,
  externalDomains,
});

// 使用範例
communicator.emit(AppEvents.USER_LOGIN, { userId: 123 });

navigator.nativeNavigate("/shop"); // 導航到 App2

2. 建立 App2 (Nuxt 範例)

cd apps/app2
pnpm dlx nuxi@latest init .
pnpm install

在你的 Nuxt 應用中整合框架:

// plugins/microfrontend.ts
import {
  createCommunicator,
  createGlobalStoreSyncFacade,
} from "@web-microfrontend/core";
import { AppEvents } from "../../config/events";
import { stateMappings } from "../../config/state-mappings";

export default defineNuxtPlugin(() => {
  const communicator = createCommunicator<typeof AppEvents>();
  const syncFacade = createGlobalStoreSyncFacade(stateMappings);

  // 註冊 Pinia store
  const appStore = useAppStore();
  syncFacade.registerTarget("appStore", appStore);

  // 監聽事件
  communicator.on(AppEvents.USER_LOGIN, (data) => {
    console.log("User logged in:", data);
  });

  return {
    provide: {
      communicator,
      syncFacade,
    },
  };
});

🔧 進階配置

自訂 Nginx 配置

修改 docker/default.dev.conf.templatedocker/default.prod.conf.template 來自訂 Nginx 行為。

環境變數

在應用程式目錄中建立環境檔案:

# apps/app1/.env.production
# apps/app2/.env.production

狀態轉換器

為不同框架間的資料格式差異配置轉換器:

export const stateMappings: StateMapping[] = [
  {
    sourceStore: "userStore",
    targetStore: "appStore",
    syncDirection: "bidirectional",
    transformer: {
      sourceToTarget: (data) => {
        // React (Zustand) → Vue (Pinia) 轉換
        return {
          ...data,
          timestamp: Date.now(),
        };
      },
      targetToSource: (data) => {
        // Vue (Pinia) → React (Zustand) 轉換
        const { timestamp, ...rest } = data;
        return rest;
      },
    },
  },
];

🐳 Docker 部署

開發環境

docker-compose up --build

生產環境

# 建構映像
docker build --build-arg ENV=production -t web-microfrontend:prod .

# 執行容器
docker run -d --name web-microfrontend -p 80:80 web-microfrontend:prod

📖 架構設計

本框架採用以下設計模式:

  1. 門面模式 (Facade Pattern): StoreSyncFacade 提供統一的 API
  2. 適配器模式 (Adapter Pattern): StoreAdapter 統一不同狀態管理函式庫的介面
  3. 註冊表模式 (Registry Pattern): StoreRegistry 管理 store 實例
  4. 觀察者模式 (Observer Pattern): 事件通訊和狀態同步
  5. 單例模式 (Singleton Pattern): 全域實例管理

狀態同步流程

App1 (Zustand) ──┐
                 ├──> StoreAdapter ──> StateSynchronizer ──> StoreAdapter ──> App2 (Pinia)
                 └──> StatePersistence (SessionStorage) ─────────────────────┘

路由處理流程

Request ──> Nginx ──> 路由規則判斷 ──┬──> App1 (React)
                                     └──> App2 (Nuxt) [預設]

🤝 貢獻

歡迎提交 Issue 和 Pull Request!

📝 授權

MIT License

🔗 相關資源

❓ 常見問題

Q: 如何新增更多應用程式?

A: 在 apps/ 目錄下建立新的應用程式資料夾,並在 apps/config/routes.ts 中配置路由。

Q: 支援哪些狀態管理函式庫?

A: 目前支援 Zustand 和 Pinia,可透過實作 GenericStore 介面來支援其他函式庫。

Q: 如何除錯狀態同步問題?

A: 使用 syncFacade.getStatus()syncFacade.getStoreDetails() 來檢查同步狀態。

Q: 可以在生產環境中使用嗎?

A: 是的,框架已包含完整的生產環境建構和部署配置。

🎯 路線圖

  • 支援更多狀態管理函式庫 (Redux, MobX)
  • 改善文件和範例
  • 效能監控和分析工具
  • CLI 工具用於快速建立新專案
  • 單元測試和整合測試
  • CI/CD 範例配置

Built with ❤️ for modern web development

About

No description, website, or topics provided.

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published