5.9 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Popiart SkillHub 前端。技术栈:React 18 + TypeScript + Vite 5(非 Vue),UI 用 Arco Design(@arco-design/web-react)+ Tailwind CSS v4 + SCSS,状态管理 Zustand,路由 React Router 6,请求 Axios,国际化 i18next。
强制规则(改代码/UI/文档前必读)
AGENTS.md 将以下 .cursor 规则声明为 mandatory:
.cursor/skills/react-best-practices/SKILL.md(始终生效).cursor/rules/changelog-writing.mdc- UI/样式设计参考
.cursor/skills/frontend-design/SKILL.md;Figma 像素还原参考.cursor/skills/figma-ui-implementation/SKILL.md
核心硬约束:
- 禁止
any:ESLintstrictTypeChecked+no-explicit-any: error,lint 零 warning(--max-warnings 0)。 - 所有 UI 文案必须走 i18n,禁止硬编码。
- 只用函数组件 + hooks;state 尽量本地化,少用
useEffect/useMemo/useCallback。 - SCSS 嵌套须跟随 DOM 结构、语义化 class、避免深层选择器。
- 提交须符合 Conventional Commits(commitlint + Husky/lint-staged 提交前校验)。
常用命令
包管理器 npm(仅 package-lock.json);无 Node 版本约束(无 engines/.nvmrc)。
npm run dev— 开发服务器,端口 5195,--host 0.0.0.0。npm run build— 默认构建(先tsc -p tsconfig.app.json类型检查,再vite build)。npm run build:stage/npm run build:prod— 预发 / 生产构建(用.env.stage/.env.prod)。注意:这两个不含tsc类型检查,要查类型请单独跑npm run build或tsc。npm run preview— 预览构建产物。npm run lint/npm run lint:fix— ESLint。npm run format/npm run format:check— Prettier(printWidth 280、双引号、分号、trailingComma all)。
无测试:项目未配置任何测试框架/脚本。
架构大局(需读多文件才理解的部分)
入口:src/main.tsx 挂载 RouterProvider + AliveScope(KeepAlive)+ i18n,并 bootstrap 拉取 paramConfig / memberLevel。src/App.tsx 只做全局副作用(埋点、拖拽拦截等),路由不在 App.tsx 渲染,而在 main.tsx 的 RouterProvider。
路由(src/router/index.tsx):createBrowserRouter + 全量 lazy() 懒加载。路径统一走 ROUTES 常量(src/constants/index.ts)。布局分层:多数路由包在 src/router/LayoutRoot.tsx 下共享 Layout,首页 /index 独立于 Layout。KeepAlive 用 react-activation(CachedLayoutOutlet.tsx / routeCache.ts)。权限守卫非 Vue 式 beforeEach,而是 src/router/routeGuard.ts(集中的受保护路由表)+ LayoutRoot 内 LayoutRouteGate(useEffect 拦截,未登录弹 openLoginDialog)。
状态(src/store/):Zustand,每个 store 一个文件(useXxxStore.ts),无中央 rootStore。useUserStore 用 persist 中间件存 localStorage(key user_info)。bootstrap 类 store 暴露幂等 ensureXxx() 方法。store 内部直接调 @/api/api 拉数据。
网络层(src/api/):
request.tsaxios 实例,baseURL: "/api_client/"—— 固定相对路径,靠 Vite dev proxy 转发,不直接读VITE_API_URL。- 请求拦截注入
Authorization: Bearer <localStorage.token>。 - 响应拦截按业务码约定:
status === "0000"为成功;4001未登录→清 token 弹登录;4005积分不足→弹充值;4004支付轮询"处理中"放行;其他→Message.error。可传skipGlobalErrorHandler跳过全局处理。 - 所有接口集中在单文件
src/api/api.ts(~127 个导出函数 + 类型),并非按模块拆目录。
命令式弹窗(src/dialog/):src/dialog/index.tsx 是 barrel,导出 openLoginDialog、openInsufficientPointsDialog 等命令式 API(含 history 栈管理)。登录等交互走这些函数而非页面组件。
i18n(src/i18n/index.ts):支持 zh-CN/zh-TW/en-US,默认 zh-CN,keySeparator: false(用完整字符串作 key)。文案在 src/locales/*.json。
目录约定:src/pages(按路由,页面目录内 index.tsx + index.scss)、src/components(PascalCase 目录,index.tsx + index.scss 成对)、src/layouts/Layout/Layout.tsx(主框架,含侧栏/顶栏)、src/hooks、src/utils、src/constants。别名 @ → src。hooks/utils/dialog/constants 均有 barrel index 统一 re-export。
环境与代理(易踩坑)
- Vite dev proxy(
vite.config.mts):/api_client、/media、/resource→http://192.168.77.111:8080/(devApiTarget;注释中留有备用 targetwwwtest.popi.art/www.popi.art)。改后端联调地址在这里改。 - 三套
.env:.env(默认/dev)、.env.stage、.env.prod,VITE_前缀注入。VITE_API_URL/VITE_SKILLHUB_URL/VITE_CANVAS_URL主要用于跳转链接,而非 axios baseURL。 - prod 构建:esbuild
drop console/debugger、无 sourcemap;RollupmanualChunks手动分包(react/arco/swiper/markdown/data vendor)。
响应式适配现状
本项目 README 定位为 PC 端(≥1280px)网站,移动端基本未做真正重排。当前"适配"策略是等比缩放优先而非重排:
src/hooks/useViewportScale.ts以 1920px 设计稿为基准,用 CSSzoom/transform缩放整个 Layout 内容区(缩放下限 0.65;宽度 <900px 时关闭缩放,交由页面自身响应式)。- 媒体查询零散存在(约 40 个 scss 文件),但断点极不统一(出现过 1778/1680/1500/1280/960/900/768/480 等各种值),无统一断点体系、无 rem 方案、无 amfe-flexible / postcss-px-to-viewport。
做移动端响应式时需正视上述现状(缩放机制与页面自身响应式的边界在 900px)。