阅读视图

发现新文章,点击刷新页面。

微前端架构下的平台级公共组件资源体系设计

二、核心分层设计(对标阿里 Fusion / 字节 Semi / 腾讯 TDesign)

L0 — Design Token(设计令牌层)

职责:统一视觉语言,与 UI 框架解耦

@cmc/design-tokens
├── colors.css          # CSS Variables
├── spacing.css
├── typography.css
├── shadows.css
├── tokens.json         # Style Dictionary 源文件(可生成多端产物)
└── index.ts            # JS/TS 常量导出
  • Style Dictionary 管理,一份源数据 → 输出 CSS Variables / SCSS / TS / Figma Plugin
  • Element Plus 主题通过覆盖 --el-* 变量接入,各子应用无需各自配置
  • 由基座注入全局 CSS Variables,子应用继承

L1 — 基础增强组件层

职责:Element Plus 二次封装 + 原子级通用组件

@cmc/ui
├── CmcTable/           # 增强表格(列配置化、分页内聚、虚拟滚动)
├── CmcForm/            # 配置化表单(JSON Schema 驱动)
├── CmcUpload/          # 统一上传(OSS/本地/断点续传)
├── CmcDialog/          # 增强弹窗(拖拽/全屏/promise化)
├── CmcSearch/          # 搜索栏(折叠/展开/记忆)
├── CmcDescription/     # 详情描述列表
├── CmcPermission/      # 权限指令/组件
└── ...

关键设计原则

  • Props 透传v-bind="$attrs" 全量透传 Element Plus 原生属性,不做阉割
  • 插槽穿透:暴露原组件所有 slot,保证可扩展性
  • 类型完备:每个组件导出 Props / Emits / Expose 类型定义
  • 无业务逻辑:纯 UI 层,不含接口调用

L2 — 业务组件层

职责:跨系统复用的业务功能单元

@cmc/biz-components
├── ShipmentSelector/      # 船期选择器
├── PortPicker/            # 港口选择器(含模糊搜索+常用)
├── CustomerSearch/        # 客户搜索组件
├── ApprovalFlow/          # 审批流展示
├── FilePreview/           # 统一文件预览
└── ...
  • 允许内置接口调用,但通过 依赖注入 抽象 API 层(不硬编码域名/路径)
  • 通过 provide/inject 或 props 传入 API adapter

L3 — Pro 区块/模板层

职责:页面级可复用布局模式

@cmc/pro-components
├── ProTable/          # 搜索 + 表格 + 分页 + 工具栏 一体化
├── ProForm/           # 分步表单 / 弹窗表单 / 抽屉表单
├── ProLayout/         # 标准页面布局框架
├── ProDetail/         # 标准详情页
└── CrudTemplate/      # CRUD 页面生成器

三、微前端共享机制(核心难点)

方案:Module Federation + npm 包双轨制

┌──────────────────────────────────────────────────────┐
│                    分发策略矩阵                        │
├──────────────┬──────────────┬────────────────────────┤
│   组件层级    │   分发方式    │        理由            │
├──────────────┼──────────────┼────────────────────────┤
│ L0 Token     │ npm 包       │ 构建时确定,极少变更     │
│ L1 基础组件   │ npm 包       │ 稳定,需要类型推导      │
│ L2 业务组件   │ MF Remote    │ 变更频繁,需要热更新     │
│ L3 Pro 区块   │ npm 包       │ 需要 Tree-shaking      │
├──────────────┼──────────────┼────────────────────────┤
│ 紧急热修复    │ MF Remote    │ 一次发布,全部生效       │
└──────────────┴──────────────┴────────────────────────┘

Module Federation 关键架构

                    ┌───────────────────────┐
                    │   Component Service    │
                    │   (独立部署的组件服务)   │
                    │                       │
                    │  remoteEntry.js        │
                    │  ├── CmcUpload        │
                    │  ├── ApprovalFlow     │
                    │  └── ShipmentSelector │
                    └───────────┬───────────┘
                                │
              ┌─────────────────┼─────────────────┐
              ▼                 ▼                   ▼
     ┌────────────┐    ┌────────────┐      ┌────────────┐
     │  供应商门户  │    │  运营后台   │      │  客户门户   │
     │  (Consumer) │    │  (Consumer) │      │  (Consumer) │
     └────────────┘    └────────────┘      └────────────┘

Vite 集成配置@module-federation/vite):

// Component Service(Remote 端)
// vite.config.ts
import { federation } from '@module-federation/vite'

export default defineConfig({
  plugins: [
    federation({
      name: 'cmc_shared_ui',
      filename: 'remoteEntry.js',
      exposes: {
        './CmcUpload': './src/components/CmcUpload/index.vue',
        './ApprovalFlow': './src/components/ApprovalFlow/index.vue',
      },
      shared: {
        vue: { singleton: true },
        'element-plus': { singleton: true },
        pinia: { singleton: true },
      },
    }),
  ],
})
// 子应用(Consumer 端)
// vite.config.ts
federation({
  name: 'supplier_portal',
  remotes: {
    cmc_shared_ui: {
      type: 'module',
      name: 'cmc_shared_ui',
      // 通过 manifest 实现版本管理 + 灰度
      entry: 'https://static.cmclink.com/shared-ui/remoteEntry.js',
    },
  },
  shared: {
    vue: { singleton: true },
    'element-plus': { singleton: true },
  },
})

