# 开发调试体系
> 高效的调试能力决定了开发速度的下限。本章覆盖 Next.js 16 开发中的四大调试场景:React DevTools 组件调试、Next.js 服务端断点调试、Turbopack 开发体验优化、以及 VS Code / Cursor 的高效配置。掌握这些工具,你的 debug 效率可以提升 3-5 倍。
## 1. React DevTools
### 1.1 安装与基础使用
React DevTools 是调试 React 组件的必备工具。安装 Chrome/Firefox 扩展后,开发者工具会多出两个 Tab:
- **Components**:查看组件树、Props、State、Hooks
- **Profiler**:分析组件渲染性能
```
Components Tab 功能:
├── 🔍 搜索组件(按名称/Props 过滤)
├── 👁️ 查看 Props / State / Hooks 实时值
├── ✏️ 实时编辑 Props 和 State
├── 🎯 点击组件 → 高亮 DOM 元素
└── 📍 点击 DOM 元素 → 定位到组件
```
### 1.2 Server Components 调试
在 Next.js 16 中,Server Components **不会出现在 React DevTools 中**——因为它们运行在服务端,不发送 JS 到浏览器。
如何区分 Server 和 Client Components:
```tsx
// ✅ 会出现在 DevTools 中(Client Component)
'use client'
export function ChatInput() { ... }
// ❌ 不会出现在 DevTools 中(Server Component)
export default async function ChatPage() { ... }
```
**调试 Server Components 的方法**:
1. **console.log** — 输出会出现在终端(不是浏览器控制台)
2. **Next.js 服务端断点**(下一节详解)
3. **React Server Components Payload 检查** — 浏览器 Network Tab 中搜索 `RSC` 或 `__next` 请求
### 1.3 Profiler:性能分析
Profiler 帮助你找出不必要的重渲染:
1. 打开 Profiler Tab → 点击录制按钮
2. 在页面上执行操作(输入、点击、导航)
3. 停止录制 → 查看 Flamegraph
```
关注指标:
├── Render Duration — 组件渲染耗时
├── Why did this render? — 触发渲染的原因
│ ├── Props changed
│ ├── State changed
│ ├── Parent rendered
│ └── Context changed
└── Highlight updates — 实时高亮重渲染的组件
```
::: tip 开启 "Highlight updates when components render"
Settings → General → 勾选此选项。每次组件重渲染时会闪烁高亮,能快速发现不必要的渲染。
:::
## 2. Next.js 服务端调试
### 2.1 Node.js Inspector 断点调试
Next.js 支持 Node.js Inspector 协议,可以在 VS Code 中打断点调试服务端代码:
```json
// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug server-side",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/next",
"runtimeArgs": ["dev"],
"skipFiles": ["<node_internals>/**"],
"env": {
"NODE_OPTIONS": "--inspect"
}
},
{
"name": "Next.js: debug client-side",
"type": "chrome",
"request": "launch",
"url": "http://localhost:3000"
},
{
"name": "Next.js: debug full stack",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/next",
"runtimeArgs": ["dev"],
"serverReadyAction": {
"pattern": "- Local:.+(https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}
```
使用方法:
1. 在 Server Component / Route Handler / Server Action 代码中设置断点
2. 按 F5 启动 "Next.js: debug full stack"
3. 访问对应页面 → 断点命中 → 查看变量、调用栈
### 2.2 console 调试技巧
```tsx
// Server Component 中的 console.log → 输出到终端
export default async function ChatPage() {
const chats = await db.query.chats.findMany()
console.log('[ChatPage]', { count: chats.length }) // 终端
return <ChatList chats={chats} />
}
// Client Component 中的 console.log → 输出到浏览器
'use client'
export function ChatInput() {
console.log('[ChatInput] rendered') // 浏览器控制台
return <input />
}
```
**推荐**:用结构化日志代替散装 `console.log`:
```typescript
// lib/logger.ts
export function log(context: string, data?: Record<string, unknown>) {
if (process.env.NODE_ENV === 'development') {
console.log(`[${new Date().toISOString()}] [${context}]`, data ?? '')
}
}
// 使用
log('ChatPage', { userId: session.user.id, chatCount: chats.length })
// [2025-04-12T12:00:00.000Z] [ChatPage] { userId: 'xxx', chatCount: 42 }
```
### 2.3 错误追踪
```tsx
// app/error.tsx — 开发环境显示详细错误栈
'use client'
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string }
reset: () => void
}) {
return (
<html>
<body>
<h2>Something went wrong!</h2>
{process.env.NODE_ENV === 'development' && (
<pre className="overflow-auto rounded bg-red-50 p-4 text-sm">
{error.stack}
</pre>
)}
<button onClick={reset}>Try again</button>
</body>
</html>
)
}
```
## 3. Turbopack 开发体验
### 3.1 Turbopack 优势
Next.js 16 默认使用 Turbopack 作为开发构建器:
| 场景 | Webpack | Turbopack |
|------|---------|-----------|
| 冷启动 | 5-15s | 1-3s |
| 文件修改 HMR | 200-500ms | 10-50ms |
| 大页面首次编译 | 2-5s | 0.5-1s |
| 内存占用 | 500MB-2GB | 200-500MB |
### 3.2 HMR(Hot Module Replacement)
Turbopack 的 HMR 是**增量**的——只重新编译修改的模块及其直接依赖,不做全量构建:
```
修改 components/chat/chat-input.tsx
├── Turbopack 检测到变更
├── 只重新编译 chat-input.tsx(~10ms)
├── 通过 WebSocket 推送更新到浏览器
└── React Fast Refresh 替换组件(保持状态)
```
**Fast Refresh 保持状态的条件**:
- 文件只导出 React 组件
- 组件使用命名导出或默认导出
- 没有导出非组件的值(如常量、工具函数)
```tsx
// ✅ Fast Refresh 有效 — 编辑后保持 state
export default function Counter() {
const [count, setCount] = useState(0)
return <button onClick={() => setCount(c => c + 1)}>{count}</button>
}
// ❌ Fast Refresh 失效 — 编辑后状态重置(因为混合导出)
export const API_URL = '/api'
export default function Counter() { ... }
```
### 3.3 常见问题排查
```bash
# 1. Turbopack 编译错误不清晰 → 查看完整日志
NEXT_DEBUG_TURBOPACK=1 pnpm dev
# 2. HMR 不生效 → 检查文件是否混合导出
# 把非组件导出移到单独文件
# 3. 某些库不兼容 Turbopack → 临时回退 Webpack
pnpm dev --no-turbopack
```
## 4. VS Code / Cursor 高效配置
### 4.1 核心快捷键
| 快捷键 | 功能 | 场景 |
|--------|------|------|
| `Cmd+Shift+P` | 命令面板 | 一切操作的入口 |
| `Cmd+P` | 快速打开文件 | 输入文件名跳转 |
| `Cmd+Shift+F` | 全局搜索 | 搜索代码/文本 |
| `F12` | 跳转到定义 | 查看函数/组件源码 |
| `Shift+F12` | 查找所有引用 | 看谁调用了这个函数 |
| `F2` | 重命名符号 | 安全重命名变量/函数 |
| `Cmd+.` | Quick Fix | ESLint 修复、导入补全 |
| `Cmd+Shift+O` | 文件内符号搜索 | 跳转到函数/类/接口 |
### 4.2 Next.js 专属配置
```json
// .vscode/settings.json
{
// TypeScript
"typescript.tsdk": "node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
// 格式化
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit",
"source.organizeImports": "explicit"
},
// Tailwind CSS 智能提示
"tailwindCSS.experimental.classRegex": [
["cva\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["cn\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"],
["clsx\\(([^)]*)\\)", "[\"'`]([^\"'`]*).*?[\"'`]"]
],
// 文件关联
"files.associations": {
"*.css": "tailwindcss"
},
// Emmet 支持 JSX
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"typescript": "typescriptreact"
},
// 隐藏干扰文件
"files.exclude": {
"**/.next": true,
"**/node_modules": true
}
}
```
### 4.3 代码片段(Snippets)
```json
// .vscode/nextjs.code-snippets
{
"Next.js Server Component": {
"prefix": "nsc",
"body": [
"export default async function ${1:Component}() {",
" return (",
" <div>",
" $0",
" </div>",
" )",
"}"
]
},
"Next.js Client Component": {
"prefix": "ncc",
"body": [
"'use client'",
"",
"export default function ${1:Component}() {",
" return (",
" <div>",
" $0",
" </div>",
" )",
"}"
]
},
"Server Action": {
"prefix": "nsa",
"body": [
"'use server'",
"",
"import { z } from 'zod'",
"import { revalidatePath } from 'next/cache'",
"",
"const ${1:Schema} = z.object({",
" $2",
"})",
"",
"export async function ${3:action}(formData: FormData) {",
" const parsed = ${1:Schema}.safeParse(Object.fromEntries(formData))",
" if (!parsed.success) return { error: parsed.error.flatten() }",
"",
" $0",
"",
" revalidatePath('/')",
"}"
]
},
"Route Handler": {
"prefix": "nrh",
"body": [
"import { NextRequest, NextResponse } from 'next/server'",
"",
"export async function ${1|GET,POST,PUT,DELETE|}(request: NextRequest) {",
" $0",
" return NextResponse.json({ success: true })",
"}"
]
}
}
```
### 4.4 Cursor / AI 编辑器配置
如果你使用 Cursor,可以创建 `.cursorrules` 配置 AI 行为:
```
# .cursorrules
You are a Next.js 16 expert. Follow these rules:
- Use App Router (not Pages Router)
- Default to Server Components; only use 'use client' when needed
- Use TypeScript strict mode, never use 'as any'
- Use Zod for all external input validation
- Use Server Actions for data mutations
- Use shadcn/ui for UI components
- Use Tailwind CSS v4 for styling
- Follow the project directory structure: app/, components/, lib/, hooks/, types/
```
## 5. 开发工作流总结
### 5.1 日常开发循环
```
1. pnpm dev → Turbopack 启动(~1s)
2. 编辑 Server Component → console.log 看终端
3. 编辑 Client Component → Fast Refresh 保持状态
4. 遇到 Bug → F5 启动断点调试
5. 性能问题 → React Profiler 分析
6. 提交前 → pnpm lint && pnpm type-check
```
### 5.2 常用 package.json scripts
```json
{
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"type-check": "tsc --noEmit",
"format": "prettier --write .",
"format:check": "prettier --check .",
"db:push": "drizzle-kit push",
"db:studio": "drizzle-kit studio"
}
}
```
## 本章小结
- **React DevTools**:Components Tab 查看组件树/Props/State,Profiler 分析渲染性能
- **Server Component 调试**:console.log 输出到终端,VS Code 断点调试服务端代码
- **Turbopack**:10ms 级 HMR,保持 Fast Refresh 有效的关键是不混合导出组件和非组件
- **VS Code 配置**:launch.json 断点调试 + 代码片段提效 + Tailwind 智能提示
- **开发工作流**:dev → edit → hot reload → debug → lint → commit
至此,第一篇「基础认知与工程初始化」全部完成。下一篇,我们将深入路由系统——App Router 的核心。