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
创建组件时可遵循以下检查项:
  • 使用 TypeScript 的
    React.FC<Props>
    模式
  • 如果是重型组件,使用懒加载:
    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/{功能名称}/
    目录
  • 创建子目录:
    api/
    components/
    hooks/
    helpers/
    types/
  • 创建 API 服务文件:
    api/{功能名称}Api.ts
  • types/
    目录中配置 TypeScript 类型定义
  • routes/{功能名称}/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/{功能名}/api/{功能名}Api.ts
    文件
  • 使用
    apiClient
    axios 实例
  • 按功能集中维护接口方法
  • 路由格式:
    /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、自定义导航栏)
功能目录子结构:
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
    prop 定义样式
  • 使用
    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
表单/鉴权/DataGrid开发common-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       # 自定义Hooks
        useSuspenseMyFeature.ts  # Suspense相关Hooks
      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模式规范

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