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

256 lines
9.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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:基础设施搭建
```bash
# 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:代码迁移
```bash
# 将现有代码移动到 apps/main-site
mv src apps/main-site/src
mv public apps/main-site/public
mv next.config.ts apps/main-site/
```
### 阶段3:共享组件抽取
```bash
# 创建共享 UI 包
mkdir -p packages/ui/components
# 抽取通用组件
mv apps/main-site/src/components/ui packages/ui/components/base
```
### 阶段4:创建产品站点
```bash
# 复制主站作为模板
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:增量构建、按需部署、自动化流水线