Files
makemd/archive/handover/js-fullstack-architecture.md
wurenzhi 136c2fa579 feat: 初始化项目结构并添加核心功能模块
- 新增文档模板和导航结构
- 实现服务器基础API路由和控制器
- 添加扩展插件配置和前端框架
- 引入多租户和权限管理模块
- 集成日志和数据库配置
- 添加核心业务模型和类型定义
2026-03-17 22:07:19 +08:00

25 KiB
Raw Blame History

JS+JS 全栈架构技术方案 (V2.0)

版本V2.0
更新日期2026-03-15
状态:优化版

1. 概述

本文档为 Crawlful Hub 项目提供完整的 JavaScript 全栈技术架构方案涵盖前端框架选型、后端技术栈、数据库设计、API 规范、开发流程及部署策略。本方案基于项目现有技术基底UmiJS + Node.js + MySQL + TypeScript进行系统性技术升级与规范化。

1.1 架构目标

  • 技术统一:前后端均采用 JavaScript/TypeScript实现代码复用与团队技能统一
  • 开发效率:提升前后端协作效率,减少技术栈切换成本
  • 可维护性:建立清晰的代码分层与模块化架构
  • 性能优化:构建高性能、高可用的企业级应用
  • 务实可靠:去除 AI 概念,采用成熟稳定的规则引擎方案

1.2 方案边界

本方案适用于以下业务场景:

  • 电商中台前端控制台Console开发
  • 后端 RESTful API 服务
  • 实时数据交互与状态管理
  • 多租户 SaaS 平台架构

2. 可行性分析

2.1 技术可行性评估

2.1.1 运行时环境

技术组件 版本要求 状态
Node.js >= 20.x LTS 现有技术栈
npm / yarn >= 9.x 现有技术栈
TypeScript >= 5.x 现有技术栈
MySQL 8.0+ 现有技术栈
Redis 6.0+ 现有技术栈

结论:项目基础设施已具备 JS+JS 全栈开发条件,无需额外环境搭建。

2.1.2 团队能力矩阵

角色 当前技能 全栈扩展成本
前端开发 React/Vue/UmiJS 低(框架同源)
后端开发 Node.js/Express/Koa 低(语言统一)
全栈工程师 兼前端+后端 极低(技术同源)

结论TypeScript 作为粘合语言,可实现前后端代码无缝衔接,团队学习成本可控。

2.2 业务可行性评估

2.2.1 业务复杂度适配

业务模块 复杂度 技术方案
订单管理 Node.js + MySQL 事务
实时爬虫 中高 Node.js 异步流处理
数据分析 Node.js + Redis 缓存
规则引擎 Node.js + 业务规则库

结论Node.js 单线程模型适用于 IO 密集型业务,配合 Worker Threads 可处理 CPU 密集型任务。

2.3 风险预判

风险项 等级 缓解措施
后端单线程性能瓶颈 集群模式 + 负载均衡
前后端代码耦合 明确分层架构 + Monorepo 管理
TypeScript 类型扩散 统一 shared types 包

3. 技术选型标准

3.1 选型原则

3.1.1 核心选型标准

  1. 成熟度优先:选择社区活跃、文档完善的稳定版本
  2. 生态兼容:优先选择与现有技术栈兼容的方案
  3. 性能优先:针对关键路径进行性能基准测试
  4. 维护可持续:评估维护周期与社区活跃度
  5. 务实可靠:优先选择经过大规模验证的方案

3.1.2 技术债务控制

  • 禁止引入已停止维护超过 12 个月的开源库
  • 核心依赖需有企业级支持或活跃社区
  • 定期进行依赖安全审计

4. 前端框架选型

4.1 候选方案对比

维度 React Vue 3 Angular UmiJS现有
社区活跃度 极高
学习曲线
TypeScript 支持 原生 原生 原生 优秀
生态丰富度 丰富 较丰富 完整 依赖 Ant Design
企业级组件 Ant Design Element Plus Angular Material Ant Design 5.x
与现有项目兼容 需重构 需重构 需重构 现有方案

