Skip to content
返回技术栈推荐

Next.js App Router 架构

Next.js 15 App Router 搭配 RSC、Server Actions、Drizzle ORM 和流式渲染 — 现代全栈架构。

全栈复杂

技术栈组成

FrameworkNext.js 15 (App Router)
DatabasePostgreSQL + Drizzle ORM
AuthAuth.js v5 (cookies)
ValidationZod + conform
StylingTailwindCSS 4
DeployVercel / Fly.io

为什么

App Router 的 React Server Components 减少 70% 客户端 JS。Server Actions 消除 mutation 的 API 路由。

Drizzle 比 Prisma 快 3 倍且语法类 SQL。流式 + Suspense 数据加载时即时显示内容。

何时使用

选择 App Router 用于需要 SEO + 交互的新 Next.js 应用、数据密集仪表板和想要更少 API 端点的团队。避免增量迁移大型 Pages Router 应用(混用令人困惑)。

如何做

1. 脚手架 — npx create-next-app@latest --app --typescript --tailwind 2. Drizzle 设置 — npm i drizzle-orm pg,drizzle-kit generate + migrate 3. Server Components — app/ 中默认,用 await db.query 获取数据 4. Server Actions — "use server" 函数做 mutation,之后 revalidatePath 5. 流式 — 慢组件包 <Suspense fallback={...}> 即时显示外壳 6. 认证 — Auth.js v5 用 cookies,RSC 中 auth(),客户端 useSession 7. 表单 — conform + Zod 渐进增强,无 JS 也能工作 8. 部署 — vercel deploy,或 fly.io 自托管带 Postgres

示例

// db/schema.ts — Drizzle ORM import { pgTable, serial, varchar, timestamp } from "drizzle-orm/pg-core"; export const users = pgTable("users", { id: serial("id").primaryKey(), email: varchar("email").notNull().unique(), name: varchar("name").notNull(), createdAt: timestamp("created_at").defaultNow(), }); // app/users/actions.ts — Server Action "use server"; import { db } from "@/db"; import { users } from "@/db/schema"; import { revalidatePath } from "next/cache"; import { z } from "zod"; const schema = z.object({ email: z.string().email(), name: z.string().min(1) }); export async function createUser(formData: FormData) { const data = schema.parse(Object.fromEntries(formData)); await db.insert(users).values(data); revalidatePath("/users"); // 即时缓存失效 } // app/users/page.tsx — RSC 带流式 import { db } from "@/db"; import { Suspense } from "react"; async function UserList() { const allUsers = await db.query.users.findMany(); return <ul>{allUsers.map((u) => <li key={u.id}>{u.name}</li>)}</ul>; } export default function Page() { return ( <main> <h1>用户</h1> <Suspense fallback={<p>加载中...</p>}> <UserList /> </Suspense> <form action={createUser}> <input name="email" type="email" required /> <input name="name" required /> <button type="submit">添加</button> </form> </main> ); }

常见问题

  • ⚠过度使用 'use client' — 标记整棵树为客户端,扼杀 RSC 优势,推到叶子组件
  • ⚠Server Action 未 revalidate — mutation 后数据过期,必须调 revalidatePath
  • ⚠客户端组件中 Drizzle 查询 — DB 泄露到浏览器,移到 RSC 或 API 路由
  • ⚠Suspense fallback 闪烁 — 用 loading.tsx 约定做路由级流式

最佳实践

  • ✓默认用 Server Components — 仅交互时加 'use client'(onClick、useState)
  • ✓所有 mutation 用 Server Actions — 无需 API 路由,端到端类型安全
  • ✓查询用 Drizzle RQB — 链式、类型安全、编译为最优 SQL
  • ✓并行数据获取 — RSC 中 Promise.all 避免瀑布加载

常见问题解答

什么是Next.js App Router 架构?适合做什么项目?

Next.js 15 App Router 搭配 RSC、Server Actions、Drizzle ORM 和流式渲染 — 现代全栈架构。 它通过分层组合提供端到端类型安全与开箱即用的部署体验,适合从 MVP 到生产 SaaS 的快速迭代。

如何用Next.js App Router 架构在 10 分钟内跑通一个 demo?

两步起步:① 脚手架 — npx create-next-app@latest --app --typescript --tailwind;② Drizzle 设置 — npm i drizzle-orm pg,drizzle-kit generate + migrate。先跑通本地 dev server,再接一个真实数据源验证端到端链路。

Next.js App Router 架构 最常见的坑是什么?怎么避免?

最高频的坑是:过度使用 'use client' — 标记整棵树为客户端,扼杀 RSC 优势,推到叶子组件。避免方法:在 PR 模板里加入对应 checklist,CI 中跑类型检查 + lint + 单测,三重把关再合并。

Next.js App Router 架构 的最佳实践有哪些?

Next.js App Router 架构 的最佳实践包括:默认用 Server Components — 仅交互时加 'use client'(onClick、useState);所有 mutation 用 Server Actions — 无需 API 路由,端到端类型安全;查询用 Drizzle RQB — 链式、类型安全、编译为最优 SQL。其中首条「默认用 Server Components — 仅交互时加 'use client'(onClick、useState)」应在项目初始化时就落地,避免后期返工。

什么情况下不该选Next.js App Router 架构?

三种情况另选他栈:① 团队对该栈核心框架零经验且工期紧张(学习曲线风险);② 项目是纯内容/营销站(选 Astro 更轻);③ 需要极高吞吐(>1 万 RPS)或强一致微服务(选 Go/Rust)。Next.js App Router 架构 的强项是中高复杂度全栈与 API,别在简单静态页上过度工程。