Files
novalon-website/docs/plans/2026-03-28-monorepo-multi-site-architecture.md
T
张翔 e6e3f79a2b feat: 更新项目配置和文档,优化UI样式和CI配置
- 从tsconfig.json中移除测试文件排除规则
- 优化错误边界组件的min-h样式
- 修正about-section中的引号转义和背景样式
- 更新woodpecker.yml中的release分支匹配模式
- 新增monorepo多站点架构设计方案文档
2026-03-28 14:39:28 +08:00

9.9 KiB
Raw Blame History

Monorepo 多站点架构设计方案

背景

当企业需要为多个产品/项目创建独立展示时,面临架构选择:单独页面 vs 独立网站

经过需求分析,确定以下约束条件:

维度 需求 架构影响
产品数量 动态增长,未来持续增加 需要高可扩展性
品牌关系 独立子品牌 需要视觉独立性
团队规模 1-2人精简团队 需要低维护成本
SEO要求 高要求,独立域名 需要独立部署能力

方案对比

方案A:独立网站(多仓库)

┌─────────────────┐  ┌─────────────────┐  ┌─────────────────┐
│  产品A (独立仓库) │  │  产品B (独立仓库) │  │  产品C (独立仓库) │
│  product-a.com  │  │  product-b.com  │  │  product-c.com  │
└─────────────────┘  └─────────────────┘  └─────────────────┘

优点:完全独立、SEO最优、互不影响 缺点 维护成本极高、代码重复严重、安全更新繁琐

方案B:单站内嵌页面

┌──────────────────────────────────────────────────────┐
│              novalon.cn (主站)                        │
│  ┌────────────┐ ┌────────────┐ ┌────────────┐       │
│  │ /product-a │ │ /product-b │ │ /product-c │       │
│  └────────────┘ └────────────┘ └────────────┘       │
└──────────────────────────────────────────────────────┘

优点:维护成本最低、部署简单 缺点 无法独立域名、SEO受限、品牌独立性差

方案CMonorepo多站点架构 推荐

┌─────────────────────────────────────────────────────────┐
│                    Monorepo (统一仓库)                   │
├─────────────────────────────────────────────────────────┤
│  apps/                                                  │
│    ├── main-site/      → novalon.cn                    │
│    ├── product-a/      → product-a.com (独立域名)       │
│    ├── product-b/      → product-b.com (独立域名)       │
│    └── product-c/      → product-c.com (独立域名)       │
│                                                         │
│  packages/  (共享代码)                                   │
│    ├── ui/             → 共享组件库                      │
│    ├── config/         → 共享配置                        │
│    └── utils/          → 共享工具函数                    │
└─────────────────────────────────────────────────────────┘

技术设计

目录结构

novalon-website/
├── apps/                          # 应用层(独立部署)
│   ├── main-site/                 # 主站 → novalon.cn
│   │   ├── src/
│   │   ├── next.config.ts
│   │   └── package.json
│   │
│   └── products/                  # 产品站点集合
│       ├── [product-slug]/        # 产品模板(可复制)
│       │   ├── src/
│       │   ├── public/
│       │   ├── next.config.ts
│       │   └── package.json
│       └── ...
│
├── packages/                      # 共享层(不独立部署)
│   ├── ui/                        # 共享组件库
│   │   ├── components/
│   │   │   ├── base/              # 基础组件(Button、Card等)
│   │   │   └── layout/            # 布局组件(Header、Footer等)
│   │   └── package.json
│   │
│   ├── config/                    # 共享配置
│   │   ├── tailwind/              # Tailwind预设
│   │   ├── eslint/                # ESLint规则
│   │   └── typescript/            # TS配置
│   │
│   └── utils/                     # 共享工具
│       ├── lib/
│       └── package.json
│
├── turbo.json                     # Turborepo配置
├── pnpm-workspace.yaml            # pnpm工作区配置
└── package.json                   # 根package.json

共享组件库设计