4.2 推荐方案:保持 UmiJS 4.x

4.2.1 选型理由

  1. 项目延续性UmiJS 4.x 已是项目现有技术栈,降低迁移风险
  2. Ant Design 深度集成:与现有 UI 组件库完美兼容
  3. 企业级特性:内置权限、国际化、路由、状态管理
  4. TypeScript 优先:开箱即用的 TS 支持

4.2.2 升级路径

UmiJS 3.x -> UmiJS 4.x -> UmiJS 5.x (预览版)

4.3 前端技术栈清单

层级 技术方案 版本要求 说明
框架 UmiJS 4.x 现有方案
UI 组件库 Ant Design 5.x 企业级组件
状态管理 Zustand >= 4.x 替代 Valtio更主流
服务端状态 TanStack Query >= 5.x 替代 Umi Model
HTTP 客户端 Axios / Umirequest >= 1.x 现有方案
表单管理 React Hook Form + Zod 最新 替代 ProForm
可视化 AntV G2 / G6 >= 5.x 现有方案
构建工具 ViteUmiJS 内置) 内置 现有方案
代码规范 ESLint + Prettier 团队统一 现有方案

4.4 前端架构设计

4.4.1 目录结构规范

src/
├── components/          # 公共组件
│   ├── Business/        # 业务组件
│   └── Basic/           # 基础组件
├── pages/              # 页面组件
├── stores/              # Zustand 状态管理
├── services/            # API 服务层 (TanStack Query)
├── utils/               # 工具函数
├── hooks/               # 自定义 Hooks
├── types/               # TypeScript 类型定义
└── assets/             # 静态资源

4.4.2 状态管理策略

状态类型 管理方案 适用场景
全局状态 Zustand 用户信息、租户配置
页面状态 React Hook Form 表单数据
服务端状态 TanStack Query API 数据缓存、同步
表单验证 Zod 复杂表单验证

4.4.3 Zustand 使用示例

// stores/orderStore.ts
import { create } from 'zustand';
import { Order, OrderQueryParams } from '@/types/order';

interface OrderState {
  orders: Order[];
  selectedOrder: Order | null;
  queryParams: OrderQueryParams;
  setOrders: (orders: Order[]) => void;
  setSelectedOrder: (order: Order | null) => void;
  setQueryParams: (params: OrderQueryParams) => void;
}

export const useOrderStore = create<OrderState>((set) => ({
  orders: [],
  selectedOrder: null,
  queryParams: {},
  setOrders: (orders) => set({ orders }),
  setSelectedOrder: (order) => set({ selectedOrder: order }),
  setQueryParams: (params) => set({ queryParams: params }),
}));

4.4.4 TanStack Query 使用示例

// services/orderService.ts
import { request } from 'umi';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { Order, CreateOrderDTO } from '@/types/order';

export const useOrders = (params: OrderQueryParams) => {
  return useQuery({
    queryKey: ['orders', params],
    queryFn: () => request<Order[]>('/api/v1/orders', { params }),
  });
};

export const useCreateOrder = () => {
  const queryClient = useQueryClient();
  return useMutation({
    mutationFn: (data: CreateOrderDTO) => 
      request<Order>('/api/v1/orders', { method: 'POST', data }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['orders'] });
    },
  });
};

5. 后端技术栈

5.1 框架选型对比

框架 Express Koa2 NestJS Fastify
架构风格 简约 中间件 模块化 极致性能
TypeScript 支持 需配置 需配置 原生 优秀
装饰器支持
生态成熟度 极高 中高
学习成本
性能 中高 极高

5.2 推荐方案NestJS

5.2.1 选型理由

  1. 企业级架构:模块化、装饰器、依赖注入,与 Spring Boot 理念相似
  2. TypeScript 优先:原生支持 TypeScript类型安全
  3. 生态系统丰富微服务、GraphQL、WebSocket、任务队列
  4. 可测试性内置单元测试、E2E 测试框架

5.2.2 架构对齐

