2026-05-20 17:50:37 +08:00
|
|
|
|
# ADR-0001: 整体技术栈选型
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
> **状态**: 已决议(2026-05-21 修订)
|
|
|
|
|
|
> **日期**: 2026-05-20
|
|
|
|
|
|
> **修订**: 2026-05-21
|
2026-05-20 17:50:37 +08:00
|
|
|
|
> **决策者**: 架构评审
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 上下文
|
|
|
|
|
|
|
|
|
|
|
|
构建 AI 驱动的化妆品配方研发智能平台(纯 Web 端),涉及四大核心模块:颜色引擎(广色域渲染)、配方可视化编辑器(拖拽交互 + 实时 AI 反馈)、配方记录管理(结构化存储 + NL 搜索)、配方推演引擎(多方案并行优化)。需对前端框架、图表库、色彩科学库、后端架构、数据库等做出技术选型。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 决策
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 1. 前端框架 → React 19 + TypeScript 5.7
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **React** | 生态最丰富;ECharts/D3/color.js 均有 React 绑定;招聘成本最低;TS 成熟 | Hooks 学习曲线 | ✅ 推荐 |
|
|
|
|
|
|
| Vue 3 | 模板直观;Composition API 类型推导好 | ECharts 官方 React 绑定更成熟;D3 + Vue 组合不如 React 灵活 | ❌ |
|
|
|
|
|
|
| Svelte 5 | 编译时框架,运行时极小 | 生态较小;关键库适配风险;社区资源少 | ❌ |
|
|
|
|
|
|
| SolidJS | 性能优于 React;API 相似 | 社区太小(GitHub stars ~30k vs React ~230k);生产风险高 | ❌ |
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:React 19 + TypeScript strict mode。
|
|
|
|
|
|
|
|
|
|
|
|
> **修订(2026-05-21)**:从 React 18 升级到 React 19。生态已稳定,React Compiler 带来额外性能收益。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 2. 构建工具 → Vite 8
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **Vite** | 原生 ESM 开发(毫秒级 HMR);Rollup 生产打包;零配置开箱;SSR 可选 | — | ✅ 推荐 |
|
|
|
|
|
|
| Next.js 15 | 全栈能力;SSR/SSG/ISR | 内部工具无需 SSR/SEO;增加复杂度;App Router 学习曲线陡峭 | ❌ |
|
|
|
|
|
|
| Remix | SSR 优先;Web 标准 | 同上;社区较 Next.js 小 | ❌ |
|
|
|
|
|
|
| CRA | — | 已停止维护;Webpack 构建慢 | ❌ |
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:Vite 8,SPA 模式。平台为内部工具,无需 SEO/SSR。
|
|
|
|
|
|
|
|
|
|
|
|
> **修订(2026-05-21)**:从 Vite 6 升级到 Vite 8。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 3. 状态管理 → Zustand
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **Zustand** | 极简 API(无 Provider/Reducer);TS 完美;< 2KB;中间件(persist/immer/devtools) | — | ✅ 推荐 |
|
|
|
|
|
|
| Redux Toolkit | 完善的 DevTools;团队规范 | 模板代码多;概念多(slice/thunk/selector);过度工程化 | ❌ |
|
|
|
|
|
|
| Jotai | 原子化精细更新 | 原子拆分粒度决策成本高;对中型应用过度 | ❌ |
|
|
|
|
|
|
| MobX | 响应式直观 | 装饰器语法过时;与 React 18+ 严格模式兼容性问题 | ❌ |
|
|
|
|
|
|
|
|
|
|
|
|
**决策**:Zustand。服务端状态用 TanStack Query,客户端状态用 Zustand,边界清晰。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 路由 → React Router v7
|
|
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **React Router v7** | 最广泛使用;layout routes;v7 类型安全路由;社区资源极丰富 | — | ✅ 推荐 |
|
|
|
|
|
|
| TanStack Router | 编译时类型安全最强 | 生态较小;与第三方库集成案例少 | ❌ |
|
|
|
|
|
|
|
|
|
|
|
|
**决策**:React Router v7。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 5. CSS 方案 → Tailwind CSS 4 + CSS Modules
|
|
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **Tailwind + CSS Modules** | Tailwind 处理 80% 日常样式;CSS Modules 处理复杂定制(颜色盘);零运行时;Tailwind v4 CSS-first 配置 | 需同时掌握两套语法 | ✅ 推荐 |
|
|
|
|
|
|
| styled-components | CSS-in-JS,组件级隔离 | 运行时开销(~14KB);Server Components 不兼容趋势 | ❌ |
|
|
|
|
|
|
| Panda CSS | 编译时 CSS-in-JS | 较新(2024),生态不成熟 | ❌ |
|
|
|
|
|
|
| Vanilla Extract | 类型安全 CSS-in-JS | 构建步骤复杂;社区小 | ❌ |
|
|
|
|
|
|
|
|
|
|
|
|
**决策**:Tailwind CSS 4(原子化,处理布局/间距/响应式)+ CSS Modules(处理颜色盘 Canvas 容器、图表交互区等复杂定制场景)。
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 6. UI 行为组件 → Radix UI
|
|
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **Radix UI** | Headless(完全控制样式);WAI-ARIA 内置;组件粒度合适;与 Tailwind 天配 | 无预置视觉风格(需要自行设计) | ✅ 推荐 |
|
|
|
|
|
|
| Ant Design | 开箱即用,组件丰富 | 企业后台感强;视觉定制困难;不适合创意工具;bundle 大 | ❌ |
|
|
|
|
|
|
| MUI | Material Design 完整实现 | 同上;Google 风格固化 | ❌ |
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| shadcn/ui | 基于 Radix + Tailwind 预封装 | 封装度低,仍需二次开发 | — |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:Radix UI。平台 UI 需要与化妆品实验室品牌调性一致,Radix 的 Headless 模式允许完全定制视觉。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 7. 图表 → ECharts
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **ECharts** | 可视化类型最丰富(雷达图/桑基图/热力图等);React 绑定成熟(echarts-for-react);大数据集高性能 | 包体积较大(~1MB) | ✅ 推荐 |
|
|
|
|
|
|
| D3.js | 自由度最高;定制性极强 | 命令式 API;React 集成需大量封装;开发效率低 | ❌ |
|
|
|
|
|
|
| Recharts | React 声明式;组件化 | 图表类型有限;大数据集性能差 | ❌ |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:ECharts 作为主图表库,D3.js 作为辅助(颜色空间可视化等高度定制场景)。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 8. 色彩科学 → colorjs.io
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **colorjs.io** | 支持所有颜色空间(CIELAB/Display P3/LCH 等);ΔE 2000/CMC 计算;积极维护 | 社区较 chroma.js 小 | ✅ 推荐 |
|
|
|
|
|
|
| chroma.js | 轻量 API;流行度高 | 不支持 ΔE 2000;不支持 Display P3 | ❌ |
|
|
|
|
|
|
| d3-color | 与 D3 生态集成 | 颜色空间有限;无 ΔE | ❌ |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:colorjs.io。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 9. 后端框架 → Fastify
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **Fastify** | 性能最高(~60k req/s);插件生态完善(CORS/Swagger/Helmet);TypeScript 原生支持;schema 验证 | 社区较 Express 小 | ✅ 推荐 |
|
|
|
|
|
|
| Express | 最广泛使用;中间件生态极丰富 | 性能较差(~15k req/s);TS 支持需额外配置;回调风格 | ❌ |
|
|
|
|
|
|
| Hono | 极轻量(< 10KB);运行时无关(Node/Deno/Bun/Edge) | 生态较小;企业级插件不成熟 | ❌ |
|
|
|
|
|
|
| NestJS | 开箱即用架构(Module/Controller/Service);DI 容器 | 过度工程化;装饰器侵入性强;学习曲线陡峭;冷启动慢 | ❌ |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:Fastify 5 + TypeScript。插件体系完整且性能优异,适合 API 密集型场景。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 10. 数据库 → PostgreSQL + pgvector
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| **PostgreSQL + pgvector** | 成熟稳定;pgvector 扩展支持向量搜索(HNSW 索引);ACID 事务 | 向量搜索性能不如专用向量 DB | ✅ 推荐 |
|
|
|
|
|
|
| MongoDB | 文档模型灵活;内置 Atlas Search | 缺乏 ACID;向量搜索需 Atlas | ❌ |
|
|
|
|
|
|
| Elasticsearch | 全文搜索最强 | 运维成本高;需额外同步数据 | ❌ |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:PostgreSQL + pgvector。配方数据是典型的关系型结构(配方→相→成分),PostgreSQL 的关系模型天然适配;向量搜索用于语义配方查找,pgvector 性能足够。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 11. ORM → Prisma
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
| :--- | :--- | :--- | :--- |
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| **Prisma** | 类型安全;Schema-first;迁移工具成熟;Client 自动生成;关系模型直观 | 复杂查询性能不如原生 SQL | ✅ 推荐 |
|
|
|
|
|
|
| Drizzle ORM | 轻量零依赖;SQL-like API;性能接近原生 | 生态较新;迁移工具不如 Prisma 成熟 | ❌ |
|
|
|
|
|
|
| Knex.js | SQL 构建器;灵活 | 无类型安全;手写迁移 | ❌ |
|
|
|
|
|
|
| Sequelize | 历史悠久;生态大 | 类型支持弱;API 设计过时 | ❌ |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:Prisma 7 + pg adapter。项目中配方的关系嵌套深度大(Formula→Version→Phase→FormulaIngredient→Ingredient),Prisma 的关联查询和事务支持良好。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
---
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 12. 包管理 → pnpm workspace
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| 候选 | 优势 | 劣势 | 结论 |
|
|
|
|
|
|
| :--- | :--- | :--- | :--- |
|
|
|
|
|
|
| **pnpm** | 硬盘高效(硬链接);严格依赖;monorepo workspace 支持;速度快 | lockfile 格式与 npm 不兼容 | ✅ 推荐 |
|
|
|
|
|
|
| npm | 默认工具 | 依赖扁平化导致幽灵依赖;磁盘占用大;慢 | ❌ |
|
|
|
|
|
|
| Yarn | Plug'n'Play 模式 | PnP 兼容性问题多;社区分裂 | ❌ |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:pnpm。前后端独立 package,共享 workspace 协议。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
### 13. 对象存储 → MinIO
|
|
|
|
|
|
|
|
|
|
|
|
**决策**:MinIO(S3 兼容),存储参考图片、导出文件。本地部署,S3 API 可无缝迁移到云。
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
> **修订(2026-05-21)**:MinIO 设为 docker compose `profiles: ["full"]`,默认不启动。当前无实际代码使用。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 14. 部署 → Docker Compose + Traefik
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
**决策**:开发环境 `docker compose up`(PostgreSQL + MinIO(可选)),生产环境 `docker compose -f docker-compose.prod.yml up`(Traefik + PostgreSQL + Backend + Frontend)。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
> **修订(2026-05-21)**:新增生产环境部署方案。Traefik 负责反向代理和自动负载均衡,Backend/Frontend 均已容器化。
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
---
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
### 15. 安全加固
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
| 组件 | 用途 | 添加日期 |
|
|
|
|
|
|
|------|------|----------|
|
|
|
|
|
|
| `@fastify/helmet` | 安全 HTTP 头(HSTS/X-Frame/X-Content-Type 等) | 2026-05-21 |
|
|
|
|
|
|
| `@fastify/rate-limit` | 全局速率限制(100 req/min) | 2026-05-21 |
|
|
|
|
|
|
| `@fastify/swagger` + `@fastify/swagger-ui` | OpenAPI 文档生成 + `/docs` 交互式浏览 | 2026-05-21 |
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
## 后果
|
2026-05-20 17:50:37 +08:00
|
|
|
|
|
2026-05-21 17:29:52 +08:00
|
|
|
|
- 所有用户必须熟悉 React + Fastify + Prisma 三件套
|
|
|
|
|
|
- 数据库变更必须通过 Prisma Migrate,不可手动修改 Schema
|
|
|
|
|
|
- OpenAPI spec 作为服务契约,前后端类型同步
|
|
|
|
|
|
- 本地开发需 Docker 运行 PostgreSQL(pgvector 扩展)
|