项目结构和组织
此页面概述了 Next.js 中的文件夹和文件约定,以及组织项目的技巧。
文件夹和文件约定
顶层文件夹
顶层文件夹用于组织应用程序的代码和静态资源。


顶层文件
顶层文件用于配置应用程序、管理依赖项、运行中间件、集成监控工具以及定义环境变量。
Next.js | |
next.config.js | Next.js 的配置文件 |
package.json | 项目依赖和脚本 |
instrumentation.ts | OpenTelemetry 和检测文件 |
middleware.ts | Next.js 请求中间件 |
.env | 环境变量 |
.env.local | 本地环境变量 |
.env.production | 生产环境环境变量 |
.env.development | 开发环境环境变量 |
.eslintrc.json | ESLint 的配置文件 |
.gitignore | 要忽略的 Git 文件和文件夹 |
next-env.d.ts | Next.js 的 TypeScript 声明文件 |
tsconfig.json | TypeScript 的配置文件 |
jsconfig.json | JavaScript 的配置文件 |
路由文件
layout | .js .jsx .tsx | 布局 |
page | .js .jsx .tsx | 页面 |
loading | .js .jsx .tsx | 加载 UI |
not-found | .js .jsx .tsx | 未找到 UI |
error | .js .jsx .tsx | 错误 UI |
global-error | .js .jsx .tsx | 全局错误 UI |
route | .js .ts | API 端点 |
template | .js .jsx .tsx | 重新渲染的布局 |
default | .js .jsx .tsx | 并行路由回退页面 |
嵌套路由
folder | 路由段 |
folder/folder | 嵌套路由段 |
动态路由
[folder] | 动态路由段 |
[...folder] | 捕获所有路由段 |
[[...folder]] | 可选的捕获所有路由段 |
路由组和私有文件夹
并行路由和拦截路由
@folder | 命名插槽 |
(.)folder | 拦截同一级别 |
(..)folder | 拦截上一级 |
(..)(..)folder | 拦截上两级 |
(...)folder | 从根目录拦截 |
元数据文件约定
应用图标
favicon | .ico | Favicon 文件 |
icon | .ico .jpg .jpeg .png .svg | 应用图标文件 |
icon | .js .ts .tsx | 生成的应用图标 |
apple-icon | .jpg .jpeg , .png | Apple 应用图标文件 |
apple-icon | .js .ts .tsx | 生成的 Apple 应用图标 |
Open Graph 和 Twitter 图片
opengraph-image | .jpg .jpeg .png .gif | Open Graph 图片文件 |
opengraph-image | .js .ts .tsx | 生成的 Open Graph 图片 |
twitter-image | .jpg .jpeg .png .gif | Twitter 图片文件 |
twitter-image | .js .ts .tsx | 生成的 Twitter 图片 |
SEO
组件层级结构
在路由段的特殊文件中定义的 React 组件以特定的层级结构渲染
layout.js
template.js
error.js
(React 错误边界)loading.js
(React Suspense 边界)not-found.js
(React 错误边界)page.js
或嵌套的layout.js


在嵌套路由中,一个段的组件将嵌套在其父段的组件内部。


组织你的项目
除了文件夹和文件约定之外,Next.js 对于你如何组织和共置项目文件是没有特定意见的。但它确实提供了一些功能来帮助你组织项目。
共置 (Colocation)
在 app
目录中,嵌套文件夹定义路由结构。每个文件夹代表一个路由段,该路由段映射到 URL 路径中的相应段。
但是,即使路由结构是通过文件夹定义的,但在将 page.js
或 route.js
文件添加到路由段之前,路由不会公开访问。


而且,即使路由是公开访问的,也只有 page.js
或 route.js
返回的内容被发送到客户端。


这意味着项目文件可以安全地共置在 app
目录中的路由段内,而不会意外地变成可路由的。


须知:
- 虽然你可以将项目文件共置在
app
中,但你不必这样做。如果你愿意,你可以将它们放在app
目录之外。
私有文件夹
私有文件夹可以通过在文件夹前加上下划线来创建:_folderName
这表示该文件夹是一个私有实现细节,不应被路由系统考虑,从而选择该文件夹及其所有子文件夹退出路由。


由于 app
目录中的文件默认可以安全地共置,因此共置不需要私有文件夹。但是,它们对于以下方面可能很有用:
- 将 UI 逻辑与路由逻辑分离。
- 在整个项目和 Next.js 生态系统中一致地组织内部文件。
- 在代码编辑器中排序和分组文件。
- 避免与未来 Next.js 文件约定发生潜在的命名冲突。
须知:
- 虽然不是框架约定,但你也可以考虑使用相同的下划线模式将私有文件夹之外的文件标记为“私有”。
- 你可以通过在文件夹名称前加上
%5F
(下划线的 URL 编码形式) 来创建以下划线开头的 URL 段:%5FfolderName
。- 如果你不使用私有文件夹,那么了解 Next.js 特殊文件约定以防止意外的命名冲突将很有帮助。
路由组
路由组可以通过将文件夹包裹在括号中来创建:(folderName)
这表示该文件夹仅用于组织目的,不应包含在路由的 URL 路径中。


路由组对于以下方面很有用:
- 将路由组织成组,例如按站点部分、意图或团队。
- 在同一路由段级别启用嵌套布局
src
目录
Next.js 支持将应用程序代码(包括 app
)存储在可选的 src
目录中。这会将应用程序代码与项目配置文件分开,后者主要位于项目的根目录中。


常用策略
以下部分列出了常用策略的非常高级别的概述。最简单的结论是选择一种适合你和你的团队的策略,并在整个项目中保持一致。
须知:在下面的示例中,我们使用
components
和lib
文件夹作为通用占位符,它们的命名没有特殊的框架意义,你的项目可能会使用其他文件夹,如ui
、utils
、hooks
、styles
等。
将项目文件存储在 app
之外
此策略将所有应用程序代码存储在你项目根目录的共享文件夹中,并将 app
目录仅用于路由目的。


将项目文件存储在 app
内的顶层文件夹中
此策略将所有应用程序代码存储在 app
目录的根目录中的共享文件夹中。


按功能或路由拆分项目文件
此策略将全局共享的应用程序代码存储在根 app
目录中,并将更具体的应用程序代码拆分到使用它们的路由段中。


这有帮助吗?