stack-fe-react — 前端技术栈规范
以 10 年经验前端架构师的标准生成、重构、解释所有前端代码。所有规范的可执行载体是 assets/frontend-template/:一个经过 pnpm install && pnpm build && pnpm test 验证的脚手架工程,含一个 features/projects 参考模块。写代码前先想清楚对应模板中的哪个位置、哪个文件,与其保持一致。
一、技术栈基准
| 类别 | 选型 | 关键约束 |
|---|---|---|
| 语言 | TypeScript 最新稳定版 | strict 必开;禁止 any |
| 框架 | React 19 | 仅函数式组件;开启 React Compiler |
| 构建 | Vite | Compiler 依赖 Babel 管线用 @vitejs/plugin-react;不启用 Compiler 时可换 -swc 版提速 |
| 包管理 | pnpm | 禁止 npm / yarn |
| 路由 | React Router v7 | 默认库模式(纯 SPA);需 SSR/SEO 才用框架模式 |
| 服务端状态 | TanStack Query | 优先 useSuspenseQuery + Suspense 边界 |
| 客户端状态 | Zustand | 仅纯 UI 状态;严禁 Redux;Context 仅限低频更新 |
| 请求 | Axios(可换 ofetch/ky) | 统一实例 + 拦截器;禁止组件内裸 fetch |
| 样式 | Tailwind CSS v4 | CSS-first @theme 配置,无 tailwind.config.ts;严禁 CSS-in-JS |
| 组件库 | shadcn/ui(Radix) | CLI 添加组件;严禁 AntD/MUI/Element |
| 图标 | Lucide | 按需导入 |
| 表单 | React Hook Form + Zod | zodResolver 声明式校验 |
| 工具库 | es-toolkit / dayjs | 严禁 lodash、moment |
| Lint | Biome | 替代 ESLint + Prettier |
| 测试 | Vitest + Testing Library | 测行为非实现;E2E 按需 Playwright |
二、新建项目:使用模板脚手架
新建任何前端项目时,必须从模板初始化,禁止从零手写工程文件:
- 复制
assets/frontend-template/到目标位置并改名 pnpm install(lock 文件已锁定验证过的版本组合)- 修改
package.jsonname、index.htmltitle、src/index.css的@theme主题 token - 按需添加 shadcn 组件:
npx shadcn@latest add <component>(配置已在 components.json) - 保留
features/projects模块作为分层参考实现,编写真实业务后删除 - 验证:
pnpm build与pnpm test必须全绿
模板已含:Vite + React Compiler 配置、Tailwind v4 @theme 入口、TS strict 三件套、Biome、Vitest + jsdom、Axios 统一实例、Zustand 示例 store、ErrorBoundary、shadcn 风格 Button 示例、@/ 路径别名。
三、代码组织铁律
src/
├── components/ # 通用组件(ui/ 为 shadcn 组件)
├── features/ # 按业务模块组织,每模块内含 api/ types/ components/ hooks/
├── lib/ # 工具函数、请求实例
├── stores/ # Zustand stores
├── hooks/ # 全局自定义 hooks
├── types/ # 全局 TS 类型
└── test/ # 测试 setup
- 业务代码一律进
features/<模块>/,禁止散落在 components/ 或页面文件里 - feature 内部自包含:API hooks(api/)、Zod schema(types/)、组件(components/)
index.html必须在项目根目录,严禁放public/
四、数据获取铁律(违反视为严重错误)
- 服务端状态一律
useSuspenseQuery/useQuery+ TanStack Query 缓存;严禁useEffect+useState+fetch手写请求(最常见反模式) - loading/error 交给
<Suspense>+<ErrorBoundary>边界;组件内不写if (isLoading) return ... - API 响应用 Zod
z.parse()解析,类型从 schema 推导(z.infer) - 表单提交用
useMutation,成功后精确失效相关 queryKey
五、UI 与样式铁律
- 样式首选 Tailwind 工具类;复杂动画/全局覆盖可写
.css文件;严禁 styled-components/emotion - 主题 token 统一定义在
src/index.css的@theme中,使用方引用bg-primary、text-text-muted等语义类 - 类名合并用
cn()(clsx + tailwind-merge) - shadcn 组件缺失时用 CLI 添加,不手写仿造
六、常见场景速查
| 需求 | 应该做 | 不应该做 |
|---|---|---|
| 发请求获取数据 | useSuspenseQuery + 统一请求实例 |
useEffect + fetch + useState |
| 提交表单 | React Hook Form + zodResolver | 手动控 value + onChange |
| 全局 UI 状态 | Zustand store | Redux / 高频 Context |
| 写样式 | Tailwind 工具类 | CSS-in-JS |
| 加图标 | Lucide 按需引 | FontAwesome 全量引 |
| 工具函数 | es-toolkit | lodash |
| 性能优化 | 依赖 React Compiler | 堆 useMemo/useCallback/memo |
| 日期处理 | dayjs / date-fns | moment.js |
| 测试组件 | Vitest + Testing Library | Jest(除非历史项目) |
七、提交前自检清单
- [ ] 无
useEffect内手写数据请求?服务端状态都走 TanStack Query? - [ ] 数据组件被 Suspense + ErrorBoundary 包裹?无散落 isLoading 分支?
- [ ] API 响应经 Zod 解析?无手写
as any断言? - [ ] 无
any?strict 编译零错误? - [ ] 无 Redux/lodash/moment/styled-components 等禁用库?
- [ ] 样式走 Tailwind?主题 token 来自
@theme而非硬编码色值? - [ ] 无手动
useMemo/useCallback/React.memo(Compiler 已处理)? - [ ] 业务代码在
features/内自包含? - [ ] 核心逻辑(utils/hooks/api)有测试?
- [ ]
pnpm build与pnpm test全绿?
详细库选型规则、React Compiler 说明、Router 模式选择见 references/stack-rules.md;代码质量、注释、测试规范见 references/coding-style.md。