Next.js项目架构 #

一、目录结构 #

1.1 推荐结构 #

text
project/
├── src/
│   ├── app/                    # App Router
│   │   ├── (auth)/             # 认证路由组
│   │   ├── (dashboard)/        # 仪表盘路由组
│   │   ├── api/                # API路由
│   │   ├── layout.tsx          # 根布局
│   │   └── page.tsx            # 首页
│   ├── components/             # 组件
│   │   ├── ui/                 # UI基础组件
│   │   ├── layout/             # 布局组件
│   │   └── features/           # 功能组件
│   ├── hooks/                  # 自定义Hooks
│   ├── lib/                    # 工具库
│   ├── types/                  # 类型定义
│   ├── styles/                 # 样式文件
│   └── config/                 # 配置文件
├── public/                     # 静态资源
├── tests/                      # 测试文件
├── .env.local                  # 环境变量
├── next.config.ts              # Next.js配置
├── tailwind.config.ts          # Tailwind配置
├── tsconfig.json               # TypeScript配置
└── package.json

1.2 组件目录 #

text
components/
├── ui/                         # 基础UI组件
│   ├── button.tsx
│   ├── card.tsx
│   ├── input.tsx
│   └── index.ts
├── layout/                     # 布局组件
│   ├── header.tsx
│   ├── footer.tsx
│   ├── sidebar.tsx
│   └── navigation.tsx
└── features/                   # 功能组件
    ├── auth/
    │   ├── login-form.tsx
    │   └── register-form.tsx
    ├── blog/
    │   ├── post-card.tsx
    │   └── post-list.tsx
    └── user/
        ├── avatar.tsx
        └── profile.tsx

1.3 lib目录 #

text
lib/
├── api.ts                      # API请求封装
├── auth.ts                     # 认证相关
├── db.ts                       # 数据库连接
├── utils.ts                    # 工具函数
├── constants.ts                # 常量定义
└── validations.ts              # 表单验证

二、代码组织 #

2.1 组件划分 #

UI组件

tsx
interface ButtonProps {
    variant?: 'primary' | 'secondary'
    size?: 'sm' | 'md' | 'lg'
    children: React.ReactNode
}

export function Button({ variant = 'primary', size = 'md', children }: ButtonProps) {
    return (
        <button className={cn(baseStyles, variants[variant], sizes[size])}>
            {children}
        </button>
    )
}

功能组件

tsx
interface LoginFormProps {
    onSuccess?: () => void
}

export function LoginForm({ onSuccess }: LoginFormProps) {
    const [state, formAction] = useActionState(login, null)
    
    return (
        <form action={formAction}>
            <Input name="email" type="email" />
            <Input name="password" type="password" />
            <Button type="submit">登录</Button>
        </form>
    )
}

2.2 Hooks组织 #

tsx
function useAuth() {
    const [user, setUser] = useState<User | null>(null)
    const [loading, setLoading] = useState(true)
    
    useEffect(() => {
        checkAuth().then(setUser).finally(() => setLoading(false))
    }, [])
    
    return { user, loading }
}

2.3 API封装 #

tsx
const API_BASE = process.env.NEXT_PUBLIC_API_URL

export async function api<T>(
    endpoint: string,
    options: RequestInit = {}
): Promise<T> {
    const res = await fetch(`${API_BASE}${endpoint}`, {
        ...options,
        headers: {
            'Content-Type': 'application/json',
            ...options.headers,
        },
    })
    
    if (!res.ok) {
        throw new Error(`API Error: ${res.status}`)
    }
    
    return res.json()
}

export const userApi = {
    get: (id: string) => api<User>(`/users/${id}`),
    list: () => api<User[]>('/users'),
    create: (data: UserData) => api<User>('/users', {
        method: 'POST',
        body: JSON.stringify(data),
    }),
}

三、模块划分 #

3.1 功能模块 #

text
features/
├── auth/
│   ├── components/
│   │   ├── login-form.tsx
│   │   └── register-form.tsx
│   ├── hooks/
│   │   └── use-auth.ts
│   ├── actions.ts
│   └── index.ts
├── blog/
│   ├── components/
│   ├── hooks/
│   ├── actions.ts
│   └── index.ts
└── user/
    ├── components/
    ├── hooks/
    ├── actions.ts
    └── index.ts

3.2 统一导出 #

tsx
export { LoginForm } from './components/login-form'
export { RegisterForm } from './components/register-form'
export { useAuth } from './hooks/use-auth'
export { login, register } from './actions'

3.3 使用模块 #

tsx
import { LoginForm, useAuth } from '@/features/auth'

export default function LoginPage() {
    const { user } = useAuth()
    
    if (user) {
        redirect('/dashboard')
    }
    
    return <LoginForm />
}

四、配置管理 #

4.1 环境配置 #

typescript
const config = {
    api: {
        baseUrl: process.env.NEXT_PUBLIC_API_URL,
        timeout: 30000,
    },
    auth: {
        cookieName: 'auth-token',
        cookieMaxAge: 60 * 60 * 24 * 7,
    },
    features: {
        enableAnalytics: process.env.NODE_ENV === 'production',
    },
}

export default config

4.2 常量定义 #

typescript
export const ROUTES = {
    HOME: '/',
    LOGIN: '/login',
    DASHBOARD: '/dashboard',
    PROFILE: '/profile',
} as const

export const API_ENDPOINTS = {
    USERS: '/users',
    POSTS: '/posts',
    AUTH: '/auth',
} as const

五、类型定义 #

5.1 类型组织 #

text
types/
├── api.ts                      # API类型
├── models.ts                   # 数据模型
├── components.ts               # 组件Props
└── index.ts                    # 统一导出

5.2 类型定义 #

typescript
interface User {
    id: string
    name: string
    email: string
    avatar?: string
    createdAt: Date
}

interface Post {
    id: string
    title: string
    content: string
    author: User
    tags: string[]
    createdAt: Date
}

interface ApiResponse<T> {
    data: T
    message: string
    success: boolean
}

六、最佳实践 #

6.1 文件命名 #

  • 组件:kebab-case.tsx
  • Hook:use-xxx.ts
  • 工具:xxx.ts
  • 类型:xxx.ts

6.2 导入顺序 #

tsx
import { useState } from 'react'
import { useRouter } from 'next/navigation'
import { Button } from '@/components/ui/button'
import { useAuth } from '@/hooks/use-auth'
import { login } from './actions'

6.3 组件结构 #

tsx
interface Props {
    title: string
}

export function Component({ title }: Props) {
    const [state, setState] = useState()
    
    useEffect(() => {}, [])
    
    const handleClick = () => {}
    
    return <div>{title}</div>
}

七、总结 #

项目架构要点:

要点 说明
目录结构 清晰的分层
组件划分 UI/功能分离
模块化 功能聚合
配置管理 环境区分
类型定义 类型安全

下一步,让我们学习TypeScript集成!

最后更新:2026-03-28