Next.js 项目结构
这篇只讲一件事:一个现代 Next.js 项目,目录到底应该怎么理解。
很多人第一次看 Next,会把它当成“React 项目多了一层文件路由”。这个理解不算错,但不够。到了 App Router 这一 代,目录不只是映射 URL,还承担了:
- 路由定义
- 布局组织
- 加载状态
- 错误边界
- 服务端与客户端边界
- 路由处理器
- 元信息文件
所以 Next 的目录结构,本质上已经是运行时结构的一部分。
先看最常见的一套骨架
app/
├── layout.tsx
├── page.tsx
├── loading.tsx
├── error.tsx
├── not-found.tsx
├── blog/
│ ├── page.tsx
│ └── [slug]/
│ └── page.tsx
├── api/
│ └── posts/
│ └── route.ts
└── dashboard/
├── layout.tsx
├── page.tsx
└── settings/
└── page.tsx
components/
lib/
public/
next.config.ts
这套结构里,最重要的不是“文件放在哪”,而是“哪些文件会被 Next 当成特殊入口”。
app/ 是现在的主线
app/ 目录是 App Router 的核心。只要在这里放文件,Next 就会按文件系统约定把它识别成页面结构的一部分。
page.tsx
对应一个可访问页面。
export default function HomePage() {
return <h1>Home</h1>;
}
layout.tsx
定义共享布局。它会包住当前目录以及子目录下的页面。
export default function DashboardLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<section>
<aside>Sidebar</aside>
<main>{children}</main>
</section>
);
}
loading.tsx
定义该路由 段的加载占位。常见于流式渲染和异步数据获取场景。
error.tsx
定义该路由段的错误边界。
not-found.tsx
定义 404 场景的展示结果。
route.ts
定义 Route Handler,也就是基于文件系统的服务端接口。
import { NextResponse } from 'next/server';
export async function GET() {
return NextResponse.json({ ok: true });
}