Next.js 文件系统路由
Next.js App Router 用 app/ 目录结构声明 URL segment,并由 page.tsx 等特殊文件把目录结构转化为可访问路由。
[!info] related notes
- 所属 MOC:
- 前置概念: routing
- 并列概念:
- 易混淆概念:
- 关系笔记:
Next.js 文件系统路由
一句话定义
Next.js App Router 的文件系统路由,是把 app/ 下的目录结构直接作为路由声明:普通文件夹表达 URL segment,page.tsx 让该 segment 成为可访问页面。
app/
├── page.tsx → /
├── assessment/
│ ├── page.tsx → /assessment
│ └── history/
│ └── page.tsx → /assessment/history
└── dashboard/
└── page.tsx → /dashboard
Route Segment
URL:
/dashboard/settings/profile
可以拆成三个 route segment:
dashboard / settings / profile
对应目录:
app/
└── dashboard/
└── settings/
└── profile/
└── page.tsx
普通文件夹通常对应一个 URL segment。
page.tsx 才使 Route 对外可访问
只有目录并不会自动产生公开页面。
例如:
app/assessment/
├── components/
│ └── BMIResult.tsx
├── schema.ts
└── data.ts
这些文件可以和 route colocate,但不会自动得到:
/assessment/components
/assessment/schema
当存在:
app/assessment/page.tsx
才得到:
/assessment
所以 app/ 既是路由树,也是允许局部 colocate 组件、数据层、校验和测试的代码组织空间。
与传统路由配置的差异
传统客户端路由常写:
{
path: "/assessment/:id",
element: <AssessmentPage />
}
Next.js 则把声明放进目录结构:
app/assessment/[id]/page.tsx
因此不再同时维护一份独立 router.ts 与页面目录映射。
文件系统路由的价值
URL 架构一眼可见
打开 app/ 就可以粗略理解产品页面结构。
减少配置漂移
不容易出现“文件存在但忘记注册 route”或“route 配置和文件路径已经不同步”。
支持路由级 Colocation
某个业务页面的局部组件、数据访问、Schema、测试可以放在附近,而不会因此全部成为 URL。
不要把内部模块层级机械映射到 URL
文件系统路由很方便,但 URL 仍然首先服务用户的信息架构。
/user/account/profile/personal/information
如果只是因为内部代码模块有五层,就把 URL 也做成五层,通常是不好的设计。
应该分别思考:
用户如何理解资源层级?
↓
URL Information Architecture
代码内部如何拆模块?
↓
Module Architecture
两者可以相关,但不要求一一对应。
与 Server Components 的关系
App Router 中的 page.tsx 默认可以作为 Server Component,因此 route 定义与服务端数据获取可以自然结合:
export default async function Page() {
const assessments = await db.assessment.findMany()
return <AssessmentList assessments={assessments} />
}
这里“文件系统路由”和“Server Component”仍然是两个不同概念:前者解决 URL 到页面的映射,后者解决组件代码在哪一侧执行。
最短记忆方式
folder → route segment
page.tsx → public page
other files → 可以 colocate,不自动暴露 URL
继续涉及变量路径时看 Next.js 动态路由段;只想组织代码但不改变 URL 时看 Next.js Route Groups。