# react-template **Repository Path**: overflow_z/react-template ## Basic Information - **Project Name**: react-template - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-06 - **Last Updated**: 2026-08-06 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # React Template 基于 Vite 8 + React 19 + TypeScript 6 构建的企业级前端开发模板,开箱即用。 ## 技术栈 | 类别 | 技术 | 版本 | |------|------|------| | 构建工具 | Vite (Rolldown) | 8.2 | | 框架 | React | 19.2 | | 类型系统 | TypeScript | 6.0 | | 样式方案 | Tailwind CSS | 4.3 | | UI 组件库 | shadcn/ui (base-ui + CVA) | 4.16 | | 图标库 | Lucide React | 1.28 | | 动画 | Framer Motion | 13.0 | | 路由 | TanStack Router | 1.170 | | 状态管理 | Zustand | 5.0 | | 数据请求 | TanStack Query | 5.101 | | 表单 | TanStack Form | 1.33 | | 代码检查 | Oxlint | 1.75 | | 测试框架 | Vitest + Testing Library | 4.1 / 16.3 | | Git Hooks | Lefthook | 2.1 | | 提交规范 | Commitlint + cz-git | 21.2 / 1.13 | | Toast 通知 | Sonner | 2.0 | | 错误边界 | react-error-boundary | 6.1 | | 缓存 | Web Crypto API + IndexedDB | built-in | ## 目录结构 ``` src/ ├── components/ │ ├── custom/ # 自定义业务组件 │ │ ├── async-state.tsx # 统一 Loading/Empty/Error 状态组件 │ │ ├── error-boundary.tsx # 错误边界 │ │ ├── error-page.tsx # 通用错误页面(404/403/500) │ │ ├── route-loading.tsx # 路由加载指示器 │ │ └── theme-toggle.tsx # 主题切换按钮 │ ├── layout/ │ │ └── root-layout.tsx # 根布局(导航栏 + 主题切换) │ ├── ui/ # shadcn/ui 原生组件(60+) │ └── theme-provider.tsx # 主题 Provider(dark/light/system) ├── hooks/ # 自定义 Hooks │ ├── use-mobile.ts # 移动端检测 │ ├── use-nprogress.ts # 路由进度条 │ └── use-query.ts # React Query 封装 hooks ├── lib/ │ ├── cache/ # 缓存模块 │ │ ├── types.ts # 类型定义 │ │ ├── crypto.ts # AES-GCM 加密/解密 │ │ ├── storage.ts # 抽象基类(TTL 过期 + 加密) │ │ ├── local.ts # localStorage 适配器 │ │ ├── session.ts # sessionStorage 适配器 │ │ ├── indexed-db.ts # IndexedDB 适配器 │ │ └── index.ts # 统一导出 + 全局实例 │ ├── query-client.ts # React Query 全局配置 │ ├── request.ts # HTTP 客户端(qs 序列化 + 多 base URL) │ └── utils.ts # 工具函数(cn 类名合并) ├── stores/ # Zustand 状态管理 │ ├── __tests__/ # Store 测试 │ └── counter.ts # 计数器示例 ├── styles/ # 全局样式 │ ├── globals.css # Tailwind 主题 + 暗色模式 │ └── nprogress.css # 进度条样式 ├── types/ │ └── env.d.ts # 环境变量类型声明 ├── views/ # TanStack Router 文件路由(自动生成) │ ├── __root.tsx # 根路由(布局 + 过渡动画) │ ├── index.tsx # 首页 │ ├── about.tsx # 关于页 │ ├── dashboard.tsx # 仪表盘 │ ├── settings.tsx # 设置页 │ ├── -not-found.tsx # 404 页面 │ ├── -forbidden.tsx # 403 页面 │ └── -server-error.tsx # 500 页面 ├── main.tsx # 应用入口 ├── routeTree.gen.ts # 自动生成的路由树 ├── test-setup.ts # 测试环境配置 └── vite-env.d.ts # Vite 类型声明 ``` ## 快速开始 ```bash # 安装依赖(推荐使用 pnpm) pnpm install # 启动开发服务器 pnpm dev # 构建生产版本 pnpm build # 预览生产构建 pnpm preview ``` ## 可用脚本 | 命令 | 说明 | |------|------| | `pnpm dev` | 启动开发服务器(HMR) | | `pnpm build` | 生产环境构建 | | `pnpm preview` | 预览生产构建产物 | | `pnpm typecheck` | TypeScript 类型检查 | | `pnpm lint` | 代码规范检查(Oxlint) | | `pnpm test` | 运行单元测试 | | `pnpm test:coverage` | 测试覆盖率报告 | | `pnpm commit` | 使用 cz-git 交互式提交 | ## 开发规范 ### 组件规范 - 页面中所有 UI 元素必须使用 shadcn/ui 组件,禁止手动编写原生 HTML 元素 - 自定义业务组件放在 `src/components/custom/`,shadcn 原生组件放在 `src/components/ui/` - 仅使用函数组件,禁止使用 Class 组件 - 组件文件使用 PascalCase 命名(如 `UserProfile.tsx`) - 导航跳转必须使用 `useNavigate` hook,禁止使用 `` 标签 ### 命名约定 | 类型 | 风格 | 示例 | |------|------|------| | 组件/类 | PascalCase | `UserProfile` | | 函数/变量 | camelCase | `getUserInfo` | | 常量 | UPPER_SNAKE_CASE | `API_BASE_URL` | | 文件名 | PascalCase / kebab-case | `UserProfile.tsx` | ### Git 提交规范 使用 Angular 提交规范,通过 `pnpm commit` 交互式提交: ``` (): feat: 新功能 fix: 修复 Bug docs: 文档更新 style: 代码格式(不影响功能) refactor: 重构 perf: 性能优化 test: 测试相关 chore: 构建/工具链变更 ``` ### Git Hooks | Hook | 行为 | |------|------| | pre-commit | Oxlint 检查 + TypeScript 类型检查 | | commit-msg | 校验提交信息是否符合 Angular 规范 | | pre-push | 运行测试 + 构建验证 | ## 主题 支持浅色/深色/跟随系统三种模式,通过导航栏右侧的太阳/月亮图标切换。主题偏好保存在 localStorage 中。 ```tsx import { useTheme } from "@/components/theme-provider"; const { theme, setTheme } = useTheme(); setTheme("dark"); // "light" | "dark" | "system" ``` 主题色在 `src/styles/globals.css` 中通过 CSS 变量控制,修改 `--primary` 即可全局切换: ```css :root { --primary: #3b82f6; /* 主色 */ --primary-foreground: #ffffff; /* 主色上的文字颜色 */ } ``` ## HTTP 请求 模板内置了基于 Fetch API 的 HTTP 客户端,支持: - 请求/响应拦截 - 自动 Toast 错误提示(sonner) - 静默模式(不弹错误提示) - HTTP 状态码 + 业务错误码双重处理 - qs 参数序列化(支持嵌套对象和数组) - 多 base URL 客户端 ```ts import { http, httpClients } from "@/lib/request"; // GET 请求(参数自动 qs 序列化) const users = await http.get("/users", { params: { page: 1 } }); // POST 请求(静默错误) await http.post("/api/data", payload, { silent: true }); // 使用命名客户端 const userData = await httpClients.user.get("/profile"); ``` ### React Query 封装 ```tsx import { useGet, usePost, useUsers } from "@/hooks/use-query"; // 通用 hooks const { data, isLoading } = useGet(["users"], "/users", { page: 1 }); const { mutate } = usePost("/users"); // 业务 hooks const { data: users } = useUsers(); ``` ## 缓存 内置统一缓存模块,支持 localStorage / sessionStorage / IndexedDB 三种后端,统一 API: ```ts import { storage, session, indexedDB } from "@/lib/cache"; // 同步读写(localStorage / sessionStorage,开发环境明文) storage.set("user", { name: "Tom" }, 5 * 60 * 1000); // 5 分钟过期 const user = storage.get("user"); // 异步读写(支持加密,IndexedDB 必须异步) await storage.setAsync("token", "abc123"); // 生产环境自动 AES-GCM 加密 const token = await storage.getAsync("token"); await indexedDB.setAsync("bigData", largeObject); // 自定义实例 import { createLocalCache, createIndexedDBCache } from "@/lib/cache"; const userCache = createLocalCache({ ttl: 60_000, encrypt: false }); const dbCache = createIndexedDBCache({ dbName: "myApp", ttl: 24 * 60 * 60 * 1000 }); ``` - **TTL 过期**:设置 `ttl` 参数,数据过期后自动清除 - **加密**:生产环境自动启用 AES-GCM 加密,开发环境明文存储 - **IndexedDB**:异步操作,使用 `getAsync` / `setAsync` / `keysAsync` / `hasAsync` ## 异步状态组件 使用 `AsyncState` 统一处理 loading / empty / error 三种状态: ```tsx import { AsyncState } from "@/components/custom/async-state"; ``` ## 错误页面 模板内置了 404、403、500 错误页面,通过 TanStack Router 的 `notFoundComponent` 和 `errorComponent` 自动触发。 ## 路由 使用 TanStack Router 文件路由系统,页面文件放在 `src/views/` 目录下: - `__root.tsx` — 根路由(布局 + Framer Motion 过渡动画 + NProgress 进度条) - `index.tsx` — 首页 `/` - `about.tsx` — 关于页 `/about` - `dashboard.tsx` — 仪表盘 `/dashboard` - `settings.tsx` — 设置页 `/settings` - `-not-found.tsx` — 404 页面 - `-forbidden.tsx` — 403 页面 - `-server-error.tsx` — 500 页面 新增页面只需在 `views/` 下创建文件,路由自动生成。文件名以 `-` 开头则不会被注册为路由(如 `-not-found.tsx`)。 ```tsx // src/views/hello.tsx import { createFileRoute } from "@tanstack/react-router"; function HelloView() { return