降级兜底策略(生产必备)

// useRemoteComponent.ts — 加载远程组件,失败回退本地
import { defineAsyncComponent, h } from 'vue'

export function useRemoteComponent(
  remoteName: string,
  localFallback: () => Promise<any>,
) {
  return defineAsyncComponent({
    loader: async () => {
      try {
        const module = await import(/* @vite-ignore */ `cmc_shared_ui/${remoteName}`)
        return module.default || module
      } catch (e) {
        console.warn(`[MF] Remote ${remoteName} 加载失败,回退本地版本`, e)
        const fallback = await localFallback()
        return fallback.default || fallback
      }
    },
    loadingComponent: () => h('div', { class: 'animate-pulse h-8 bg-gray-100 rounded' }),
    timeout: 5000,
  })
}

// 使用
const CmcUpload = useRemoteComponent(
  'CmcUpload',
  () => import('@cmc/ui/CmcUpload'), // npm 包兜底
)

四、版本治理与自动升级

┌───────────┐     push      ┌───────────┐    publish    ┌──────────┐
│ @cmc/ui   │ ──────────▶  │   CI/CD    │ ──────────▶  │ 私有 npm  │
│ 组件仓库   │              │ changesets │              │ Registry │
└───────────┘              └─────┬─────┘              └────┬─────┘
                                 │                          │
                                 │ trigger                  │ Renovate Bot
                                 ▼                          ▼
                          ┌─────────────┐          ┌──────────────┐
                          │ Storybook   │          │ 各子应用仓库   │
                          │ 自动部署     │          │ 自动提 PR      │
                          └─────────────┘          │ patch 自动合并  │
                                                   │ minor 人工审核  │
                                                   └──────────────┘

关键配置

  • changesets:语义化版本 + 自动 CHANGELOG
  • Renovate Bot:每日扫描依赖更新,自动 PR + 自动跑 CI
  • patch 自动合并:配置 Renovate automerge: true for patch
  • minor/major:需人工审核 PR 后合并

五、质量保障体系

环节 工具 说明
单元测试 Vitest + Vue Test Utils 每个 L1/L2 组件 ≥80% 覆盖率
视觉回归 Chromatic / Percy Storybook 截图对比,防止样式劣化
文档验收 Storybook / Histoire 每个组件必须有在线可交互 Demo
类型检查 vue-tsc --noEmit CI 卡口,类型不通过不允许发布
Bundle 分析 rollup-plugin-visualizer 防止包体积膨胀
API 兼容性 api-extractor 导出 API 变更自动检测 + 审批

六、仓库结构建议(pnpm workspace monorepo)

cmc-platform-ui/
├── pnpm-workspace.yaml
├── turbo.json                    # Turborepo 任务编排
├── .changeset/                   # changesets 配置
│
├── packages/
│   ├── design-tokens/            # @cmc/design-tokens (L0)
│   │   ├── tokens.json
│   │   └── package.json
│   │
│   ├── ui/                       # @cmc/ui (L1)
│   │   ├── src/
│   │   │   ├── CmcTable/
│   │   │   ├── CmcForm/
│   │   │   └── index.ts
│   │   ├── package.json
│   │   └── tsup.config.ts
│   │
│   ├── biz-components/           # @cmc/biz-components (L2)
│   │   ├── src/
│   │   └── package.json
│   │
│   ├── pro-components/           # @cmc/pro-components (L3)
│   │   ├── src/
│   │   └── package.json
│   │
│   └── shared/                   # @cmc/shared (工具函数/类型/常量)
│       ├── src/
│       └── package.json
│
├── apps/
│   ├── storybook/                # 组件文档站
│   └── mf-host/                  # Module Federation 组件服务
│       ├── src/
│       └── vite.config.ts
│
└── configs/                      # 共享配置
    ├── eslint-config/
    ├── tsconfig/
    └── tailwind-config/

七、与大厂方案对标

维度 阿里(Fusion/IceWork) 字节(Semi/Garfish) 本方案
设计令牌 Fusion Token Semi Token @cmc/design-tokens
基础组件 Fusion Next Semi Design @cmc/ui
业务组件 金融云物料 内部 Biz @cmc/biz-components
区块模板 IceWork 物料 Semi Pro @cmc/pro-components
微前端 qiankun Garfish Module Federation
共享策略 npm + CDN npm + MF npm + MF 双轨
自动升级 内部机器人 内部机器人 Renovate Bot
文档 Fusion Site Semi Site Storybook/Histoire

八、落地路径(推荐 3 个阶段)

Phase 1(1~2 周):基座搭建

  • 建 monorepo、配置 pnpm workspace + Turborepo
  • 迁移 5~10 个最高频 L1 组件
  • 接通 changesets + 私有 npm 发布

Phase 2(3~4 周):生态完善

  • Storybook 文档站上线
  • 接入 Renovate Bot 自动升级
  • 各子应用替换本地 copy → npm 依赖

Phase 3(5~8 周):高阶能力

  • L2 业务组件接入 Module Federation
  • 视觉回归测试
  • ProTable/ProForm 等 L3 组件建设

❌