在 Next.js 项目中,文件夹结构和代码组织遵循一定的约定和最佳实践。以下是常见的规范及代码存放位置的总结:
1. 动态路由
-
App Router (推荐)
使用app
目录,动态路由通过文件夹名[param]
实现:app/ ├─ blog/ │ └─ [slug]/ │ └─ page.tsx # 动态路由页面(如 /blog/hello-world)
通过
params
对象获取参数:export default function Page({ params }: { params: { slug: string } }) { return <div>{params.slug}</div>; }
-
Pages Router (旧版)
使用pages
目录,文件名格式为[param].tsx
:pages/ └─ blog/ └─ [slug].tsx # 动态路由页面
2. 服务端执行的代码
- 服务端组件 (App Router)
默认情况下,app
目录下的组件是 服务端组件(除非标记'use client'
)。可以直连数据库或调用私有 API。 - API 路由
存放在app/api/
或pages/api/
下的文件会作为无服务器函数运行(Node.js 环境):app/ └─ api/ └─ users/ └─ route.ts # 对应 /api/users
- 数据获取方法 (Pages Router)
getStaticProps
、getServerSideProps
和getStaticPaths
在构建时或请求时由 Node.js 执行。
3. 页面代码
- App Router
页面文件必须命名为page.tsx
,并放置在对应路由的目录中:app/ ├─ about/page.tsx # /about └─ dashboard/page.tsx # /dashboard
- Pages Router
页面直接放在pages
目录下,文件名即路由:pages/ ├─ about.tsx # /about └─ index.tsx # /
4. 组件存放位置
- 全局可复用组件
存放在项目根目录的components
文件夹中,按功能或模块划分子目录:components/ ├─ ui/ # 基础 UI 组件(按钮、卡片等) ├─ layout/ # 布局组件 └─ features/ └─ auth/ # 认证相关组件
- 页面专属组件
可放在页面同级目录的components
子文件夹中:app/ └─ dashboard/ ├─ components/ │ └─ Chart.tsx └─ page.tsx
5. 类型定义 (TypeScript)
- 全局类型
放在types
或@types
目录中,通过tsconfig.json
配置路径:types/ ├─ user.d.ts # 用户相关类型 └─ api.d.ts # API 响应类型
- 局部类型
直接在组件文件中定义,或就近放在模块目录的types.ts
中:app/ └─ dashboard/ ├─ types.ts └─ page.tsx
6. 网络请求函数
- API 客户端
统一放在lib
或utils
目录中:lib/ └─ api/ ├─ client.ts # 初始化 Axios 实例 └─ user.ts # 用户相关 API 函数
- 服务端请求 (App Router)
直接在服务端组件中使用fetch
(Next.js 扩展了fetch
的缓存和重验证功能):async function getData() { const res = await fetch('https://api.example.com/data'); return res.json(); }
- 客户端请求
通过useEffect
或SWR
/TanStack Query
发起请求,或调用 API 路由代理。
7. 其他关键目录
目录/文件 | 用途 |
---|---|
public/ | 静态资源(图片、字体、robots.txt) |
styles/ | 全局 CSS 或 CSS 模块 |
middleware.ts | 中间件(身份验证、重定向等) |
.env.local | 环境变量(服务端和客户端) |
tests/ 或 __tests__/ | 单元测试/集成测试 |
总结示例
my-next-app/
├─ app/
│ ├─ [slug]/page.tsx # 动态路由页面
│ ├─ api/ # API 路由(服务端)
│ │ └─ users/route.ts
│ └─ dashboard/page.tsx # 页面代码
├─ components/
│ ├─ ui/Button.tsx # 可复用组件
│ └─ features/auth/LoginForm.tsx
├─ lib/
│ └─ api.ts # 网络请求函数
├─ types/
│ └─ user.d.ts # 全局类型
├─ public/ # 静态资源
└─ package.json
注意:如果使用 App Router,服务端组件默认不支持客户端交互(如 useState
),需要交互的组件需在顶部添加 'use client'
指令。