8.2 KiB
前端开发规范
技术栈
Next.js + TypeScript + React + Tailwind CSS + Zustand/Jotai + pnpm
核心依赖
- 实时通信: SSE / WebSocket
- 可视化: Mermaid + 图谱可视化库
- 测试: Vitest + Testing Library
- 代码质量: ESLint (flat config) + Prettier + Husky + lint-staged
开发命令
pnpm install # 安装依赖
pnpm add <pkg> # 添加依赖
pnpm remove <pkg> # 移除依赖
pnpm dev # 启动开发服务器 (默认端口 3000)
pnpm build # 构建生产版本
pnpm start # 启动生产服务器
pnpm lint # 运行 ESLint 检查
pnpm type-check # TypeScript 类型检查
# 代码格式化(Prettier)
pnpm format # 格式化全部文件
pnpm format:check # 检查格式是否合规(CI / 提交钩子使用)
# 测试(Vitest)
pnpm test # 运行全部测试(单次)
pnpm test:watch # 监听模式
pnpm test:coverage # 运行测试并生成覆盖率报告
代码规范
页面设计
图标:统一使用 Lucide 图标,界面全程禁止使用表情符号。 设计标准:对标 Awwwards 顶级网站水准,达到 Awwwards、FWA、CSS Design Awards 每日最佳网站同等设计品质。 创意自由度:将浏览器视作交互式艺术画布,跳出传统布局框架,追求先锋视觉风格、实验性排版、流畅物理动效、极具冲击力的文字版式。 沉浸式体验:融合代码、高级渲染逻辑、图片素材,打造统一完整的精品页面,做出突破常规 UI 认知、令人惊艳的数字交互体验。
通用规范
- 遵循 ESLint + Prettier 配置,提交前必须通过 lint 与格式检查
- 使用 TypeScript 严格模式 (
strict: true),禁止使用any类型 - 组件使用函数式组件 + Hooks,优先使用 Server Components,必要时使用
'use client' - 文件命名: 组件使用 PascalCase (
UserProfile.tsx),工具函数使用 camelCase (formatDate.ts) - 使用
path别名 (@/*) 导入模块,避免相对路径层级过深 - 状态管理: 全局状态使用 Zustand/Jotai,局部状态使用 React useState/useReducer
CSS 变量引用
CSS 变量引用遵循 三层递进规则,优先级由上至下。
规则
Tailwind 映射类 → 优先使用
Tailwind 任意值 [var(--)] → 仅当变量不在 @theme 映射表中时使用
内联 style → 仅限复合值 / 动态运行时值
具体对照
globals.css 的 @theme inline {} 块已映射的部分,直接用 Tailwind 类:
// ✅ 正确:变量在 @theme inline {} 中有 --color-X 映射 → 用 Tailwind 类
<div className="bg-patina text-fg-dim border-rule" />
<span className="text-cinnabar" />
<div className="bg-night-bronze text-fg" />
<div className="bg-surface" />
<button className="border-gilt text-gilt" />
<div className="bg-btn-primary-bg" /> {/* Layer 2 组件 token 同理 */}
// ✅ 正确:变量未映射到 @theme inline {} → 用 Tailwind 任意值
<div className="bg-[var(--patina-wash)]" />
<span className="text-[var(--fg-faint)]" />
<div className="border-[var(--gilt-dim)]" />
<div className="bg-[var(--cinnabar-wash)]" />
bg-[var(--x)]是 Tailwind v4 的合法任意值语法(非 hack),属于 Tailwind 体系内,不是 style 违规。--patina-wash、--patina-dim、--gilt-faint、--gilt-dim、--cinnabar-wash、--cinnabar-dim当前均未直接映射,使用任意值是正确做法。
// ❌ 禁止:变量已在 @theme inline {} 中有映射,却用任意值
// 不要用 bg-[var(--patina)] —— 应写 bg-patina(已映射)
// 不要用 text-[var(--cinnabar)] —— 应写 text-cinnabar(已映射)
// 不要用 border-[var(--rule)] —— 应写 border-rule(已映射)
// 不要用 text-[var(--fg-dim)] —— 应写 text-fg-dim(已映射)
// ❌ 禁止:用内联 style 表达单值 CSS 变量
// 不要写 style={{ color: "var(--patina)" }}
// 不要写 style={{ background: "var(--surface)" }}
// ✅ 正确:渐变色/复合 CSS 用内联 style(Tailwind 无法表达)
<div style={{
background: "linear-gradient(180deg, var(--patina-wash), var(--surface))",
boxShadow: "inset 0 1px 0 var(--face-in-top), var(--shadow)",
}} />
// ✅ 正确:动态运行时值用内联 style
<div style={{ color: health === "ok" ? "var(--patina)" : "var(--cinnabar)" }} />
// ✅ 正确:SVG 属性用内联 style 或 className
<circle style={{ fill: "var(--patina)", stroke: "var(--gilt)" }} />
映射速查
当前 @theme inline {} 中已映射的 铜镜鉴心 变量(查阅 globals.css 确认完整列表):
| CSS 变量 | Tailwind 类前缀 | 示例 |
|---|---|---|
--patina |
patina |
bg-patina text-patina border-patina |
--patina-bright |
patina-bright |
bg-patina-bright |
--gilt |
gilt |
bg-gilt text-gilt |
--cinnabar |
cinnabar |
bg-cinnabar text-cinnabar |
--ink |
ink |
bg-ink |
--night-bronze |
night-bronze |
bg-night-bronze |
--fg |
fg |
text-fg |
--fg-dim |
fg-dim |
text-fg-dim |
--fg-faint |
fg-faint |
text-fg-faint |
--rule |
rule |
border-rule bg-rule |
--surface |
surface |
bg-surface |
--surface-hi |
surface-hi |
bg-surface-hi |
--patina-wash |
patina-wash |
bg-patina-wash |
--patina-dim |
patina-dim |
border-patina-dim bg-patina-dim |
--gilt-dim |
gilt-dim |
border-gilt-dim text-gilt-dim bg-gilt-dim |
--gilt-faint |
gilt-faint |
bg-gilt-faint |
--cinnabar-wash |
cinnabar-wash |
bg-cinnabar-wash |
--cinnabar-dim |
cinnabar-dim |
border-cinnabar-dim |
--glass |
glass |
bg-glass |
--glass-border |
glass-border |
border-glass-border |
--overlay-hover |
overlay-hover |
bg-overlay-hover |
未映射(用 bg-[var(--x)]):--face-sheen --sweep-gradient --face-in-top --face-in-bot --shadow --aurora-* --code-* 以及 SVG 特有的 --raw-*
例外清单
以下变量是复合 CSS 值或动画属性,必须用内联 style,不能抽象为 Tailwind 类:
- 渐变/光照效果:
--face-sheen--sweep-gradient--face-in-top--face-in-bot - 阴影:
--shadow - 背景光晕:
--aurora-* - 动态
color-mix()表达式
规则生效日:此约定写入后,新代码必须遵守。存量代码暂不回溯,待 P0/P1 功能补齐后再做 codemod 迁移。
- 统一通过
lib/api(client.ts出口)调用后端,禁止在组件内散落 fetch - SSE 连接封装在
lib/sse-client.ts,不在组件内直接实例化 EventSource - 所有 API 调用必须有 TypeScript 类型定义和错误处理(
ApiError统一承载 code/trace_id)
可视化规范
- 图谱可视化使用专用图谱库,Mermaid 用于流程图/时序图等
- 可视化组件必须支持响应式和主题切换 (暗色/亮色)
代码审查
pnpm lint # ESLint 检查
pnpm type-check # TypeScript 类型检查
pnpm format:check # Prettier 格式检查
pnpm test # Vitest 测试
- 必须同时通过 lint、type-check 与格式检查才能提交
- Husky + lint-staged 已配置
pre-commit钩子:对暂存文件自动跑 ESLint --fix + Prettier,再整体 type-check;不通过则阻止提交(临时跳过用git commit --no-verify) - 注:本仓库 git 根在父目录(monorepo),
prepare脚本以cd .. && husky frontend/.husky安装钩子,core.hooksPath指向frontend/.husky/_
绝对禁止事项
- 直接修改
package.json或pnpm-lock.yaml(依赖必须用pnpm add/remove;scripts 字段可用pnpm pkg set,注意带冒号的键需用方括号语法scripts["name"]) - 在客户端代码中硬编码敏感信息 (密钥、Token等)
- 使用
any类型 (除非经过团队评审) - 忽略 TypeScript 或 ESLint 错误强制提交
- 在 Server Component 中直接使用
useState、useEffect等客户端 Hooks - 使用 CSS-in-JS 方案 (统一使用 Tailwind CSS)
- 在 Client Component 中直接调用数据库
- 在 useEffect 中做页面初始数据请求
- 创建 Class 组件