Files
taotie-web/AGENTS.md

173 lines
6.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AGENTS.md
你是 JavaScript、Rsbuild 和 Web 应用开发方面的专家,编写可维护、高性能且无障碍的代码。
## 技术栈
- **React 19** + **TypeScript** — 前端框架和类型系统
- **Rsbuild 2** — 构建工具(基于 Rspack配置文件为 `rsbuild.config.ts`
- **React Router v7**`react-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 v7**`react-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 配置
- 已启用 `noUnusedLocals``noUnusedParameters`,未使用的变量/参数会报错
- 已启用 `verbatimModuleSyntax`,纯类型导入必须使用 `import type`
- `moduleResolution: "bundler"`,使用打包器风格的模块解析
## 代码风格
- **单引号**`.prettierrc``singleQuote: true`
- ESLint 仅作用于 `**/*.{ts,tsx}`,启用了 `react-hooks``react-refresh` 插件
## 注释规范
**所有代码都应附带必要的注释,说明意图而非重复代码本身。**
- 函数 / Hook用 JSDoc 说明用途、参数含义
- 复杂逻辑、非直觉的实现:行内注释解释原因
- 模拟数据 / 临时代码:标注 `// TODO:``// FIXME:` 方便后续替换
- 类型字段:用 JSDoc 注释说明每个字段的含义
```ts
// ✅ 说明意图
// 用 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
- 布局使用 `Layout``Header` / `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"`
自定义主题通过 `ConfigProvider``App.tsx` 统一配置:
```tsx
import { ConfigProvider } from 'antd';
<ConfigProvider theme={{ token: { colorPrimary: '#00b96b' } }}>
<RouterProvider router={router} />
</ConfigProvider>
```
## HTTP 请求
- 所有请求通过 `src/utils/request.ts` 封装的方法发出,不直接使用 `axios`
- **只使用 `get``post` 两种方法**,不使用 `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` |
```ts
// 使用示例
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` 代替)
## 参考文档
- Rsbuild: https://rsbuild.rs/llms.txt
- Rspack: https://rspack.rs/llms.txt
- antd v6 组件导航文档: https://ant.design/llms.txt