项目现有后端采用 core/domains/workers/api/shared 分层结构NestJS 模块系统可完美映射:

src/
├── core/               # NestJS Core (Guard, Interceptor, Pipe)
├── modules/            # 业务模块 (对应 domains)
│   ├── order/
│   ├── product/
│   ├── finance/
│   └── trade/
├── api/                # Controller 层
├── workers/            # Background Jobs
└── shared/             # Shared 模块 (DTO, Entities, Utils)

5.3 后端技术栈清单

层级 技术方案 版本要求 说明
运行时 Node.js 20.x LTS 现有
框架 NestJS 10.x 企业级框架
语言 TypeScript 5.x (strict) 严格模式
ORM Prisma >= 5.x 替代 Knex/TypeORM
数据库 MySQL 8.0 现有
缓存 Redis 6.0+ 现有
消息队列 BullMQ 最新 现有
验证 class-validator + Zod 最新 增强验证
文档 Swagger / OpenAPI @nestjs/swagger 现有

5.4 ORM 选型Prisma

5.4.1 为什么选择 Prisma

特性 Prisma TypeORM Knex.js
TypeScript 支持 原生 需类型定义
迁移体验 优秀 一般 一般
查询构建 Prisma Client Entity Query Builder
性能
学习曲线 中高
开发者体验 优秀 一般 一般

5.4.2 Prisma Schema 示例

// schema.prisma
generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

model Order {
  id          String   @id @default(uuid())
  orderNo     String   @unique
  status      OrderStatus @default(PENDING)
  totalAmount Decimal  @db.Decimal(10, 2)
  tenantId    String
  shopId      String
  items       OrderItem[]
  createdAt   DateTime @default(now())
  updatedAt   DateTime @updatedAt

  @@index([tenantId, shopId])
  @@index([status])
}

model OrderItem {
  id        String  @id @default(uuid())
  orderId   String
  order     Order   @relation(fields: [orderId], references: [id])
  productId String
  quantity  Int
  price     Decimal @db.Decimal(10, 2)
}

5.5 数据库设计

5.5.1 关系型数据库MySQL 8.0

表分类 命名规范 示例
核心业务表 cf_前缀 cf_order, cf_product
租户隔离表 cf_tenant_ cf_tenant_config
日志审计表 cf_log_ cf_log_operation

5.5.2 数据库设计原则

  1. 命名规范:小写字母 + 下划线
  2. 主键策略:使用 UUID 或雪花 ID
  3. 时间戳created_at, updated_at 字段必填
  4. 软删除:使用 is_deleted 字段标记
  5. 索引优化:高频查询字段添加索引

5.5.3 非必要场景

场景 推荐方案
简单配置存储 MySQL JSON 字段
会话缓存 Redis
实时计数器 Redis INCR
大文件存储 对象存储OSS/MinIO

6. API 设计规范

6.1 RESTful API 标准

6.1.1 路由设计

方法 用途 示例
GET 查询 GET /api/v1/orders
POST 创建 POST /api/v1/orders
PUT 完整更新 PUT /api/v1/orders/:id
PATCH 部分更新 PATCH /api/v1/orders/:id
DELETE 删除 DELETE /api/v1/orders/:id

6.1.2 响应结构

// 成功响应
{
  "success": true,
  "data": {
    "id": "uuid",
    "status": "PENDING"
  },
  "pagination": {
    "page": 1,
    "pageSize": 20,
    "total": 100
  }
}

// 错误响应
{
  "success": false,
  "error": {
    "code": "ORDER_NOT_FOUND",
    "message": "订单不存在",
    "details": {}
  }
}

6.2 错误码规范

错误类别 错误码前缀 说明
4xx CLIENT_ERROR_ 客户端错误(参数、权限)
5xx SERVER_ERROR_ 服务端错误(数据库、外部服务)
业务 BIZ_ 业务规则错误
认证 AUTH_ 认证授权错误

6.3 版本控制

  • URL 版本:/api/v1/, /api/v2/
  • 兼容策略:旧版本至少维护 6 个月
  • 废弃通知:提前 3 个月公告

