Skip to content
工程与部署
Next.js 概述:从 React 到全栈框架
Next.js 概述:从 React 到全栈框架 的概念、用法、示例和注意点
2024/01/116 分钟工程与部署
Next.js 概述
React 负责界面渲染与状态管理,但它不关心路由、数据获取方式、服务端运行环境以及最终产物的组织结构。一个典型的 Create React App 项目启动后,开发服务器返回几乎为空的 HTML 文件,所有内容都依赖浏览器下载并执行 JavaScript 才能呈现。这套流程在首屏速度、搜索引擎抓取和项目结构上都有明显短板。
Next.js 不是要替代 React,而是在 React 之上补全了构建完整 Web 应用所缺的基础设施。它把路由、服务端渲染、数据获取、API 端点、构建优化等能力统一到一个框架中。React 是组件引擎,Next.js 是围绕这个引擎设计的全栈运行时。
核心特性
Next.js 提供的不是单一功能,而是一组经过集成验证的能力组合:
- 文件系统路由:在
app或pages目录下创建文件即可对应 URL,无需手写路由配置。 - 多种渲染模式:支持服务端渲染(SSR)、静态站点生成(SSG)、增量静态再生(ISR)以及客户端渲染(CSR),可以在不同页面甚至不同组件中组合使用。
- API 路由与 Route Handler:在同一个项目中编写后端接口,避免跨域与工程碎片化。
- 自动代码分割与快速刷新:模块按需加载,开发状态下修改组件会自动反映在浏览器中,无需手动刷新。
- React Server Components:默认情况下组件在服务端运行,可以向客户端发送更小的 JavaScript 体积。
- Response Streaming、Server Actions:面向数据交互与表单处理的特性,在后续章节会涉及。
环境准备
Next.js 的运行与构建都基于 Node.js。官方要求的最低 Node.js 版本为 20.9,推荐安装最新的 LTS 版本,提供更长期的支持与稳定性。
检查本地环境:
bash
node -v
npm -v输出类似 v22.11.0 和 10.9.2 即表示环境就绪。如果未安装,可以从 nodejs.org 下载对应系统的安装包。Windows 用户可以使用 .msi 安装程序,完成后在命令提示符中运行上述命令验证。
创建项目
Next.js 提供了官方的项目脚手架工具 create-next-app:
bash
npx create-next-app@latest my-app执行过程中会询问配置选项:
- 项目名称
- 是否使用 TypeScript(默认是)
- 是否使用 ESLint(默认是)
- 是否使用 Tailwind CSS(默认是)
- 是否使用
src目录 - 是否启用 App Router(默认是)
- 是否自定义 import alias
如果希望跳过所有提示,直接采用默认设置(启用 TypeScript、Tailwind CSS、ESLint、App Router,使用 @/* 作为 import alias),可以加上 --yes 参数:
bash
npx create-next-app@latest my-app --yes完成后进入项目目录,可以看到生成的工程结构。
App Router:页面与布局
项目根目录下的 app 文件夹是 App Router 的工作区。其中两个文件最为基础:
app/page.tsx—— 对应网站的根路径/app/layout.tsx—— 作为所有页面的外层布局,必须包含<html>和<body>标签
一个最基础的 app/layout.tsx:
tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="zh-CN">
<body>{children}</body>
</html>
)
}它接收 children 属性,这个位置会被当前匹配的页面组件填充。
app/page.tsx 可以简单至极:
tsx
export default function Home() {
return <h1>Next.js 已运行</h1>
}运行 npm run dev,打开 http://localhost:3000,页面上会显示 "Next.js 已运行"。这就是基于文件系统路由的最简形态——不需要额外安装路由库,也不需要手写 <BrowserRouter>。
服务端组件与客户端组件
在 App Router 中,组件默认都是 Server Component。它们在服务端执行,可以安全地访问数据库、读取文件或调用后端 API,并且不会被包含在发往客户端的 JavaScript 包中。一个没有交互行为的页面可以不向浏览器发送任何组件级别的 JS。
当组件需要响应客户端事件(如点击、输入)或使用 React 的状态、副作用等 Hook 时,必须转为 Client Component。声明方式是在文件顶部添加指令:
tsx
'use client'这条指令告诉 Next.js 该组件及其依赖需要在客户端渲染和水合。只有需要的部分被打包进客户端,父级布局或兄弟组件仍保持服务端组件性质。
示例:交互式计数器
计数器需要用到 useState,所以它必须是一个客户端组件。为了避免整个页面都退化为客户端组件,通常把交互部分抽成独立的客户端模块。
新建 app/components/Counter.tsx:
tsx
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>当前计数:{count}</p>
<button onClick={() => setCount(count + 1)}>+1</button>
</div>
)
}然后在 app/page.tsx(仍为服务端组件)中引入:
tsx
import Counter from './components/Counter'
export default function Home() {
return (
<main>
<h1>交互式计数器</h1>
<Counter />
</main>
)
}这个结构的关键点在于:Home 组件在服务端渲染时生成包含标题和 <Counter /> 占位 HTML 的完整页面;Counter 组件内部的 count 状态和事件处理逻辑被打包进客户端代码,在水合阶段挂载到 DOM 上。最终既保证了首屏的完整 HTML,又使页面具有动态交互能力。
运行 npm run dev,浏览器中点击按钮,计数能正常增加,说明客户端状态已经激活。
开发服务器与热更新
Next.js 的开发环境内置了基于 Turbopack(或 Webpack)的实时编译引擎。启动方式:
bash
npm run dev默认监听 3000 端口。修改组件文件(例如修改 <h1> 文字内容)并保存后,浏览器会自动刷新对应部分,而不丢失当前页面的状态——对于 React 状态来说,状态通常会保留,除非组件树结构发生较大变化。如果有类型错误或语法异常,终端和浏览器都会给出明确的错误信息以及代码位置。
渲染模式对比
回顾纯 React(不使用框架)的默认行为:浏览器下载一个几乎为空的 HTML 文件,然后下载和执行 JavaScript,再由 React 在客户端构建真实的 DOM。这个过程在慢网环境下会出现较长的白屏时间,搜索引擎看到的可能只是空壳页面。
Next.js 的 SSR 行为则不同:请求到达服务器后,对应的页面组件会在 Node.js 环境中执行,产出完整的 HTML 字符串发送给客户端。浏览器可以立即渲染出可见内容,同时并行下载所需的 JavaScript。当 JS 加载完成并执行水合后,页面变为可交互状态。这种方式明显缩短了首次内容绘制(FCP)的时间,也让搜索引擎能够抓取到有意义的页面内容。
前面的计数器示例同时展现了两者协作:首屏 HTML 包含标题与初始计数(count 为 0),用户无需等待 JavaScript 下载即可看到内容;随后脚本完成水合,按钮的事件监听器生效,交互启动。
注意点
'use client'只影响当前文件:不要将整个应用都标记为客户端组件。把需要交互的子组件独立出来,其余布局和内容依然是服务端组件,保持 JS 体积最小。服务端组件不能使用浏览器 API:
window、document、useEffect或事件处理器只能存在于客户端组件中。服务端组件里写了这类代码,构建时就会报错。计数器的初始状态由服务端渲染:示例中
count初始值是 0,这个 0 既出现在服务端生成的 HTML 中,也传递给了客户端的初始状态。如果初始值依赖异步数据,需要进一步使用数据获取方案(本篇不展开)。开发服务器不适用于部署:
npm run dev仅供本地开发,构建产物需要用npm run build和npm start。构建会生成优化的静态资源与服务端代码,输出在.next目录。后续延伸:路由之间的状态保持和页面间参数传递将在下一篇《文件系统路由与导航》中讨论。
参考链接
- [1] https://learn.microsoft.com/zh-cn/visualstudio/javascript/tutorial-nodejs?view=visualstudio
- [2] https://developer.mozilla.org/zh-CN/docs/Learn_web_development/Extensions/Server-side/Express_Nodejs/development_environment
- [4] https://nextjs.org/docs/app/getting-started/installation
- [8] https://github.com/wangmiaozero/code/blob/master/Node.js%E5%AE%89%E8%A3%85%E5%8F%8A%E7%8E%AF%E5%A2%83%E9%85%8D%E7%BD%AE%E4%B9%8BWindows%E7%AF%87.md
- [9] https://cloud.tencent.com/document/product/1552/127381
- [10] https://cloud.tencent.com/developer/article/2637753
相关推荐
2025/02/25 · 6 分钟Nuxt.js 概述
Nuxt.js 概述 的概念、用法、示例和注意点
2024/01/17 · 5 分钟Next.js 数据获取:缓存、重新验证与请求Next.js 数据获取:缓存、重新验证与请求 的概念、用法、示例和注意点
2024/01/15 · 7 分钟Next.js 渲染策略:服务端组件与客户端组件Next.js 渲染策略:服务端组件与客户端组件 的概念、用法、示例和注意点
2024/01/13 · 7 分钟Next.js 基本概念:文件系统路由与导航Next.js 基本概念:文件系统路由与导航 的概念、用法、示例和注意点
