pma-web
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseWeb Frontend Implementation Guide
Web前端实现指南
Standard frontend stack and conventions for web application projects.
Web应用项目的标准前端技术栈与规范。
Tech Stack
技术栈
| Category | Technology | Version | Notes |
|---|---|---|---|
| Core | |||
| Framework | React | 19.2 | |
| Language | TypeScript | 5.9 | strict mode |
| Build tool | Vite | 8 | host: |
| Package manager | bun workspaces | — | monorepo |
| Routing & State | |||
| Router | React Router | 7 | lazy routes for code splitting |
| Async state | TanStack Query | 5.90 | request caching, refetch, sync |
| Client state | Zustand | 5.0 | UI-only state |
| UI & Styling | |||
| Component library | shadcn/ui + Base UI | — | |
| CSS | Tailwind CSS | 4.2 | |
| Theming | shadcn/ui ThemeProvider | — | official Vite guide, light / dark / system |
| i18n | |||
| Internationalization | react-i18next | — | i18next-http-backend for lazy loading |
| Tooling | |||
| Lint / format | ESLint + @antfu/eslint-config | 10 / 7.7 |
| 分类 | 技术 | 版本 | 说明 |
|---|---|---|---|
| 核心 | |||
| 框架 | React | 19.2 | |
| 语言 | TypeScript | 5.9 | 严格模式 |
| 构建工具 | Vite | 8 | host: |
| 包管理器 | bun workspaces | — | 单仓库(Monorepo) |
| 路由与状态管理 | |||
| 路由 | React Router | 7 | 懒加载路由实现代码分割 |
| 异步状态 | TanStack Query | 5.90 | 请求缓存、重新获取、同步 |
| 客户端状态 | Zustand | 5.0 | 仅UI相关状态 |
| UI与样式 | |||
| 组件库 | shadcn/ui + Base UI | — | |
| CSS框架 | Tailwind CSS | 4.2 | |
| 主题管理 | shadcn/ui ThemeProvider | — | 官方Vite指南,支持亮色/暗色/系统模式 |
| 国际化 | |||
| 国际化方案 | react-i18next | — | 使用i18next-http-backend实现懒加载 |
| 工具链 | |||
| 代码检查/格式化 | ESLint + @antfu/eslint-config | 10 / 7.7 |
Monorepo Structure
单仓库(Monorepo)结构
bunfig.toml
bun.lock
package.json # workspaces: ["apps/*", "packages/*"]
apps/
web/
src/
app/
providers.tsx # compose all Providers
router.tsx # React Router 7 route config
i18n.ts # i18n initialization
features/ # organized by business domain
auth/
components/
hooks/
api.ts # TanStack Query hooks
store.ts # Zustand store (if needed)
routes.tsx
dashboard/
...
shared/
components/
ui/ # shadcn/ui components
theme-provider.tsx # shadcn/ui official ThemeProvider
mode-toggle.tsx # shadcn/ui official ModeToggle
hooks/
lib/
http.ts # fetch wrapper
query-client.ts # TanStack Query client
types/
styles/
theme.css # CSS variables & design tokens
index.html
vite.config.ts
tsconfig.json
package.json
packages/
config/ # @repo/config — shared configs
tsconfig/
base.json # module: NodeNext, strict: true, target: ES2022
react.json # extends base, module: ESNext, jsx: react-jsx
utils.json # extends base, declaration: true
package.json
shared/ # @repo/shared — cross-workspace types
src/
index.ts # domain types, API types, shared constants
package.json
eslint.config.tsbunfig.toml
bun.lock
package.json # workspaces: ["apps/*", "packages/*"]
apps/
web/
src/
app/
providers.tsx # 组合所有Providers
router.tsx # React Router 7路由配置
i18n.ts # 国际化初始化
features/ # 按业务领域组织
auth/
components/
hooks/
api.ts # TanStack Query钩子
store.ts # Zustand状态仓库(按需使用)
routes.tsx
dashboard/
...
shared/
components/
ui/ # shadcn/ui组件
theme-provider.tsx # shadcn/ui官方ThemeProvider
mode-toggle.tsx # shadcn/ui官方ModeToggle
hooks/
lib/
http.ts # fetch封装
query-client.ts # TanStack Query客户端
types/
styles/
theme.css # CSS变量与设计令牌
index.html
vite.config.ts
tsconfig.json
package.json
packages/
config/ # @repo/config — 共享配置
tsconfig/
base.json # 基础配置:module: NodeNext, strict: true, target: ES2022
react.json # 继承基础配置,module: ESNext, jsx: react-jsx
utils.json # 继承基础配置,declaration: true
package.json
shared/ # @repo/shared — 跨工作区类型定义
src/
index.ts # 领域类型、API类型、共享常量
package.json
eslint.config.tsbun workspaces
bun workspaces 配置
- Root declares
package.json"workspaces": ["apps/*", "packages/*"] - for workspace-level options
bunfig.toml - Use instead of
bun installpnpm install - Run scripts:
bun run --filter apps/web dev - Cross-package references: ,
"@repo/config": "workspace:*""@repo/shared": "workspace:*"
- 根目录中声明
package.json"workspaces": ["apps/*", "packages/*"] - 用于配置工作区级别的选项
bunfig.toml - 使用替代
bun installpnpm install - 运行脚本:
bun run --filter apps/web dev - 跨包引用:,
"@repo/config": "workspace:*""@repo/shared": "workspace:*"
packages/config — Shared Configs
packages/config — 共享配置
Shared TypeScript configs for all workspaces:
| File | Purpose |
|---|---|
| Base: |
| Extends base: |
| Extends base: |
Each app's extends the appropriate config:
tsconfig.jsonjson
{
"extends": "@repo/config/tsconfig/react.json",
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}为所有工作区提供共享TypeScript配置:
| 文件 | 用途 |
|---|---|
| 基础配置: |
| 继承基础配置: |
| 继承基础配置: |
每个应用的继承对应配置:
tsconfig.jsonjson
{
"extends": "@repo/config/tsconfig/react.json",
"compilerOptions": {
"baseUrl": ".",
"paths": { "@/*": ["./src/*"] }
}
}packages/shared — Cross-Workspace Types
packages/shared — 跨工作区类型定义
Single entry point exporting all shared types:
- Domain types (entities, enums, constants)
- API types (, request/response shapes)
ApiResponse<T> - Use for type-only imports across workspaces
import type
单一入口导出所有共享类型:
- 领域类型(实体、枚举、常量)
- API类型(、请求/响应结构)
ApiResponse<T> - 跨工作区的类型导入必须使用
import type
State Management
状态管理方案
| Data type | Solution |
|---|---|
| Async/request state | TanStack Query |
| Client UI state | Zustand |
| Theme | shadcn/ui ThemeProvider (single source of truth) |
| Forms | Controlled components or react-hook-form |
| 数据类型 | 解决方案 |
|---|---|
| 异步/请求状态 | TanStack Query |
| 客户端UI状态 | Zustand |
| 主题状态 | shadcn/ui ThemeProvider(单一数据源) |
| 表单 | 受控组件或react-hook-form |
Theming
主题管理
- Use shadcn/ui official Vite dark mode guide
- ThemeProvider is the single source of truth — do not mix with Zustand
- Support light / dark / system modes
- Persist via
localStorage - Tailwind 4.2 defines design tokens;
@themeclass toggles variable values.dark
- 遵循shadcn/ui官方Vite暗黑模式指南
- ThemeProvider是单一数据源——不要与Zustand混合使用
- 支持亮色/暗色/系统模式
- 通过持久化
localStorage - Tailwind 4.2的定义设计令牌;
@theme类切换变量值.dark
i18n
国际化(i18n)
- react-i18next + i18next-http-backend for lazy loading
- Namespace per feature: common, auth, dashboard, etc.
- Language files at
public/locales/{{lng}}/{{ns}}.json - Support zh-CN and en, fallback to zh-CN
- Auto-detect via i18next-browser-languagedetector
- 使用react-i18next + i18next-http-backend实现懒加载
- 按功能模块划分命名空间:common、auth、dashboard等
- 语言文件存放于
public/locales/{{lng}}/{{ns}}.json - 支持zh-CN和en,回退到zh-CN
- 通过i18next-browser-languagedetector自动检测语言
Provider Composition Order
Provider组合顺序
I18nextProvider
└─ QueryClientProvider
└─ ThemeProvider
└─ AppI18nextProvider
└─ QueryClientProvider
└─ ThemeProvider
└─ AppConventions
编码规范
| Area | Convention |
|---|---|
| API layer | Each feature exports |
| Routing | Feature-level |
| Components | shadcn/ui → |
| Naming | Files: kebab-case; Components: PascalCase; Hooks: |
| Path alias | |
| Imports | |
| Styling | |
| 领域 | 规范 |
|---|---|
| API层 | 每个功能模块从 |
| 路由 | 功能模块级别的 |
| 组件 | shadcn/ui组件→ |
| 命名 | 文件:短横线命名(kebab-case);组件:大驼峰命名(PascalCase);钩子: |
| 路径别名 | |
| 类型导入 | 类型导入必须使用 |
| 样式 | |
ESLint
ESLint配置
- with
@antfu/eslint-config, TypeScript, Reacttype: 'app' - No Prettier — ESLint handles formatting
- Stylistic: 2-space indent, single quotes, no semicolons
- Ignore shadcn/ui generated components:
src/components/ui/**
- 使用,配置
@antfu/eslint-config,支持TypeScript、Reacttype: 'app' - 不使用Prettier——ESLint处理格式化
- 风格:2空格缩进、单引号、无分号
- 忽略shadcn/ui生成的组件:
src/components/ui/**
Vite Config
Vite配置
ts
// vite.config.ts
export default defineConfig({
plugins: [
tailwindcss(), // @tailwindcss/vite
tsConfigPaths(), // vite-tsconfig-paths
react(), // @vitejs/plugin-react
],
server: {
host: '0.0.0.0',
allowedHosts: true,
},
})ts
// vite.config.ts
export default defineConfig({
plugins: [
tailwindcss(), // @tailwindcss/vite
tsConfigPaths(), // vite-tsconfig-paths
react(), // @vitejs/plugin-react
],
server: {
host: '0.0.0.0',
allowedHosts: true,
},
})shadcn/ui Initialization
shadcn/ui初始化
Step 1: Init shadcn in the app directory
步骤1:在应用目录中初始化shadcn
bash
cd apps/web
bunx shadcn@latest initSelect these options:
- Style:
base-nova - Base color:
neutral - CSS variables: yes
- RSC: no (Vite, not Next.js)
- Icon library:
lucide
This generates :
components.jsonjson
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}bash
cd apps/web
bunx shadcn@latest init选择以下选项:
- 风格:
base-nova - 基础颜色:
neutral - CSS变量:是
- RSC:否(使用Vite,非Next.js)
- 图标库:
lucide
这将生成:
components.jsonjson
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "base-nova",
"rsc": false,
"tsx": true,
"tailwind": {
"config": "",
"css": "src/index.css",
"baseColor": "neutral",
"cssVariables": true
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
}
}Step 2: Add components
步骤2:添加组件
bash
undefinedbash
undefinedAdd individual components
添加单个组件
bunx shadcn@latest add button card dialog
bunx shadcn@latest add button card dialog
Add theme components for dark mode
添加主题相关组件以支持暗黑模式
bunx shadcn@latest add sonner
undefinedbunx shadcn@latest add sonner
undefinedStep 3: Theme setup (dark mode)
步骤3:主题设置(暗黑模式)
Follow the official Vite dark mode guide:
- Create — ThemeProvider context
src/shared/components/theme-provider.tsx - Create — theme switcher UI
src/shared/components/mode-toggle.tsx - Wrap app with
<ThemeProvider defaultTheme="system" storageKey="ui-theme">
遵循官方Vite暗黑模式指南:
- 创建——ThemeProvider上下文
src/shared/components/theme-provider.tsx - 创建——主题切换UI
src/shared/components/mode-toggle.tsx - 使用包裹应用
<ThemeProvider defaultTheme="system" storageKey="ui-theme">
Notes
注意事项
- shadcn/ui components are generated into — they are owned code, not a dependency.
src/shared/components/ui/ - ESLint should ignore (generated code).
src/shared/components/ui/** - Always use to add new components, not manual copy.
bunx shadcn@latest add
- shadcn/ui组件生成到——属于项目自有代码,而非依赖包。
src/shared/components/ui/ - ESLint应忽略(生成的代码)。
src/shared/components/ui/** - 始终使用添加新组件,不要手动复制。
bunx shadcn@latest add
Tailwind CSS v4
Tailwind CSS v4配置
css
/* src/index.css */
@import 'tailwindcss';
@import 'tw-animate-css';
@custom-variant dark (&:is(.dark *));
@theme inline {
/* map CSS variables to Tailwind color tokens */
--color-background: var(--background);
--color-foreground: var(--foreground);
/* ... */
}css
/* src/index.css */
@import 'tailwindcss';
@import 'tw-animate-css';
@custom-variant dark (&:is(.dark *));
@theme inline {
/* 映射CSS变量到Tailwind颜色令牌 */
--color-background: var(--background);
--color-foreground: var(--foreground);
/* ... */
}