7. 前后端数据交互

7.1 通信协议

交互方式 协议 适用场景
REST API HTTP/1.1 常规 CRUD 操作
WebSocket WS/WSS 实时状态推送
Server-Sent Events HTTP 单向实时推送
GraphQL HTTP 复杂查询场景

7.2 数据类型共享

7.2.1 Shared Types 包

packages/
└── shared-types/
    ├── index.ts
    ├── order.types.ts
    ├── product.types.ts
    └── api.types.ts

7.2.2 类型同步机制

  1. Monorepo 架构:使用 Nx 或 Turborepo 管理
  2. npm 私有包:发布 shared-types 到私有仓库
  3. 构建时同步CI/CD 自动同步类型定义

7.3 请求封装

7.3.1 前端请求层

// services/api.ts
import { request } from 'umi';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';

export const orderService = {
  list: (params: OrderQueryParams) => 
    request('/api/v1/orders', { params }),
  
  create: (data: CreateOrderDTO) => 
    request('/api/v1/orders', { method: 'POST', data }),
    
  update: (id: string, data: UpdateOrderDTO) =>
    request(`/api/v1/orders/${id}`, { method: 'PATCH', data }),
};

// TanStack Query Hook 封装
export const useOrders = (params: OrderQueryParams) => {
  return useQuery({
    queryKey: ['orders', params],
    queryFn: () => orderService.list(params),
  });
};

7.3.2 统一错误处理

  • 401 Unauthorized跳转登录页
  • 403 Forbidden显示权限不足
  • 429 Too Many Requests显示限流提示
  • 5xx Server Error显示服务异常

8. 开发环境配置

8.1 环境要求

环境 配置要求
开发环境 Node.js 20.x, MySQL 8.0, Redis 6.0
测试环境 Docker 容器化部署
生产环境 阿里云 ECS + RDS + Redis

8.2 开发工具链

工具 用途 配置
VS Code IDE 推荐配置
ESLint 代码检查 .eslintrc.js
Prettier 代码格式化 .prettierrc
TypeScript 类型检查 tsconfig.json
Husky Git Hooks .husky/
lint-staged 增量检查 package.json

8.3 环境变量管理

.env                  # 本地开发
.env.development      # 开发环境
.env.staging          # 预发布环境
.env.production       # 生产环境
变量分类 示例变量
数据库 DB_HOST, DB_PORT, DB_USER
Redis REDIS_HOST, REDIS_PORT
认证 JWT_SECRET, JWT_EXPIRES
第三方 PLATFORM_APP_ID, PLATFORM_SECRET

9. 测试策略

9.1 测试分层

测试类型 覆盖目标 工具
单元测试 业务逻辑、工具函数 Jest / Vitest
集成测试 API 接口、数据库操作 Jest + Supertest
E2E 测试 关键用户路径 Playwright / Cypress
性能测试 API 响应时间、并发 k6 / Artillery

9.2 测试覆盖率要求

模块 最低覆盖率
核心业务 Service 80%
工具函数 90%
Controller 70%
整体项目 75%

9.3 测试数据管理

  • 使用 Fixtures 管理测试数据
  • 避免依赖外部真实数据
  • 测试用例需有清理机制

10. 部署方案

10.1 部署架构

                    [CDN]
                      |
                  [Nginx]
                      |
              [负载均衡器]
                    |
          +---------+---------+
          |                   |
      [Node Cluster]      [Node Cluster]
          |                   |
      [MySQL RDS]         [Redis Cache]

10.2 容器化部署

10.2.1 Docker 配置

# 后端 Dockerfile
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist/ ./dist/
EXPOSE 3000
CMD ["node", "dist/main.js"]

10.2.2 Docker Compose 开发环境

version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
    depends_on:
      - mysql
      - redis

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: crawlfuhl_hub

  redis:
    image: redis:6-alpine

10.3 CI/CD 流程

