01 · 分层全景
六层栈:从语言底座到领域能力
点步进器或图里的任意一层聚焦;下方详情会列出该层的真实依赖与选它的理由。上层依赖下层,越往上越重、越该慎选。
提示:悬停某一层看它的一句话定位,点击则展开该层的依赖清单与选型理由。
01
02 · 选型原则
四条不成文的规矩
这些原则不写在代码里,但决定了上面每一层为什么长这样。
无头优先
交互逻辑与可访问性交给无头库(Radix / Base UI / Ariakit),样式全权自持。升级不被组件库的视觉锁死,改一处 token 全站跟着变。
单向依赖
底层零业务、上层不反向依赖下层的实现细节。cn() 收口所有 class 合并,主题走 next-themes 一处切换,杜绝散落的样式判断。
一处一职、允许并存
同类库只在边界清晰时并存:Zustand 管全局、Jotai 管原子;dnd-kit 走新功能、react-dnd 留存量。并存是过渡态,不是终态。
可回退
每个重依赖都留退路。成品组件库只占各自的垂直页面,拆掉不伤主干;越靠上层越贵的依赖,越要能被换掉。
03 · 关键抉择
六个岔路口,选了什么、放弃了什么
每一条都有真实备选。列出来是为了让「为什么不是那个」也留痕。
富文本编辑器
| 选择 | PlateJS 52(基于 Slate) |
| 备选 | TipTap / Lexical |
| 理由 | 40+ 官方插件、docx 与 markdown 双向、评论 / 建议 / 协同齐活;生态深度压过迁移成本。 |
样式方案
| 选择 | Tailwind v4 + shadcn 模式 |
| 备选 | CSS-in-JS / 组件库全家桶 |
| 理由 | 原子类零运行时,cva 管变体,组件源码在自己仓库;改样式不排队等上游。 |
状态管理
| 选择 | Zustand + Jotai |
| 备选 | Redux Toolkit / 单一大 store |
| 理由 | 全局用 Zustand store、局部用 Jotai 原子,零样板;未引入 Redux。 |
AI 对话 UI
| 选择 | assistant-ui + Vercel AI SDK |
| 备选 | 全自建对话层 |
| 理由 | 流式、工具卡、Markdown 渲染开箱即用;后端接 Mastra 运行时,前端不重造轮子。 |
数据获取
| 选择 | RSC + Server Actions + axios |
| 备选 | TanStack Query |
| 理由 | 服务端组件直取数据,客户端只留必要请求;未引入 React Query,减一层缓存心智。 |
表格与长列表
| 选择 | TanStack Table + Virtual |
| 备选 | AntD Table 独大 |
| 理由 | 无头表格配自建样式,万行列表交给 react-virtual;AntD 只在重后台页兜底。 |
04 · 完整选型清单
14 个域,一屏看全前端依赖
逐条取自 apps/web/package.json。颜色标出每个依赖在选型里的角色。
前端依赖面板
核心主干撑起日常;成品库只在垂直场景空降;无头 / 自建 / 构建类是骨架;虚线红 是存量或可替换项。
选型边界(known tensions)
- 三套组件观并存有重量:自建 152 组件 + AntD 6 + LobeHub UI,包体与视觉一致性靠「各守垂直页」的纪律来克制。
- 图标库 5 套按来源就近取用,未强行收敛;靠
optimizePackageImports与 tree-shaking 兜住体积。 - 拖拽 dnd-kit 与 react-dnd 并存:新功能一律 dnd-kit,react-dnd 是待迁移存量。
- 富文本 40+ 依赖是最大单点,换栈成本极高——已用分包与按需导入缓解首屏。
- 未引入独立表单库(RHF / Formik):轻表单手写 + Zod 4 校验,复杂表单场景需再评估。