frontend-dev-guidelines

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Frontend Development Guidelines

前端开发指南

Purpose

目的

Comprehensive guide for modern React development, emphasizing Suspense-based data fetching, lazy loading, proper file organization, and performance optimization.
本指南为现代React开发提供全面指导,重点介绍基于Suspense的数据获取、懒加载、规范的文件组织以及性能优化。

When to Use This Skill

适用场景

  • Creating new components or pages
  • Building new features
  • Fetching data with TanStack Query
  • Setting up routing with TanStack Router
  • Styling components with MUI v7
  • Performance optimization
  • Organizing frontend code
  • TypeScript best practices

  • 创建新组件或页面
  • 开发新功能模块
  • 使用TanStack Query获取数据
  • 使用TanStack Router配置路由
  • 使用MUI v7为组件添加样式
  • 性能优化
  • 前端代码组织
  • TypeScript最佳实践

Quick Start

快速开始

New Component Checklist

新组件检查清单

Creating a component? Follow this checklist:
  • Use
    React.FC<Props>
    pattern with TypeScript
  • Lazy load if heavy component:
    React.lazy(() => import())
  • Wrap in
    <SuspenseLoader>
    for loading states
  • Use
    useSuspenseQuery
    for data fetching
  • Import aliases:
    @/
    ,
    ~types
    ,
    ~components
    ,
    ~features
  • Styles: Inline if <100 lines, separate file if >100 lines
  • Use
    useCallback
    for event handlers passed to children
  • Default export at bottom
  • No early returns with loading spinners
  • Use
    useMuiSnackbar
    for user notifications
创建组件时,请遵循以下检查清单:
  • 使用
    React.FC<Props>
    TypeScript模式
  • 若为大型组件,启用懒加载:
    React.lazy(() => import())
  • 使用
    <SuspenseLoader>
    包裹以处理加载状态
  • 使用
    useSuspenseQuery
    进行数据获取
  • 使用导入别名:
    @/
    ,
    ~types
    ,
    ~components
    ,
    ~features
  • 样式规则:代码少于100行时内联编写,超过100行时使用单独文件
  • 传递给子组件的事件处理器使用
    useCallback
    包裹
  • 在文件底部使用默认导出
  • 避免通过提前返回实现加载动画
  • 使用
    useMuiSnackbar
    实现用户通知

New Feature Checklist

新功能模块检查清单

Creating a feature? Set up this structure:
  • Create
    features/{feature-name}/
    directory
  • Create subdirectories:
    api/
    ,
    components/
    ,
    hooks/
    ,
    helpers/
    ,
    types/
  • Create API service file:
    api/{feature}Api.ts
  • Set up TypeScript types in
    types/
  • Create route in
    routes/{feature-name}/index.tsx
  • Lazy load feature components
  • Use Suspense boundaries
  • Export public API from feature
    index.ts

开发功能模块时,请按以下结构搭建:
  • 创建
    features/{feature-name}/
    目录
  • 创建子目录:
    api/
    ,
    components/
    ,
    hooks/
    ,
    helpers/
    ,
    types/
  • 创建API服务文件:
    api/{feature}Api.ts
  • types/
    目录中定义TypeScript类型
  • routes/{feature-name}/index.tsx
    中配置路由
  • 懒加载功能模块组件
  • 使用Suspense边界
  • 在功能模块的
    index.ts
    中导出公共API

Import Aliases Quick Reference

导入别名速查

AliasResolves ToExample
@/
src/
import { apiClient } from '@/lib/apiClient'
~types
src/types
import type { User } from '~types/user'
~components
src/components
import { SuspenseLoader } from '~components/SuspenseLoader'
~features
src/features
import { authApi } from '~features/auth'
Defined in: vite.config.ts lines 180-185

别名对应路径示例
@/
src/
import { apiClient } from '@/lib/apiClient'
~types
src/types
import type { User } from '~types/user'
~components
src/components
import { SuspenseLoader } from '~components/SuspenseLoader'
~features
src/features
import { authApi } from '~features/auth'
定义位置:vite.config.ts 第180-185行