阶段 工具 执行内容
代码检查 ESLint, TypeScript 语法检查、类型校验
单元测试 Jest 覆盖率检查
构建 npm 产物打包
镜像构建 Docker 容器镜像
部署 GitLab CI / GitHub Actions 灰度发布

11. 性能优化策略

11.1 前端性能优化

优化点 方案 预期收益
首屏加载 Code Splitting, Lazy Loading 减少 30% 首屏时间
请求优化 TanStack Query 缓存 减少 50% 请求数
图片优化 WebP, 懒加载 减少 40% 带宽
渲染优化 React.memo, useMemo 减少重渲染开销
构建优化 Turborepo + esbuild 提升 10x 构建速度

11.2 后端性能优化

优化点 方案 预期收益
数据库 Prisma 连接池 + 索引优化 提升 10x 查询速度
缓存 Redis 多级缓存 减少 80% 数据库查询
并发 PM2 集群模式 提升 5x 并发能力
异步 BullMQ 消息队列 提升吞吐量
压缩 Express 压缩中间件 减少 60% 带宽

11.3 监控与告警

监控指标 工具 告警阈值
API 响应时间 Prometheus + Grafana > 500ms
错误率 Sentry > 1%
CPU / 内存 Node.js 内置 > 80%
数据库连接 MySQL 慢查询 > 1s

12. 可扩展性设计

12.1 模块化架构

12.1.1 模块注册机制

// 模块配置接口
export interface ModuleConfig {
  name: string;
  version: string;
  controllers: Type<any>[];
  providers: Type<any>[];
  entities: Type<any>[];
  routes: RouteConfig[];
}

// 动态模块加载器
export class ModuleLoader {
  private modules: Map<string, ModuleConfig> = new Map();
  
  async registerModule(config: ModuleConfig): Promise<void> {
    this.modules.set(config.name, config);
  }
  
  async loadModulesFromPath(path: string): Promise<void> {
    const files = await fs.readdir(path);
    for (const file of files) {
      if (file.endsWith('.module.ts')) {
        const module = await import(join(path, file));
        await this.registerModule(module.default);
      }
    }
  }
}

12.2 插件系统设计

12.2.1 平台插件接口

// 平台插件接口
export interface IPlatformPlugin {
  platform: string;
  version: string;
  
  // 授权
  authorize(code: string): Promise<AuthToken>;
  refreshToken(token: AuthToken): Promise<AuthToken>;
  
  // 商品
  fetchProducts(params: ProductQueryParams): Promise<Product[]>;
  publishProduct(product: Product): Promise<string>;
  
  // 订单
  fetchOrders(params: OrderQueryParams): Promise<Order[]>;
  fulfillOrder(orderId: string, tracking: Tracking): Promise<void>;
}

// 插件注册
@Injectable()
export class PluginRegistry {
  private plugins: Map<string, IPlatformPlugin> = new Map();
  
  register(plugin: IPlatformPlugin): void {
    this.plugins.set(plugin.platform, plugin);
  }
  
  get(platform: string): IPlatformPlugin | undefined {
    return this.plugins.get(platform);
  }
}

12.2.2 支持的插件类型

插件类型 功能 示例
平台插件 接入新电商平台 Amazon, eBay, TikTok
物流插件 接入新物流渠道 燕文, 4PX, 云途
支付插件 接入新支付方式 PayPal, Stripe
通知插件 接入新通知渠道 邮件, 短信, 钉钉

12.3 微服务演进路径

阶段 架构 适用场景 拆分策略
第一阶段 单体应用 初创期 -
第二阶段 模块化单体 成长期 按业务域拆分
第三阶段 微服务 成熟期 按服务拆分

演进策略

  1. 先实现清晰的模块边界(当前阶段)
  2. 使用 NestJS 命名空间隔离
  3. 未来可通过 Kubernetes 拆分为独立服务

13. 安全性加固

13.1 认证授权

13.1.1 JWT 双 Token 策略

Token 类型 有效期 用途
Access Token 15 分钟 API 访问
Refresh Token 7 天 刷新 Access Token

13.1.2 权限控制

