pma-web

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Web Frontend Implementation Guide

Web前端实现指南

Standard frontend stack and conventions for web application projects.
Web应用项目的标准前端技术栈与规范。

Tech Stack

技术栈

CategoryTechnologyVersionNotes
Core
FrameworkReact19.2
LanguageTypeScript5.9strict mode
Build toolVite8host:
0.0.0.0
, allowedHosts:
true
Package managerbun workspacesmonorepo
Routing & State
RouterReact Router7lazy routes for code splitting
Async stateTanStack Query5.90request caching, refetch, sync
Client stateZustand5.0UI-only state
UI & Styling
Component libraryshadcn/ui + Base UI
CSSTailwind CSS4.2
@theme
+ CSS variables
Themingshadcn/ui ThemeProviderofficial Vite guide, light / dark / system
i18n
Internationalizationreact-i18nexti18next-http-backend for lazy loading
Tooling
Lint / formatESLint + @antfu/eslint-config10 / 7.7
分类技术版本说明
核心
框架React19.2
语言TypeScript5.9严格模式
构建工具Vite8host:
0.0.0.0
, allowedHosts:
true
包管理器bun workspaces单仓库(Monorepo)
路由与状态管理
路由React Router7懒加载路由实现代码分割
异步状态TanStack Query5.90请求缓存、重新获取、同步
客户端状态Zustand5.0仅UI相关状态
UI与样式
组件库shadcn/ui + Base UI
CSS框架Tailwind CSS4.2
@theme
+ CSS变量
主题管理shadcn/ui ThemeProvider官方Vite指南,支持亮色/暗色/系统模式
国际化
国际化方案react-i18next使用i18next-http-backend实现懒加载
工具链
代码检查/格式化ESLint + @antfu/eslint-config10 / 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.ts
bunfig.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.ts

bun workspaces

bun workspaces 配置

  • Root
    package.json
    declares
    "workspaces": ["apps/*", "packages/*"]
  • bunfig.toml
    for workspace-level options
  • Use
    bun install
    instead of
    pnpm 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 install
    替代
    pnpm 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:
FilePurpose
tsconfig/base.json
Base:
module: NodeNext
,
strict: true
,
target: ES2022
tsconfig/react.json
Extends base:
module: ESNext
,
moduleResolution: bundler
,
jsx: react-jsx
,
noEmit: true
tsconfig/utils.json
Extends base:
noEmit: true
,
declaration: true
Each app's
tsconfig.json
extends the appropriate config:
json
{
  "extends": "@repo/config/tsconfig/react.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": { "@/*": ["./src/*"] }
  }
}
为所有工作区提供共享TypeScript配置:
文件用途
tsconfig/base.json
基础配置:
module: NodeNext
,
strict: true
,
target: ES2022
tsconfig/react.json
继承基础配置:
module: ESNext
,
moduleResolution: bundler
,
jsx: react-jsx
,
noEmit: true
tsconfig/utils.json
继承基础配置:
noEmit: true
,
declaration: true
每个应用的
tsconfig.json
继承对应配置:
json
{
  "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 (
    ApiResponse<T>
    , request/response shapes)
  • Use
    import type
    for type-only imports across workspaces
单一入口导出所有共享类型:
  • 领域类型(实体、枚举、常量)
  • API类型(
    ApiResponse<T>
    、请求/响应结构)
  • 跨工作区的类型导入必须使用
    import type

State Management

状态管理方案

Data typeSolution
Async/request stateTanStack Query
Client UI stateZustand
Themeshadcn/ui ThemeProvider (single source of truth)
FormsControlled 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
    @theme
    defines design tokens;
    .dark
    class toggles variable values
  • 遵循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
            └─ App
I18nextProvider
  └─ QueryClientProvider
       └─ ThemeProvider
            └─ App

Conventions

编码规范

AreaConvention
API layerEach feature exports
useXxxQuery
/
useXxxMutation
from
api.ts
RoutingFeature-level
routes.tsx
defines sub-routes;
app/router.tsx
aggregates with lazy imports
Componentsshadcn/ui →
shared/components/ui/
; business components → within each feature
NamingFiles: kebab-case; Components: PascalCase; Hooks:
use-xxx.ts
Path alias
@/
src/
Imports
import type
required for type-only imports
Styling
cn()
=
twMerge(clsx(...))
from
lib/utils.ts
领域规范
API层每个功能模块从
api.ts
导出
useXxxQuery
/
useXxxMutation
路由功能模块级别的
routes.tsx
定义子路由;
app/router.tsx
通过懒加载聚合所有路由
组件shadcn/ui组件→
shared/components/ui/
;业务组件→对应功能模块目录下
命名文件:短横线命名(kebab-case);组件:大驼峰命名(PascalCase);钩子:
use-xxx.ts
路径别名
@/
src/
类型导入类型导入必须使用
import type
样式
cn()
=
twMerge(clsx(...))
,定义于
lib/utils.ts

ESLint

ESLint配置

  • @antfu/eslint-config
    with
    type: 'app'
    , TypeScript, React
  • No Prettier — ESLint handles formatting
  • Stylistic: 2-space indent, single quotes, no semicolons
  • Ignore shadcn/ui generated components:
    src/components/ui/**
  • 使用
    @antfu/eslint-config
    ,配置
    type: 'app'
    ,支持TypeScript、React
  • 不使用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 init
Select these options:
  • Style:
    base-nova
  • Base color:
    neutral
  • CSS variables: yes
  • RSC: no (Vite, not Next.js)
  • Icon library:
    lucide
This generates
components.json
:
json
{
  "$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.json
json
{
  "$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
undefined
bash
undefined

Add 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
undefined
bunx shadcn@latest add sonner
undefined

Step 3: Theme setup (dark mode)

步骤3:主题设置(暗黑模式)

  1. Create
    src/shared/components/theme-provider.tsx
    — ThemeProvider context
  2. Create
    src/shared/components/mode-toggle.tsx
    — theme switcher UI
  3. Wrap app with
    <ThemeProvider defaultTheme="system" storageKey="ui-theme">
  1. 创建
    src/shared/components/theme-provider.tsx
    ——ThemeProvider上下文
  2. 创建
    src/shared/components/mode-toggle.tsx
    ——主题切换UI
  3. 使用
    <ThemeProvider defaultTheme="system" storageKey="ui-theme">
    包裹应用

Notes

注意事项

  • shadcn/ui components are generated into
    src/shared/components/ui/
    — they are owned code, not a dependency.
  • ESLint should ignore
    src/shared/components/ui/**
    (generated code).
  • Always use
    bunx shadcn@latest add
    to add new components, not manual copy.
  • 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);
  /* ... */
}