Files
taotie-web/AGENTS.md

8.3 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 根节点 + 启动 MSW mock
  App.tsx                 # 根组件ConfigProvider / AntdApp / RouterProvider
  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
    SystemLayout.tsx      # 系统配置布局(<Outlet />,作为 /system 父路由容器)
  components/
    AuthGuard.tsx         # 路由守卫(未登录跳转登录页)
  hooks/
    useAppInit.ts         # 应用初始化 hook刷新页面时重新获取用户信息
  api/
    auth.ts               # 登录接口
    system/
      user.ts             # 部门 / 用户接口
      role.ts             # 角色接口
  store/
    index.ts              # 统一导出入口
    app.ts                # 全局应用状态(侧边栏折叠等)
    user.ts               # 用户状态userInfo / token
  mock/
    index.ts              # MSW worker 初始化,汇总所有 handlers
    auth.ts               # 登录 mock
    system.ts             # 部门 / 用户 / 角色 mock
  pages/
    login/
      index.tsx           # "/login" 登录页(不加载布局)
    home/
      index.tsx           # "/" 首页
    about/
      index.tsx           # "/about" 关于页
    not-found/
      index.tsx           # "*" 兜底 404 页
    system/
      user/
        index.tsx         # "/system/user" 用户管理入口
        DeptTree.tsx      # 部门树组件
        DeptModal.tsx     # 部门弹窗组件
        UserTable.tsx     # 用户表格组件
        UserModal.tsx     # 用户弹窗组件
      role/
        index.tsx         # "/system/role" 角色管理入口
        RoleTable.tsx     # 角色表格组件
        RoleModal.tsx     # 角色弹窗组件
  types/
    http.d.ts             # 全局 API 命名空间(无需 import 直接使用 API.Response<T>
  utils/
    request.ts            # axios 实例封装,导出 get / post自动附加 token
.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 代替)

参考文档