// RBAC 权限装饰器
export const Permissions = (...permissions: string[]) => 
  SetMetadata('permissions', permissions);

// 权限守卫
@Injectable()
export class PermissionsGuard implements CanActivate {
  canActivate(context: ExecutionContext): boolean {
    const permissions = Reflect.getMetadata('permissions', context.getHandler());
    const user = context.switchToHttp().getRequest().user;
    
    return permissions.every(p => user.permissions.includes(p));
  }
}

// 使用示例
@UseGuards(JwtAuthGuard, PermissionsGuard)
@Get('orders')
@Permissions('order:read')
async getOrders() {}

13.2 数据安全

安全措施 实现方案
SQL 注入 Prisma 参数化查询
XSS 攻击 Helmet + Content-Security-Policy
CSRF SameSite Cookie
敏感数据 AES-256 加密存储
传输加密 TLS 1.3

13.3 审计日志

// 审计日志装饰器
export const AuditLog = (action: string) => 
  SetMetadata('auditAction', action);

// 审计拦截器
@Injectable()
export class AuditInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const request = context.switchToHttp().getRequest();
    const user = request.user;
    const action = Reflect.getMetadata('auditAction', context.getHandler());
    
    this.auditService.log({
      userId: user?.id,
      tenantId: user?.tenantId,
      action,
      resource: request.url,
      method: request.method,
      ip: request.ip,
      userAgent: request.headers['user-agent'],
      timestamp: new Date(),
    });
    
    return next.handle();
  }
}

13.4 API 安全

防护措施 实现
请求限流 Redis 计数器 + 滑动窗口
IP 黑名单 Nginx / 应用层
请求验签 HMAC-SHA256
CORS 白名单配置

14. 风险评估与缓解措施

14.1 技术风险

风险项 等级 缓解措施
单线程性能瓶颈 PM2 集群 + 负载均衡
内存泄漏 定期内存分析 + 监控
依赖安全漏洞 自动化安全审计 + Snyk
TypeScript 类型膨胀 统一 shared-types 包

14.2 业务风险

风险项 等级 缓解措施
数据一致性 事务 + 补偿机制
第三方 API 依赖 熔断器模式 + 降级策略
租户数据隔离 强制 tenant_id 过滤

14.3 运维风险

风险项 等级 缓解措施
服务不可用 多活架构 + 自动故障转移
数据丢失 极高 定期备份 + 异地容灾
性能退化 性能监控 + 容量规划

15. 实施路线图

15.1 阶段规划

阶段 时间 里程碑 优先级
Phase 1 1 周 NestJS + Prisma 框架搭建 P0
Phase 2 2 周 状态管理迁移 (Zustand + TanStack Query) P1
Phase 3 2 周 核心业务模块迁移 P1
Phase 4 2 周 API 规范化 + 测试补全 P1
Phase 5 2 周 安全加固 + 审计日志 P1
Phase 6 1 周 性能优化 + 监控部署 P2
Phase 7 1 周 容器化 + CI/CD 完善 P2
Phase 8 2 周 插件系统设计 P2

15.2 验收标准

  • 所有核心 API 具备单元测试
  • API 响应时间 P99 < 500ms
  • 前后端类型完全同步
  • 部署流程自动化
  • 安全审计通过

16. 附录

16.1 技术栈总览

层级 技术方案 版本
前端框架 UmiJS 4.x
UI 组件 Ant Design 5.x
状态管理 Zustand 4.x
服务端状态 TanStack Query 5.x
表单验证 React Hook Form + Zod 最新
后端框架 NestJS 10.x
ORM Prisma 5.x
数据库 MySQL 8.0
缓存 Redis 6.0+
消息队列 BullMQ 最新
构建工具 Vite 内置
语言 TypeScript 5.x (strict)

16.2 参考资源

16.3 版本历史

版本 日期 变更内容
V1.0 2024-01 初始版本
V2.0 2026-03-15 优化版去除AI、技术栈升级、安全加固

文档维护者Crawlful Hub 架构团队
版本V2.0
状态:已优化