Common Imports Cheatsheet

常用导入代码片段

typescript
// React & Lazy Loading
import React, { useState, useCallback, useMemo } from 'react';
const Heavy = React.lazy(() => import('./Heavy'));

// MUI Components
import { Box, Paper, Typography, Button, Grid } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';

// TanStack Query (Suspense)
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';

// TanStack Router
import { createFileRoute } from '@tanstack/react-router';

// Project Components
import { SuspenseLoader } from '~components/SuspenseLoader';

// Hooks
import { useAuth } from '@/hooks/useAuth';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';

// Types
import type { Post } from '~types/post';

typescript
// React & 懒加载
import React, { useState, useCallback, useMemo } from 'react';
const Heavy = React.lazy(() => import('./Heavy'));

// MUI 组件
import { Box, Paper, Typography, Button, Grid } from '@mui/material';
import type { SxProps, Theme } from '@mui/material';

// TanStack Query (Suspense)
import { useSuspenseQuery, useQueryClient } from '@tanstack/react-query';

// TanStack Router
import { createFileRoute } from '@tanstack/react-router';

// 项目组件
import { SuspenseLoader } from '~components/SuspenseLoader';

// 自定义Hooks
import { useAuth } from '@/hooks/useAuth';
import { useMuiSnackbar } from '@/hooks/useMuiSnackbar';

// 类型定义
import type { Post } from '~types/post';

Topic Guides

主题指南

🎨 Component Patterns

🎨 组件设计模式

Modern React components use:
  • React.FC<Props>
    for type safety
  • React.lazy()
    for code splitting
  • SuspenseLoader
    for loading states
  • Named const + default export pattern
Key Concepts:
  • Lazy load heavy components (DataGrid, charts, editors)
  • Always wrap lazy components in Suspense
  • Use SuspenseLoader component (with fade animation)
  • Component structure: Props → Hooks → Handlers → Render → Export
📖 Complete Guide: resources/component-patterns.md

现代React组件采用以下规范:
  • 使用
    React.FC<Props>
    保证类型安全
  • 使用
    React.lazy()
    实现代码分割
  • 使用
    SuspenseLoader
    处理加载状态
  • 采用“命名常量+默认导出”模式
核心概念:
  • 对大型组件(DataGrid、图表、编辑器)启用懒加载
  • 懒加载组件必须包裹在Suspense中
  • 使用带淡入动画的SuspenseLoader组件
  • 组件结构:Props定义 → Hooks调用 → 事件处理器 → 渲染逻辑 → 导出
📖 完整指南:resources/component-patterns.md

📊 Data Fetching

📊 数据获取

PRIMARY PATTERN: useSuspenseQuery
  • Use with Suspense boundaries
  • Cache-first strategy (check grid cache before API)
  • Replaces
    isLoading
    checks
  • Type-safe with generics
API Service Layer:
  • Create
    features/{feature}/api/{feature}Api.ts
  • Use
    apiClient
    axios instance
  • Centralized methods per feature
  • Route format:
    /form/route
    (NOT
    /api/form/route
    )
📖 Complete Guide: resources/data-fetching.md

首选模式:useSuspenseQuery
  • 配合Suspense边界使用
  • 缓存优先策略(先检查缓存再调用API)
  • 替代
    isLoading
    状态检查
  • 通过泛型保证类型安全
