调试
调试方法论
遇到问题时,按以下顺序排查,效率最高:
- 浏览器控制台 → 看 JS 错误和警告
- Network 面板 → 看 API 请求是否正常、响应数据是否正确
- Nuxt DevTools → 查看组件树、路由、Payload
- 源码断点 → VS Code 调试器或浏览器 DevTools Sources 面板
- 日志输出 → 在关键位置添加
console.log
核心原则
先用最小成本定位问题范围(前端?后端?数据?路由?),再用具体工具深入排查。不要一上来就设断点,先看错误信息。
Nuxt DevTools
Nuxt 内置开发者工具,默认开启。在浏览器底部会看到 DevTools 图标,点击即可打开。
功能说明
| 功能 | 用途 | 典型场景 |
|---|---|---|
| 页面组件树 | 查看当前页面的组件嵌套关系 | 组件不显示时检查是否正确渲染 |
| 路由信息 | 查看当前路由、参数、中间件 | 路由跳转不正确时排查 |
| Payload 数据 | 查看 SSR 传递到客户端的数据 | useFetch 数据不对时检查 |
| 自动导入列表 | 查看所有自动导入的函数/组件 | is not defined 错误时检查 |
| Pinia 状态 | 查看/修改 Pinia Store | 状态不正确时排查 |
| 性能分析 | 页面加载时间、组件渲染时间 | 页面加载慢时定位瓶颈 |
| 时间线 | 页面生命周期事件的时间线 | 理解组件加载/渲染顺序 |
Nuxt DevTools vs Vue DevTools
Nuxt DevTools 专注 Nuxt 特性(SSR Payload、自动导入、路由规则等),Vue DevTools 专注 Vue 特性(组件 Props、响应式数据、事件等)。两者互补,建议同时安装。
启用/禁用
export default defineNuxtConfig({
devtools: { enabled: true }, // 启用(默认)
// devtools: { enabled: false }, // 禁用
})端到端调试案例:数据不显示
场景:页面中 useFetch('/api/users') 的数据不显示。
步骤 1:浏览器控制台
┌─────────────────────────────────┐
│ ❌ 有红色错误?→ 根据错误信息修复 │
│ ✅ 没有错误?→ 继续排查 │
└─────────────────────────────────┘
↓
步骤 2:Network 面板
┌─────────────────────────────────┐
│ 找到 /api/users 请求 │
│ ❌ 请求没发出?→ 检查 useFetch 调用│
│ ❌ 返回 4xx/5xx?→ 检查 API 代码 │
│ ❌ 返回空数据?→ 检查数据库查询 │
│ ✅ 数据正常?→ 继续排查 │
└─────────────────────────────────┘
↓
步骤 3:Nuxt DevTools → Payload
┌─────────────────────────────────┐
│ 查看 Payload 中的数据 │
│ ❌ Payload 中没有数据?→ SSR 未获取│
│ ❌ 数据在但页面不显示?→ 检查模板 │
│ ✅ 找到原因! │
└─────────────────────────────────┘为什么这个顺序有效?
从最外层(浏览器)到最内层(数据源),逐步缩小范围。大多数问题在前两步就能定位。
端到端调试案例:路由不跳转
场景:点击 <NuxtLink> 后页面没有变化。
步骤 1:浏览器控制台
┌─────────────────────────────────┐
│ ❌ 有 "Navigation aborted" 错误? │
│ → 中间件阻止了导航 │
│ ❌ 有 Hydration 错误? │
│ → 可能是路由配置问题 │
│ ✅ 没有错误?→ 继续排查 │
└─────────────────────────────────┘
↓
步骤 2:Nuxt DevTools → Routes
┌─────────────────────────────────┐
│ 查看目标路由是否存在 │
│ ❌ 路由不存在?→ 检查 pages/ 目录 │
│ ❌ 中间件标注了红色?→ 检查中间件 │
│ ✅ 路由存在?→ 继续排查 │
└─────────────────────────────────┘
↓
步骤 3:检查代码
┌─────────────────────────────────┐
│ 检查 NuxtLink 的 to 属性 │
│ 检查路由中间件是否 return false │
│ 检查页面文件是否在正确目录 │
└─────────────────────────────────┘VS Code 调试
客户端调试配置
在项目根目录创建 .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "Nuxt: Chrome",
"url": "http://localhost:3000",
"webRoot": "${workspaceFolder}"
}
]
}使用方法:
- 先在终端运行
npm run dev - 在 VS Code 中按 F5(或点击"运行和调试")
- 选择 "Nuxt: Chrome" 配置
- 浏览器自动打开,可以在 VS Code 中设断点
断点设在哪?
直接在 .vue 文件的 <script setup> 中点击行号旁边,设置断点。VS Code 会在代码执行到该行时暂停。
服务端调试配置
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Nuxt: Server",
"runtimeExecutable": "node",
"runtimeArgs": ["--inspect", ".output/server/index.mjs"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}使用方法:
- 先运行
nuxt build生成构建产物 - 在 VS Code 中按 F5,选择 "Nuxt: Server"
- 在
server/api/文件中设断点 - 请求 API 时断点会被触发
INFO
️ 注意:服务端调试需要先构建(nuxt build) 因为 VS Code 调试的是构建后的 .output/server/index.mjs,而不是源码。修改源码后需要重新构建
开发时服务端调试(推荐)
如果不想每次都构建,可以用 --inspect 模式开发:
NODE_OPTIONS='--inspect' nuxt dev然后在 Chrome 中:
- 打开
chrome://inspect - 在 "Remote Target" 中找到你的 Nuxt 项目
- 点击 "inspect" 打开 DevTools
- 在 Sources 面板中找到服务端文件,设置断点
--inspect 做了什么?
它让 Node.js 打开一个调试端口,Chrome DevTools 可以连接到这个端口来调试服务端代码。断点命中时代码暂停执行,你可以查看变量、调用栈等。
VS Code 中调试服务端(开发模式)
更好的方案是在 VS Code 中直接调试开发模式的服务端:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Nuxt: Dev Server",
"runtimeExecutable": "node",
"runtimeArgs": ["--inspect", "node_modules/.bin/nuxt", "dev"],
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}这样就不需要先构建了
直接在源码中设断点,修改代码后自动重载。
Vue DevTools
安装浏览器扩展 Vue.js DevTools:
- 组件检查:查看组件 Props、Data、Computed
- 事件监听:追踪组件间的事件传递
- 路由信息:查看当前路由和导航历史
- Pinia 状态:查看/修改 Store(与 Nuxt DevTools 功能重叠,但界面不同)
- 性能分析:组件渲染性能
日志调试
最简单也最实用的调试方式
在关键位置添加 console.log,Nuxt 会自动在终端显示服务端日志,在浏览器控制台显示客户端日志。
前后端日志的区别
// server/api/users.ts → 日志显示在终端
export default defineEventHandler((event) => {
console.log('[服务端] 请求路径:', event.path)
return { users: [] }
})
// app/pages/index.vue → 日志显示在浏览器控制台
// SSR 时也会在终端显示一次
<script setup>
console.log('[页面] 组件初始化')
onMounted(() => {
console.log('[页面] 仅客户端执行')
})
</script>日志出现在哪里?
| 代码位置 | SSR 时 | 客户端导航时 |
|---|---|---|
server/ 下的代码 | ✅ 终端 | ✅ 终端 |
app/ 下的 <script setup> 顶层 | ✅ 终端 + 浏览器 | ✅ 浏览器 |
app/ 下的 onMounted | ❌ 不执行 | ✅ 浏览器 |
.client.ts 插件 | ❌ 不执行 | ✅ 浏览器 |
结构化日志(生产环境推荐)
// server/utils/logger.ts
export const logger = {
info: (msg: string, data?: any) => {
console.log(JSON.stringify({ level: 'info', msg, data, time: new Date().toISOString() }))
},
error: (msg: string, data?: any) => {
console.error(JSON.stringify({ level: 'error', msg, data, time: new Date().toISOString() }))
},
}
// 使用
logger.info('用户请求', { path: event.path, userId: event.context.user?.id })生产环境建议使用 pino 等结构化日志库
而非 console.log。结构化日志可以控制日志级别、格式化输出、集成日志收集服务。
常见问题调试
Hydration 不匹配
什么是 Hydration 不匹配? SSR 时服务端生成 HTML,客户端加载后 Vue 尝试"接管"这些 HTML。如果客户端重新渲染的结果与服务端 HTML 不一致,就会报 Hydration mismatch 警告。
排查步骤:
- 检查是否使用了浏览器 API——
window、document、localStorage在 SSR 时不存在 - 检查是否有时间/随机相关逻辑——
Date.now()、Math.random()在 SSR 和 CSR 时结果不同 - 检查第三方库是否支持 SSR——有些库只在客户端运行
- 检查 HTML 中是否有条件渲染——如
v-if依赖的值在两端不同
解决方案:
<!-- 方案一:使用 ClientOnly 包裹 -->
<ClientOnly>
<BrowserOnlyComponent />
</ClientOnly>
<!-- 方案二:在 onMounted 中初始化 -->
<script setup>
const width = ref(0)
onMounted(() => {
width.value = window.innerWidth
})
</script>
<!-- 方案三:使用 NuxtTime 渲染时间 -->
<NuxtTime :datetime="new Date()" format="yyyy-MM-dd HH:mm" />如何快速定位哪个组件导致 Hydration 不匹配?
- 浏览器控制台的错误信息会指向具体的 DOM 节点
- 逐步注释组件,缩小范围
- 在 Nuxt DevTools 中查看组件树,找到问题组件
页面空白
按以下步骤排查:
- 打开浏览器控制台——查看是否有 JS 错误
- 检查
useFetch的error——数据获取失败但未处理错误 - 检查路由注册——在 Nuxt DevTools 中查看路由列表
- 检查
app.vue——是否缺少<NuxtPage /> - 检查页面文件——是否在
app/pages/目录下 - 检查终端——服务端渲染是否报错
API 请求失败
步骤 1:Network 面板 → 查看 HTTP 状态码
├── 404 → 路由不存在(检查 server/api/ 目录结构)
├── 400 → 请求参数错误(检查请求体/查询参数)
├── 401 → 未认证(检查 Cookie/Token)
├── 500 → 服务端错误(查看终端日志)
└── CORS 错误 → 配置跨域或检查 baseURL构建错误
# 清理缓存(解决大多数构建异常)
npx nuxt cleanup
# 重新生成类型(解决类型相关错误)
npx nuxt prepare
# 检查依赖和配置信息
npx nuxt info
# 重新安装依赖
rm -rf node_modules package-lock.json
npm installnuxt cleanup 做了什么?
删除 .nuxt/ 目录(缓存文件、自动生成代码),下次 nuxt dev 时会重新生成。很多奇怪的构建错误都是缓存导致的。
Source Map 配置
Source Map 让你在浏览器中看到源码而非编译后的代码,是调试的前提:
export default defineNuxtConfig({
sourcemap: {
server: true, // 服务端 Source Map
client: true, // 客户端 Source Map
},
})INFO
️ 生产环境注意: Source Map 会暴露源码 建议只在开发环境启用。可以用环境变量控制
sourcemap: {
server: process.env.NODE_ENV !== 'production',
client: process.env.NODE_ENV !== 'production',
},常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| DevTools 不显示 | 被浏览器广告拦截器屏蔽 | 禁用广告拦截器或添加白名单 |
chrome://inspect 找不到 Node 进程 | 端口不对或未启用 inspect | 确认 --inspect 参数和端口号 |
| 断点不命中 | Source Map 未正确生成 | 运行 nuxt cleanup 后重启 |
| 日志在终端不显示 | 代码只在客户端执行 | 检查是否在 .client.ts 文件中 |
| 服务端断点不触发 | 未先构建 | 先 nuxt build,或用开发模式调试配置 |
知识脉络
测试 → 你在这里:调试
│
├─→ 下一步:类型检查
│
├─→ 相关:错误处理(11-错误处理)
│
└─→ 相关:生命周期(理解日志出现的位置)