Files
taotie-web/AGENTS.md

6.9 KiB
Raw Blame History

AGENTS.md

你是 JavaScript、Rsbuild 和 Web 应用开发方面的专家,编写可维护、高性能且无障碍的代码。

技术栈

  • React 19 + TypeScript — 前端框架和类型系统
  • Rsbuild 2 — 构建工具(基于 Rspack配置文件为 rsbuild.config.ts
  • React Router v7react-router)— 客户端路由
  • antd 6 + @ant-design/icons 6 — UI 组件库和图标集
  • pnpm — 包管理器

常用命令

  • pnpm run dev — 启动开发服务器(自动打开 http://localhost:3000
  • pnpm run build — 构建生产版本(输出至 dist/
  • pnpm run preview — 本地预览生产构建
  • pnpm run lint — 使用 ESLint 检查 TypeScript/TSX 文件
  • pnpm run format — 使用 Prettier 格式化所有文件

项目结构

src/
  index.tsx          # 应用入口,将 React 根节点挂载到 #root
  App.tsx            # 根组件,渲染 <RouterProvider>,包含 ConfigProvider / AntdApp 全局配置
  App.css            # 全局样式reset
  router.tsx         # createBrowserRouter由路由树自动生成
  env.d.ts           # Rsbuild 环境变量类型声明ImportMetaEnv
  routes/
    types.ts         # RouteItem 类型定义
    index.tsx        # 路由树数据(唯一数据源),导出 routes / RouteItem
    utils.tsx        # toRouteObjects():将路由树转为 React Router RouteObject[]
  layouts/
    RootLayout.tsx   # 根布局Header + Sider + Content
  pages/
    Home.tsx         # "/" 首页
    About.tsx        # "/about" 关于页
    NotFound.tsx     # "*" 兜底 404 页
  types/
    http.d.ts        # 全局 API 命名空间(无需 import 直接使用 API.Response<T>
  utils/
    request.ts       # axios 实例封装,导出 get / post / put / del
.env                 # 本地环境变量(已 gitignore勿提交
.env.example         # 环境变量模板(提交到仓库供参考)
public/
  favicon.png
rsbuild.config.ts    # 构建配置
eslint.config.mjs    # ESLint 扁平配置(仅作用于 TS/TSX忽略 dist/
tsconfig.json

环境变量

  • 变量文件:.env(本地,已 gitignore
  • 模板文件:.env.example(提交到仓库)
  • 新成员初始化:cp .env.example .env
  • Rsbuild 规则:PUBLIC_ 为前缀的变量会暴露给客户端,通过 import.meta.env.PUBLIC_XXX 读取
变量 说明
PUBLIC_BASE_URL 后端接口 baseURL

不同环境可创建 .env.development / .env.production 覆盖默认值,.env.example 中同步维护所有变量。

路由

使用 React Router v7react-router)的 createBrowserRouter

  • 唯一数据源src/routes/index.tsx 维护 routes: RouteItem[] 路由树
  • RouteItem 字段:path / label / icon? / component? / hideInMenu? / redirect? / children?
  • toRouteObjects(routes) 将路由树转换为 React Router 所需的 RouteObject[]
  • 菜单、面包屑等模块直接消费 routes 数组,无需重复维护路由信息
  • 添加新页面:在 src/pages/ 创建组件,在 src/routes/index.tsx 追加节点即可

TypeScript 配置

  • 已启用 noUnusedLocalsnoUnusedParameters,未使用的变量/参数会报错
  • 已启用 verbatimModuleSyntax,纯类型导入必须使用 import type
  • moduleResolution: "bundler",使用打包器风格的模块解析

代码风格

  • 单引号.prettierrcsingleQuote: true
  • ESLint 仅作用于 **/*.{ts,tsx},启用了 react-hooksreact-refresh 插件

注释规范

所有代码都应附带必要的注释,说明意图而非重复代码本身。

  • 函数 / Hook用 JSDoc 说明用途、参数含义
  • 复杂逻辑、非直觉的实现:行内注释解释原因
  • 模拟数据 / 临时代码:标注 // TODO:// FIXME: 方便后续替换
  • 类型字段:用 JSDoc 注释说明每个字段的含义
// ✅ 说明意图
// 用 cancelled 标志位防止组件卸载后的竞态更新
let cancelled = false;

/**
 * 根据部门 ID 获取用户列表
 * @param deptKey 部门节点 key
 */
const fetchUsersByDept = (deptKey: string): Promise<UserRecord[]> => { ... };

// TODO: 替换为真实接口
const mockData = [...];

UI 组件规范antd

页面 UI 优先使用 antd 组件,不自行实现已有组件的功能。

  • antd 直接导入组件,从 @ant-design/icons 导入图标,自动 tree-shaking
  • 布局使用 LayoutHeader / Sider / Content / Footer
  • 导航使用 Menu,面包屑使用 Breadcrumb
  • 表单使用 Form + Form.Item,不使用原生 <form>
  • 按钮使用 Button,不使用原生 <button>
  • 弹窗使用 Modal,消息提示使用 message / notification
  • 数据展示使用 Table / List / Descriptions / Card
  • 空状态使用 Empty,加载状态使用 Spin / Skeleton
  • 404 页面使用 Result status="404"

自定义主题通过 ConfigProviderApp.tsx 统一配置:

import { ConfigProvider } from 'antd';
<ConfigProvider theme={{ token: { colorPrimary: '#00b96b' } }}>
  <RouterProvider router={router} />
</ConfigProvider>

HTTP 请求

  • 所有请求通过 src/utils/request.ts 封装的方法发出,不直接使用 axios
  • 只使用 getpost 两种方法,不使用 put / delete 等其他方法
  • 编辑接口用 post,路径加 /edit 后缀;删除接口用 post,路径加 /del 后缀
  • 全局响应结构 API.Response<T> 定义在 src/types/http.d.ts,无需 import 直接使用
  • 请求拦截器(添加 token和响应拦截器处理错误码统一在 request.ts 中维护
  • 接口函数统一放在 src/api/ 下,按模块分文件管理(如 src/api/system/user.ts

接口函数命名规范:

操作 前缀 示例
新增 add addDept
编辑 edit editDept
删除 del delDept
获取列表 list listUser
获取详情 detail detailUser
特殊查询(树等) 语义命名 deptTree
// 使用示例
import { get, post } from '../utils/request';

const res = await get<User[]>('/api/users');
// res.code / res.msg / res.data / res.ok / res.time

API 层规范

  • 数据结构不导出src/api/ 目录下的 interface / type 不得加 export,禁止其他模块 import
  • 组件自定类型:页面组件如需使用数据结构,在组件文件内自行定义,不依赖 API 层的类型
  • mock 文件同理src/mock/ 下的文件也需自行定义类型,不导入 src/api/ 中的类型
  • API 函数可以内部使用类型,但签名中避免使用导出的复杂类型(可用 Record<string, unknown>any 代替)

参考文档