API服务层规范:
  • 创建
    features/{feature}/api/{feature}Api.ts
    文件
  • 使用
    apiClient
    axios实例
  • 按功能模块集中管理API方法
  • 路由格式:
    /form/route
    (禁止使用
    /api/form/route
📖 完整指南:resources/data-fetching.md

📁 File Organization

📁 文件组织

features/ vs components/:
  • features/
    : Domain-specific (posts, comments, auth)
  • components/
    : Truly reusable (SuspenseLoader, CustomAppBar)
Feature Subdirectories:
features/
  my-feature/
    api/          # API service layer
    components/   # Feature components
    hooks/        # Custom hooks
    helpers/      # Utility functions
    types/        # TypeScript types
📖 Complete Guide: resources/file-organization.md

features/ 与 components/ 区别:
  • features/
    : 领域特定模块(帖子、评论、权限验证)
  • components/
    : 通用可复用组件(SuspenseLoader、CustomAppBar)
功能模块子目录结构:
features/
  my-feature/
    api/          # API服务层
    components/   # 功能模块专属组件
    hooks/        # 自定义Hooks
    helpers/      # 工具函数
    types/        # TypeScript类型定义
📖 完整指南:resources/file-organization.md

🎨 Styling

🎨 样式编写

Inline vs Separate:
  • <100 lines: Inline
    const styles: Record<string, SxProps<Theme>>
  • 100 lines: Separate
    .styles.ts
    file
Primary Method:
  • Use
    sx
    prop for MUI components
  • Type-safe with
    SxProps<Theme>
  • Theme access:
    (theme) => theme.palette.primary.main
MUI v7 Grid:
typescript
<Grid size={{ xs: 12, md: 6 }}>  // ✅ v7 syntax
<Grid xs={12} md={6}>             // ❌ Old syntax
📖 Complete Guide: resources/styling-guide.md

内联与分离规则:
  • 代码少于100行:使用内联
    const styles: Record<string, SxProps<Theme>>
  • 代码超过100行:使用单独的
    .styles.ts
    文件
首选方式:
  • 为MUI组件使用
    sx
    属性
  • 通过
    SxProps<Theme>
    保证类型安全
  • 主题访问:
    (theme) => theme.palette.primary.main
MUI v7 Grid语法:
typescript
<Grid size={{ xs: 12, md: 6 }}>  // ✅ v7 正确语法
<Grid xs={12} md={6}>             // ❌ 旧版语法
📖 完整指南:resources/styling-guide.md

🛣️ Routing

🛣️ 路由配置

TanStack Router - Folder-Based:
  • Directory:
    routes/my-route/index.tsx
  • Lazy load components
  • Use
    createFileRoute
  • Breadcrumb data in loader
Example:
typescript
import { createFileRoute } from '@tanstack/react-router';
import { lazy } from 'react';

const MyPage = lazy(() => import('@/features/my-feature/components/MyPage'));

export const Route = createFileRoute('/my-route/')({
    component: MyPage,
    loader: () => ({ crumb: 'My Route' }),
});
📖 Complete Guide: resources/routing-guide.md

TanStack Router - 基于目录的路由:
  • 目录结构:
    routes/my-route/index.tsx
  • 懒加载组件
  • 使用
    createFileRoute
    创建路由
  • 在loader中配置面包屑数据
示例:
typescript
import { createFileRoute } from '@tanstack/react-router';
import { lazy } from 'react';

const MyPage = lazy(() => import('@/features/my-feature/components/MyPage'));

export const Route = createFileRoute('/my-route/')({
    component: MyPage,
    loader: () => ({ crumb: '我的路由' }),
});
📖 完整指南:resources/routing-guide.md

⏳ Loading & Error States

⏳ 加载与错误状态

CRITICAL RULE: No Early Returns
typescript
// ❌ NEVER - Causes layout shift
if (isLoading) {
    return <LoadingSpinner />;
}

// ✅ ALWAYS - Consistent layout
<SuspenseLoader>
    <Content />
</SuspenseLoader>
Why: Prevents Cumulative Layout Shift (CLS), better UX
Error Handling:
  • Use
    useMuiSnackbar
    for user feedback
  • NEVER
    react-toastify
  • TanStack Query
    onError
    callbacks
📖 Complete Guide: resources/loading-and-error-states.md

核心规则:禁止提前返回
typescript
// ❌ 绝对禁止 - 会导致布局偏移
if (isLoading) {
    return <LoadingSpinner />;
}

// ✅ 正确方式 - 保持布局稳定
<SuspenseLoader>
    <Content />
</SuspenseLoader>
原因: 避免累积布局偏移(CLS),提升用户体验
错误处理:
  • 使用
    useMuiSnackbar
    提供用户反馈
  • 禁止使用
    react-toastify
  • 通过TanStack Query的
    onError
    回调处理错误
📖 完整指南:resources/loading-and-error-states.md

⚡ Performance

⚡ 性能优化

Optimization Patterns:
  • useMemo
    : Expensive computations (filter, sort, map)
  • useCallback
    : Event handlers passed to children
  • React.memo
    : Expensive components
  • Debounced search (300-500ms)
  • Memory leak prevention (cleanup in useEffect)
📖 Complete Guide: resources/performance.md

优化模式:
  • useMemo
    : 处理昂贵计算(过滤、排序、映射)
  • useCallback
    : 传递给子组件的事件处理器
  • React.memo
    : 优化大型组件性能
  • 搜索输入防抖(300-500ms)
  • 内存泄漏预防(在useEffect中清理)
📖 完整指南:resources/performance.md

📘 TypeScript

📘 TypeScript规范

Standards:
  • Strict mode, no
    any
    type
  • Explicit return types on functions
  • Type imports:
    import type { User } from '~types/user'
  • Component prop interfaces with JSDoc
📖 Complete Guide: resources/typescript-standards.md

标准要求:
  • 启用严格模式,禁止使用
    any
    类型
  • 函数必须显式声明返回类型
  • 类型导入使用
    import type { User } from '~types/user'
  • 组件Props接口需添加JSDoc注释
📖 完整指南:resources/typescript-standards.md

🔧 Common Patterns

🔧 通用模式

Covered Topics:
  • React Hook Form with Zod validation
  • DataGrid wrapper contracts
  • Dialog component standards
  • useAuth
    hook for current user
  • Mutation patterns with cache invalidation
📖 Complete Guide: resources/common-patterns.md

涵盖主题:
  • 结合Zod校验的React Hook Form
  • DataGrid封装规范
  • Dialog组件标准
  • 获取当前用户的
    useAuth
    Hook
  • 带缓存失效的Mutation模式
📖 完整指南:resources/common-patterns.md

📚 Complete Examples

📚 完整示例

Full working examples:
  • Modern component with all patterns
  • Complete feature structure
  • API service layer
  • Route with lazy loading
  • Suspense + useSuspenseQuery
  • Form with validation
📖 Complete Guide: resources/complete-examples.md

可运行的完整示例:
  • 包含所有最佳实践的现代组件
  • 完整的功能模块结构
  • API服务层实现
  • 带懒加载的路由配置
  • Suspense + useSuspenseQuery组合
  • 带校验的表单
📖 完整指南:resources/complete-examples.md

Navigation Guide

导航指南

Need to...Read this resource
Create a componentcomponent-patterns.md
Fetch datadata-fetching.md
Organize files/foldersfile-organization.md
Style componentsstyling-guide.md
Set up routingrouting-guide.md
Handle loading/errorsloading-and-error-states.md
Optimize performanceperformance.md
TypeScript typestypescript-standards.md
Forms/Auth/DataGridcommon-patterns.md
See full examplescomplete-examples.md

需求场景参考资源
创建组件component-patterns.md
数据获取data-fetching.md
文件/目录组织file-organization.md
组件样式编写styling-guide.md
路由配置routing-guide.md
加载/错误状态处理loading-and-error-states.md
性能优化performance.md
TypeScript类型规范typescript-standards.md
表单/权限/DataGridcommon-patterns.md
查看完整示例complete-examples.md

Core Principles

核心原则

  1. Lazy Load Everything Heavy: Routes, DataGrid, charts, editors
  2. Suspense for Loading: Use SuspenseLoader, not early returns
  3. useSuspenseQuery: Primary data fetching pattern for new code
  4. Features are Organized: api/, components/, hooks/, helpers/ subdirs
  5. Styles Based on Size: <100 inline, >100 separate
  6. Import Aliases: Use @/, ~types, ~components, ~features
  7. No Early Returns: Prevents layout shift
  8. useMuiSnackbar: For all user notifications

  1. 大型组件全部懒加载:路由、DataGrid、图表、编辑器
  2. 使用Suspense处理加载状态:使用SuspenseLoader,禁止提前返回
  3. useSuspenseQuery为首选数据获取模式:新代码统一使用该模式
  4. 功能模块结构化:包含api/、components/、hooks/、helpers/子目录
  5. 按代码量选择样式方式:少于100行内联,超过100行分离
  6. 使用导入别名:统一使用@/、~types、~components、~features
  7. 禁止提前返回:避免布局偏移
  8. 统一使用useMuiSnackbar:所有用户通知均使用该方式

Quick Reference: File Structure

文件结构速查

src/
  features/
    my-feature/
      api/
        myFeatureApi.ts       # API service
      components/
        MyFeature.tsx         # Main component
        SubComponent.tsx      # Related components
      hooks/
        useMyFeature.ts       # Custom hooks
        useSuspenseMyFeature.ts  # Suspense hooks
      helpers/
        myFeatureHelpers.ts   # Utilities
      types/
        index.ts              # TypeScript types
      index.ts                # Public exports

  components/
    SuspenseLoader/
      SuspenseLoader.tsx      # Reusable loader
    CustomAppBar/
      CustomAppBar.tsx        # Reusable app bar

  routes/
    my-route/
      index.tsx               # Route component
      create/
        index.tsx             # Nested route

src/
  features/
    my-feature/
      api/
        myFeatureApi.ts       # API服务文件
      components/
        MyFeature.tsx         # 主组件
        SubComponent.tsx      # 相关组件
      hooks/
        useMyFeature.ts       # 自定义Hook
        useSuspenseMyFeature.ts  # Suspense Hook
      helpers/
        myFeatureHelpers.ts   # 工具函数
      types/
        index.ts              # TypeScript类型定义
      index.ts                # 公共导出入口

  components/
    SuspenseLoader/
      SuspenseLoader.tsx      # 可复用加载组件
    CustomAppBar/
      CustomAppBar.tsx        # 可复用导航栏

  routes/
    my-route/
      index.tsx               # 路由组件
      create/
        index.tsx             # 嵌套路由

Modern Component Template (Quick Copy)

现代组件模板(快速复制)

typescript
import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';

interface MyComponentProps {
    id: number;
    onAction?: () => void;
}

export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
    const [state, setState] = useState<string>('');

    const { data } = useSuspenseQuery({
        queryKey: ['feature', id],
        queryFn: () => featureApi.getFeature(id),
    });

    const handleAction = useCallback(() => {
        setState('updated');
        onAction?.();
    }, [onAction]);

    return (
        <Box sx={{ p: 2 }}>
            <Paper sx={{ p: 3 }}>
                {/* Content */}
            </Paper>
        </Box>
    );
};

