01. 企业级目录结构设计

在企业级 Next.js 项目中,默认的 app/ 结构往往不够用。我们需要一种更可维护、可扩展的组织方式。

推荐采用 “Feature-Driven” (特性驱动)“Domain-Driven” (领域驱动) 的混合架构。

1. 顶层目录结构

建议把所有源码放在 src 目录下,与配置文件隔离开。

.
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
├── public/                 # 静态资源 (images, fonts, robots.txt)
└── src/
    ├── app/                # 路由层 (只放 page, layout, route)
    ├── components/         # 全局通用组件 (Button, Input)
    ├── features/           # ✨ 核心:按业务领域划分
    ├── lib/                # 第三方库的配置/封装 (db, auth, utils)
    ├── hooks/              # 全局 Hooks
    ├── types/              # 全局 TS 类型
    └── styles/             # 全局样式

2. Features 目录详解 (核心)

不要把所有组件都堆在 components 文件夹里!这是维护的噩梦。

应该按照业务功能来组织代码。比如做一个电商网站,可以这样划分:

src/features/
├── auth/                   # 用户认证模块
│   ├── components/         # 只有 auth 模块会用的组件
│   │   ├── LoginForm.tsx
│   │   └── UserAvatar.tsx
│   ├── actions.ts          # Server Actions (login, logout)
│   ├── hooks.ts            # useAuth
│   └── types.ts            # User 接口定义
├── product/                # 商品模块
│   ├── components/
│   │   ├── ProductCard.tsx
│   │   └── FilterBar.tsx
│   ├── services.ts         # 数据获取逻辑
│   └── utils.ts            # 价格格式化等
└── cart/                   # 购物车模块

原则

  • 高内聚:跟这个功能相关的一切(UI、逻辑、类型、API)都放在一起。
  • 低耦合auth 模块不应该直接引用 product 模块的内部组件。

3. App 目录的最佳实践

app 目录应该尽量。它只负责路由定义和页面组装,不包含复杂的业务逻辑。

src/app/
├── layout.tsx              # 全局布局
├── page.tsx                # 首页
├── (auth)/                 # Route Group (不影响 URL 路径)
│   ├── login/
│   │   └── page.tsx        # 仅仅是引用 @/features/auth/LoginForm
│   └── register/
│   │   └── page.tsx
└── dashboard/
    ├── layout.tsx
    └── page.tsx

示例:app/login/page.tsx

import { LoginForm } from '@/features/auth/components/LoginForm'
 
export default function LoginPage() {
  return (
    <div className="flex justify-center items-center h-screen">
       {/* 页面只负责布局,逻辑都在 Feature 组件里 */}
      <LoginForm />
    </div>
  )
}

4. Lib 与 Utils 的区别

  • src/lib/:存放第三方库的初始化代码单例

    • prisma.ts (数据库客户端实例)
    • redis.ts
    • stripe.ts
    • utils.ts (Tailwind 的 cn 合并函数通常放在这里)
  • src/utils/ (可选):存放纯逻辑的辅助函数。

    • formatDate.ts
    • currency.ts

5. 绝对路径导入 (Path Alias)

tsconfig.json 中配置别名,避免 ../../../../ 地狱。

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

使用:

import { Button } from '@/components/ui/button'     // ✅ 清晰
import { login } from '@/features/auth/actions'     // ✅ 清晰
// import { login } from '../../../features/auth'   // ❌ 难维护

6. 总结

  1. Feature First:按业务功能组织代码,而不是按文件类型。
  2. App 目录保持整洁app 目录只是路由的映射表,业务逻辑全部抽离到 src/features
  3. UI 组件库独立:通用的 UI 组件(如 Shadcn/ui)放在 src/components/ui,与业务组件分开。