Next.js 项目结构指南
学习如何使用 App Router 组织 Next.js 项目,创建可扩展、易维护的代码结构。
在学会如何配置 NextDevKit 的一些开发工具后,我们接下来就要开始学习我们的代码和项目结构了。
在你学习具体的一些 NextDevKit 的代码细节之前,我们先来整体了解一下 NextDevKit 的代码结构。由于 NextDevKit 作为一个生产环境可用的 SaaS 模板,代码结构已经比较复杂了,所以我们这一节内容会从最简单的 Next.js 项目结构开始,一步一步的教你 NextDevKit 代码结构是如何组织和构建的。
理解 Next.js App Router
NextDevKit 为了降低复杂度和学习成本,没有使用 monorepo 的架构来组织代码,而是使用了 Next.js App Router,它是构建 React 应用程序的现代方法,具有增强功能:
- 基于文件的路由:通过向
app
目录添加文件来创建页面 - 服务端和客户端组件:通过策略性渲染提高性能
- 路由组:组织路由而不影响 URL 结构
- 并行路由:在同一布局中同时显示多个页面
步骤 1: 基础核心文件
要了解 NextDevKit 的代码结构,我们先从一个最简单的 Next.js 项目的文件结构开始。
除了一些配置文件,每个 Next.js 项目都从 2 个核心文件 开始:
layout.tsx
- 定义包含所有页面的根布局(可以定义头部、底部、导航等,会影响该目录下所有页面)page.tsx
- 创建用户访问时看到的首页
这两个文件构成了 Next.js 应用程序的基础。
App Router 核心概念:
layout.tsx
:为其子级共享的 UI。布局保持状态并保持交互性page.tsx
:路由的唯一 UI,使路由可公开访问loading.tsx
:页面内容加载时立即显示的加载 UIerror.tsx
:出现错误时显示的错误 UInot-found.tsx
:抛出notFound
函数时显示的 UI
步骤 2: 添加页面路由
要创建新页面和路由,只需创建包含 page.tsx 文件的文件夹:
/pricing
文件夹 +page.tsx
→ 创建定价页面/contact
文件夹 +page.tsx
→ 创建联系页面/blog
文件夹 +page.tsx
→ 创建博客页面
Next.js 使用文件系统路由自动将这些文件夹转换为可访问的页面。
动态路由:
[slug]
- 动态段(例如/blog/hello-world
)[...slug]
- 捕获所有段(例如/blog/2024/hello-world
)[[...slug]]
- 可选捕获所有段
动态路由对于渲染博客、文档、动态数据页等页面非常方便,你可以在 NextDevKit 代码中的博客页面中看到动态路由的示例。
步骤 3: 使用路由组和布局进行组织
随着功能的增多,在同一个目录下平铺所有的页面,会导致代码难以维护,所以需要使用路由组和嵌套布局进行更好的组织:
路由组:
(marketing)/
- 组织营销页面(定价、联系、博客)(app)/
- 组织应用页面(仪表板、设置)
国际化:
[locale]/
- 自动处理不同语言(中文、英文等)
重要提示: 圆括号 ()
组织代码但不影响 URL,它仅仅代表可以更好的组织你的代码目录和路由,不会影响你的真实 URL。 [locale]
代表国际化路由,该配置会影响你的 URL,例如你的页面路由会接受 /zh/pricing
和 /en/pricing
等。
步骤 4: 添加服务端功能
除了页面路由外,Next.js 也支持通过文件系统来定义 API 路由,我们需要 API 路由来实现后端、Auth 和第三方调用例如 Stripe 等功能。
添加**API 路由:
API 路由:
api/auth/
- 处理用户身份验证api/search/
- 提供搜索功能api/webhooks/
- 第三方服务的 Webhook 处理器
路由处理器:
route.ts
- 处理 GET、POST、PUT、DELETE 请求
除了 API 可以操作数据库外,我们也可以直接使用服务器组件的方式来获取数据库数据和渲染页面。这个我们以后再讲。
步骤 5: 组件架构
在了解 NextDevKit 的基本代码结构后,我们接下来要学习如何组织和复用前端 UI 组件。
UI 组件(设计系统):
components/ui/
- shadcn ui 原始基础组件(按钮、输入框、对话框)components/auth/
- 身份验证特定组件components/marketing/
- 营销页面组件components/dashboard/
- 应用特定组件
服务端 vs 客户端组件:
- 服务端组件:默认,在服务端渲染
- 客户端组件:使用 'use client',处理交互和状态
步骤 6: 生产就绪架构
对于企业级应用程序,除了上面的一些基础前端功能外,我们还需要实现这些核心模块:
业务逻辑模块:
actions/
- 数据变更的服务端操作mail/
- 邮件发送功能payment/
- 支付处理和订阅storage/
- 文件存储管理
数据层:
database/
- 数据库架构和数据管理
配置和内容:
config/
- 应用程序配置content/
- 博客和文档的 MDX 内容messages/
- 国际化文件
到这里的时候,我们已经拥有了一个和一个完整的生产环境的 NextDevKit 项目非常相似的组织结构。相信你对 NextDevKit 项目的目录结构已经有了一个基本的了解。如果你还有不懂的,可以基于 NextDevKit 当前的代码结构询问 AI 来获取帮助。下面简单介绍一些 App Router 最佳实践的一些最佳实践。
App Router 最佳实践
服务端 vs 客户端组件策略
使用服务端组件用于:
- 从数据库或 API 获取数据
- 访问后端服务
- 应该保留在服务端的大型依赖项
- SEO 敏感内容
使用客户端组件用于:
- 交互元素(onClick、onChange 等)
- 仅浏览器 API(localStorage、地理位置)
- 状态管理(useState、useReducer)
- 效果和生命周期方法(useEffect)
性能优化
路由级优化:
- 加载 UI:使用
loading.tsx
提供即时加载状态 - 流式传输:使用 React Suspense 进行渐进式页面渲染
- 并行数据获取:在布局和页面中并行获取数据
- 静态生成:在构建时预构建页面(当可能时)