export default MyComponent;
For complete examples, see resources/complete-examples.md

typescript
import React, { useState, useCallback } from 'react';
import { Box, Paper } from '@mui/material';
import { useSuspenseQuery } from '@tanstack/react-query';
import { featureApi } from '../api/featureApi';
import type { FeatureData } from '~types/feature';

interface MyComponentProps {
    id: number;
    onAction?: () => void;
}

export const MyComponent: React.FC<MyComponentProps> = ({ id, onAction }) => {
    const [state, setState] = useState<string>('');

    const { data } = useSuspenseQuery({
        queryKey: ['feature', id],
        queryFn: () => featureApi.getFeature(id),
    });

    const handleAction = useCallback(() => {
        setState('updated');
        onAction?.();
    }, [onAction]);

    return (
        <Box sx={{ p: 2 }}>
            <Paper sx={{ p: 3 }}>
                {/* 内容区域 */}
            </Paper>
        </Box>
    );
};

export default MyComponent;
查看完整示例请参考 resources/complete-examples.md

Related Skills

相关技能

  • error-tracking: Error tracking with Sentry (applies to frontend too)
  • backend-dev-guidelines: Backend API patterns that frontend consumes

Skill Status: Modular structure with progressive loading for optimal context management
  • error-tracking: 基于Sentry的错误追踪(同样适用于前端)
  • backend-dev-guidelines: 前端调用的后端API设计模式

技能状态: 模块化结构,支持渐进式加载,优化上下文管理