Next.js 介绍
By Leeting Yan
一、Next.js 是什么?
-
定位:基于 React 的全栈 Web 框架,用来构建从简单博客到复杂 SaaS 的各种 Web 应用。
-
作者&公司:由 Vercel 公司及社区维护,最初由 Guillermo Rauch 等人创建。(维基百科)
-
首次发布:2016 年 10 月 25 日开源。(维基百科)
-
语言与运行环境:
- 前端用 JavaScript / TypeScript + React
- 后端基于 Node.js / Edge Runtime
- 内部还使用 Rust 实现编译与打包工具(Turbopack 等)(维基百科)
-
协议:MIT 开源许可。(维基百科)
简单说:Next.js 在 React 基础上,帮你解决了路由、数据获取、渲染模式、SEO、静态导出、代码拆分、图片和字体优化、API 层等一整套问题,是一个“拿来就能上生产”的应用框架。
二、为什么要用 Next.js(核心特性总览)
1. 文件系统路由(File-based Routing)
-
按照文件夹结构自动生成路由:
- 在
app/或pages/目录下创建文件就等于创建页面。
- 在
-
支持:
- 动态路由:
[id].tsx - 嵌套路由:子目录结构
- 捕获所有路由:
[...slug].tsx
- 动态路由:
你不需要再手写路由表,结构一目了然。(Next.js)
2. 多种渲染模式:SSR / SSG / ISR / CSR
Next.js 最大的卖点之一就是灵活的渲染策略,可以按页面设置:
- SSR(Server-Side Rendering)服务器端渲染
每次请求时在服务端生成 HTML,适合实时数据+良好 SEO 的页面。 - SSG(Static Site Generation)静态生成
构建时把页面生成为静态 HTML,适合内容相对稳定的页面(博客、文档)。 - ISR(Incremental Static Regeneration)增量静态再生成
结合 SSG + 定时再生,页面第一次生成后,被访问一段时间后自动后台重建,做到 “静态性能 + 动态更新”。(strapi.io) - CSR(Client-Side Rendering)客户端渲染
通过纯 React 组件在浏览器侧渲染,适合高度交互的 SPA 部分。
这让你可以在同一个项目里,对不同页面选择不同策略:例如首页 SSG+ISR,后台管理页面用 SSR 或 CSR。
3. App Router 与 Pages Router
当前 Next.js 支持两套路由系统:(Next.js)
-
Pages Router(旧)
- 使用
pages/目录 - 一直沿用到 Next.js 12 时代的经典模式
- SSR / SSG / ISR API 为
getServerSideProps,getStaticProps等
- 使用
-
App Router(新)
-
使用
app/目录(推荐新项目使用) -
核心特点:
- React Server Components(服务器组件)
- 嵌套布局(layouts)与并行路由
- Streaming(流式渲染)
- 更精细的数据获取与缓存控制
- 更自然的全栈模式(Route Handlers,Server Actions 等)
-
你可以理解为:App Router 是为 React 18/19 新特性重新设计的一套 Next.js 架构。
4. React Server Components(RSC)
-
在 App Router 中,页面和布局默认是 Server Components:
- 在服务器运行,直接访问数据库或后端服务
- 渲染结果是 HTML 片段,减少发送到浏览器的 JS 体积
- 不参与客户端状态、事件处理(因此更轻更快)(Next.js)
-
当需要交互(比如按钮点击、表单输入、动画)时:
- 在组件文件顶部加上
"use client"声明,把该组件设为 Client Component,在浏览器执行。
- 在组件文件顶部加上
这种模式可以细粒度地控制“哪些逻辑必须在浏览器跑,哪些可以放在后端”,对性能和开发体验非常有利。
5. 全栈能力:API Routes / Route Handlers / Server Actions
Next.js 不是只负责前端页面,它本身就是一个全栈框架:
-
API Routes(Pages Router):在
pages/api/*.ts文件中定义 API 接口。 -
Route Handlers(App Router):
- 在
app/route.ts或[route]/route.ts里定义GET,POST等 HTTP 方法处理。(Next.js)
- 在
-
Server Actions:
- 使用
async function action() 'use server' { ... }形式,把后端操作嵌入组件逻辑中,简化“前端调用后端”的样板代码。(raftlabs.com)
- 使用
结果就是:你可以在一个 Next.js 项目里同时完成前端页面 + 后端接口 + 数据操作,非常适合中小团队和独立开发者。
6. 性能优化内建:图片、字体、代码拆分等
-
图片优化:
next/image组件自动:- 按设备尺寸和 DPR 生成合适尺寸
- 使用现代格式(如 WebP)
- 懒加载和占位图等。(Next.js)
-
字体优化:
next/font自动子集化、内联关键字体,减少 FOUT/FOIT。 -
自动代码拆分(Code Splitting):
- 按路由拆分 Bundle,避免一次性加载整个应用。(strapi.io)
-
Turbopack / Rust 编译管线:
- 新版本 Next.js 引入 Rust 写的打包器 Turbopack,相比 Webpack 有更快的冷启动和增量构建。(维基百科)
这些特性配合 SSR/SSG/ISR,可以显著提升 首屏速度、SEO 和 Lighthouse 指标。
7. 中间件与 Edge Runtime
-
Middleware:
- 在请求进入路由之前,在边缘节点执行:做重定向、AB 测试、国际化、权限验证等逻辑。(raftlabs.com)
-
Edge Runtime:
- 运行在边缘计算环境(比如 Vercel Edge Functions),延迟更低,适合用户地理分布广的应用。
三、App Router 核心概念拆解
假设你使用推荐的新模式,即 app/ 目录,这些是你会高频接触的概念。(Next.js)
1. 项目结构
典型结构示例:
app/
layout.tsx // 根布局
page.tsx // 根页面 (/)
blog/
layout.tsx // blog 区域布局
page.tsx // /blog
[slug]/
page.tsx // /blog/:slug
api/
route.ts // /api
public/
...静态资源
page.tsx:一个路由的页面组件layout.tsx:包裹子路由的通用布局(头部、导航、底部)loading.tsx:该路由的加载状态组件(配合 Suspense 与 Streaming)error.tsx:错误边界route.ts:定义路由处理(GET/POST 等)
2. 数据获取与渲染
在 App Router 里,数据获取官方推荐直接用 async Server Components:
// app/blog/[slug]/page.tsx
import { getPost } from '@/lib/posts';
export default async function PostPage({ params }) {
const post = await getPost(params.slug); // 这里直接访问数据库或 API
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.html }} />
</article>
);
}
- 该组件只在服务器执行,不会打包到浏览器。
- Next.js 会自动处理缓存与 streaming(视配置而定)。
你还可以通过:
- 缓存 & 再验证:使用
fetch的next: { revalidate: 秒数 }或revalidatePath等 API 做 ISR 风格的再生成。(Next.js) - Route Handlers:在
app/api/posts/route.ts定义GET/POST来服务数据。
3. Server / Client Components 的边界
-
默认:所有
page.tsx,layout.tsx都是 Server Components。 -
当你写组件需要:
useState,useEffect,useRef等 Hook- 访问
window,document,localStorage - 处理点击、输入、拖拽等交互事件
- 使用只支持浏览器的第三方 UI 组件库
时,就需要在文件顶部写:
"use client";
import { useState } from 'react';
export default function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(c => c + 1)}>
count: {count}
</button>
);
}
- 这个组件会打包到浏览器,在客户端执行。
- 可以把 Client Component 嵌在 Server Component 里,实现“壳在服务端、交互在客户端”。
四、开发体验与工程化
Next.js 在工程化上也做了很多封装,让你直接获得较好的 DX(Developer Experience)。(Next.js)
1. create-next-app 脚手架
用一个命令就能初始化:
npx create-next-app@latest my-app
# 或
pnpm create next-app my-app
支持可选项:
- TypeScript
- ESLint
- Tailwind CSS
- 实验特性等
2. 热更新与调试
-
Dev 模式下自动热更新(Fast Refresh),状态基本保持。
-
内置:
- 错误边界 UI
- 开发提示(比如使用了不推荐的 API)
3. TypeScript & ESLint & Prettier
- 官方模板默认把 TypeScript 配置好了。
- 默认 ESLint 配置集成 Next.js 规则。
- 和 Prettier / Husky / lint-staged 等前端工程化工具组合非常自然。
4. 与 Vercel 深度配合(但不限于 Vercel)
-
Next.js 由 Vercel 主导,自然在 Vercel 上零配置部署,非常丝滑。(维基百科)
-
同时也支持:
- 自建 Node.js 服务器
- 其他平台(如 Render、Netlify、Railway 等)通过适配器或者 Build Adapter API 部署。(维基百科)
五、典型适用场景
结合现在 2025 年的实际应用,可以概括几个 Next.js 非常适合的场景:(raftlabs.com)
-
内容型网站(博客、文档、营销页、品牌站)
- 静态生成 + ISR,性能和 SEO 都很好。
- 搭配 MDX / CMS(如 Headless CMS)非常常见。
-
SaaS / 后台管理系统 / 仪表盘
- 复杂前端交互 + 登录态 + 权限控制 + API 调用
- 可以用 SSR 提升“首屏可用速度”,App Router + Server Actions 简化后端逻辑。
-
电商网站
- 商品详情页用 SSG + ISR
- 购物车、结算等流程用 SSR/CSR
- Next.js 官方和很多案例都是电商站点。
-
多租户平台 / B2B 产品
- 通过中间件处理自定义域名、子域名的租户解析。
- 路由和数据层结合,很适合你之前做的多租户 SaaS 设计思路。
-
混合应用(部分是静态内容,部分是 Web App)
- 比如:首页 & 文档是静态的,管理后台是 SSR + SPA 体验。
六、Next.js 的优势与局限
优势
-
一体化解决方案
从路由、渲染到 API、图片、字体、部署路径都给出了一套默认方案,对团队很友好。 -
性能导向
SSR / SSG / ISR / 流式渲染 / RSC / Turbopack / 图片和字体优化等,把现代 Web 性能优化的“套路”全部内建。 -
全栈友好
少量后端逻辑就可以直接写在 Next.js 项目的 Route Handlers / Server Actions 里,省去独立后端服务的复杂度。 -
生态与社区成熟
大量教程、博客、模板、UI 组件库都对 Next.js 做了优化和封装,招聘也比较容易。(raftlabs.com)
局限 / 需要注意的点
-
概念较多,学习曲线有点陡
- Pages Router vs App Router
- SSR / SSG / ISR / CSR
- Server / Client Components
- Route Handlers / Server Actions / Middleware
对于初学者来说,一次性全吃完会有些混乱。
-
对平台绑定的担忧
- 虽然 Next.js 是开源的,但在 Vercel 上体验最好,有些高级特性(如 Edge Functions、图像优化)高度优化于 Vercel 平台,其他平台可能需要适配。(strapi.io)
-
对简单项目可能有点“重”
- 如果只是一个极简单的静态页面或纯前端小工具,用纯 React + Vite / Astro 之类也许更轻量。
七、如何快速上手一个 Next.js 项目(App Router)
给你一个最小但“现代”的示例流程:
- 创建项目
npx create-next-app@latest my-next-app
# 选:TypeScript + ESLint + Tailwind(可选)
# 路由默认就会用 app/ 目录(新项目推荐)
- 查看基础目录
my-next-app/
app/
layout.tsx // 全局布局,通常放导航、全局样式
page.tsx // 首页
public/
next.config.mjs
tsconfig.json
...
- 写一个简单的首页
app/page.tsx:
export default function Home() {
return (
<main className="p-8">
<h1 className="text-3xl font-bold">Hello Next.js</h1>
<p className="mt-4">这是一个基于 App Router 的示例首页。</p>
</main>
);
}
- 添加一个带数据获取的页面
app/posts/page.tsx(Server Component):
async function getPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts', {
// 例如 60 秒再验证一次,实现 ISR 风格
next: { revalidate: 60 },
});
return res.json();
}
export default async function PostsPage() {
const posts = await getPosts();
return (
<main className="p-8">
<h1 className="text-2xl font-bold mb-4">Posts</h1>
<ul className="space-y-2">
{posts.slice(0, 5).map((post: any) => (
<li key={post.id} className="border p-2 rounded">
<h2 className="font-semibold">{post.title}</h2>
<p className="text-sm text-gray-600">{post.body}</p>
</li>
))}
</ul>
</main>
);
}
- 添加一个 Client Component
app/components/Counter.tsx:
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return (
<button
onClick={() => setCount(c => c + 1)}
className="mt-4 px-4 py-2 border rounded"
>
点击次数:{count}
</button>
);
}
在 app/page.tsx 中使用:
import { Counter } from "./components/Counter";
export default function Home() {
return (
<main className="p-8">
<h1 className="text-3xl font-bold">Hello Next.js</h1>
<Counter />
</main>
);
}
这样你就已经实践了:
- App Router 目录结构
- Server Component 数据获取 + ISR
- Client Component 交互逻辑
总结
如果一句话概括:
Next.js = “带路由 + 渲染策略 + 性能优化 + API + 部署路径”的 React 全栈框架,App Router + Server Components 是它未来几年的核心方向。