packages/ui/
├── components/
│   ├── base/                      # 基础组件(完全共享)
│   │   ├── button/
│   │   ├── card/
│   │   ├── input/
│   │   └── ...
│   │
│   └── themed/                    # 主题化组件(可覆盖)
│       ├── header/
│       └── footer/
│
├── themes/                        # 主题配置
│   ├── default.ts                 # 默认主题
│   ├── product-a.ts               # 产品A主题
│   └── product-b.ts               # 产品B主题
│
└── lib/
    └── theme-context.tsx          # 主题上下文

组件分层策略

组件类型 共享程度 定制方式
基础组件 100%共享 通过 props 和 CSS 变量覆盖样式
布局组件 接口共享 各应用可提供自己的实现
业务组件 不共享 各应用独立开发

CI/CD 流水线

[代码推送] → [变更检测] → [增量构建] → [并行测试] → [智能部署]
                ↓              ↓              ↓
          哪些应用变了?    只构建变的应用    只部署变的应用

部署策略

场景 构建范围 部署范围
只改了 apps/product-a 只构建 product-a 只部署 product-a
改了 packages/ui 构建所有应用 部署所有应用
改了 packages/config 构建所有应用 部署所有应用

SEO优化策略

独立域名架构

┌─────────────────────────────────────────────────────────────┐
│                      Nginx 反向代理                          │
├─────────────────────────────────────────────────────────────┤
│  novalon.cn          → 主站容器 (localhost:3000)            │
│  product-a.com       → 产品A容器 (localhost:3001)           │
│  product-b.com       → 产品B容器 (localhost:3002)           │
└─────────────────────────────────────────────────────────────┘

SEO关键优势

SEO 要素 独立站点优势
独立域名 搜索引擎视为独立实体,权重互不影响
独立 sitemap 精准控制索引范围,提升爬取效率
独立 metadata 针对产品特性优化关键词,避免稀释
独立 robots.txt 灵活控制爬虫访问策略

迁移路径

阶段1: 基础设施搭建 (1-2天)
    ↓
阶段2: 代码迁移与重构 (3-5天)
    ↓
阶段3: 共享组件抽取 (2-3天)
    ↓
阶段4: CI/CD 配置 (1-2天)
    ↓
阶段5: 第一个产品站点 (2-3天)

阶段1:基础设施搭建

# 1. 创建 Monorepo 根目录结构
mkdir -p apps packages

# 2. 初始化 pnpm 工作区
cat > pnpm-workspace.yaml << EOF
packages:
  - 'apps/*'
  - 'apps/products/*'
  - 'packages/*'
EOF

# 3. 安装 Turborepo
pnpm add -Dw turbo

阶段2:代码迁移

# 将现有代码移动到 apps/main-site
mv src apps/main-site/src
mv public apps/main-site/public
mv next.config.ts apps/main-site/

阶段3:共享组件抽取

# 创建共享 UI 包
mkdir -p packages/ui/components

# 抽取通用组件
mv apps/main-site/src/components/ui packages/ui/components/base

阶段4:创建产品站点

# 复制主站作为模板
cp -r apps/main-site apps/products/product-template

# 创建新产品站点
cp -r apps/products/product-template apps/products/product-a

决策总结

评估维度 独立网站 单站内嵌页面 Monorepo多站点
独立品牌支持 完美 完美
SEO独立性 最优 受限 最优
维护成本 极高 最低
代码复用 完全 高度复用
扩展性 ⚠️ 中等 优秀
团队适配 不适合精简团队 ⚠️ 不满足需求 完美适配

结论

针对动态增长 + 独立子品牌 + 精简团队 + 高SEO要求的场景,Monorepo多站点架构是最佳选择:

  • 品牌独立:每个产品独立应用、独立域名、独立视觉
  • SEO最优:独立sitemap、独立metadata、独立域名权重
  • 维护高效:共享代码库、统一依赖、一次更新全局生效
  • 扩展简单:新增产品只需复制模板目录
  • 智能CI/CD:增量构建、按需部署、自动化流水线