Hello World

; } export const Route = createFileRoute("/hello")({ component: HelloView, }); ``` ## 环境变量 | 变量 | 说明 | 默认值 | |------|------|--------| | `VITE_APP_TITLE` | 应用名称 | React Template | | `VITE_SERVER_PORT` | 开发服务器端口 | 5173 | | `VITE_SERVER_HOST` | 开发服务器主机 | localhost | | `VITE_OPEN_BROWSER` | 启动时自动打开浏览器 | false | | `VITE_PROXY_TARGET` | API 代理配置(JSON 数组) | `[["/api","http://localhost:3000"]]` | | `VITE_PROXY_REWRITE` | 代理时是否重写路径前缀 | false | | `VITE_API_BASE_URL` | 客户端 API 请求前缀 | /api | | `VITE_API_BASE_URLS` | 多 base URL 客户端(JSON 对象) | - | TypeScript 类型定义位于 `src/types/env.d.ts`。 ## CI/CD GitHub Actions 工作流(`.github/workflows/ci-cd.yml`)在 `main` 分支 push / PR 时自动触发: | Job | 说明 | |-----|------| | Lint & Type Check | Oxlint 代码规范检查 | | Unit Tests | Vitest 单元测试 + 覆盖率报告(上传 Codecov) | | Build | 生产构建 + 产物大小分析 | | Deploy | 仅 main 分支或 tag 推送时触发,发布 GitHub Release | CI 环境使用 **pnpm 9** + **Node.js 22**,通过 `--frozen-lockfile` 确保依赖一致性。 ## 构建优化 - **代码分割**:React、Zustand 等大型依赖拆分为独立 chunk - **Gzip/Deflate 压缩**:构建产物自动生成 `.gz` 文件 - **Tree Shaking**:自动移除未使用代码 - **CSS 分割**:CSS 按需加载 - **Rolldown**:基于 Rust 的极速打包器 ## 生产部署 ```bash pnpm build # 将 dist/ 目录部署到服务器 ``` 建议 Nginx 配置静态压缩: ```nginx gzip_static on; ```