Skip to content

调试

调试方法论

遇到问题时,按以下顺序排查,效率最高:

  1. 浏览器控制台 → 看 JS 错误和警告
  2. Network 面板 → 看 API 请求是否正常、响应数据是否正确
  3. Nuxt DevTools → 查看组件树、路由、Payload
  4. 源码断点 → VS Code 调试器或浏览器 DevTools Sources 面板
  5. 日志输出 → 在关键位置添加 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、响应式数据、事件等)。两者互补,建议同时安装。

启用/禁用

ts
export default defineNuxtConfig({
  devtools: { enabled: true },   // 启用(默认)
  // devtools: { enabled: false },  // 禁用
})

端到端调试案例:数据不显示

场景:页面中 useFetch('/api/users') 的数据不显示。

text
步骤 1:浏览器控制台
┌─────────────────────────────────┐
│ ❌ 有红色错误?→ 根据错误信息修复  │
│ ✅ 没有错误?→ 继续排查           │
└─────────────────────────────────┘

步骤 2:Network 面板
┌─────────────────────────────────┐
│ 找到 /api/users 请求             │
│ ❌ 请求没发出?→ 检查 useFetch 调用│
│ ❌ 返回 4xx/5xx?→ 检查 API 代码  │
│ ❌ 返回空数据?→ 检查数据库查询   │
│ ✅ 数据正常?→ 继续排查           │
└─────────────────────────────────┘

步骤 3:Nuxt DevTools → Payload
┌─────────────────────────────────┐
│ 查看 Payload 中的数据            │
│ ❌ Payload 中没有数据?→ SSR 未获取│
│ ❌ 数据在但页面不显示?→ 检查模板  │
│ ✅ 找到原因!                    │
└─────────────────────────────────┘

为什么这个顺序有效?

从最外层(浏览器)到最内层(数据源),逐步缩小范围。大多数问题在前两步就能定位。

端到端调试案例:路由不跳转

场景:点击 <NuxtLink> 后页面没有变化。

text
步骤 1:浏览器控制台
┌─────────────────────────────────┐
│ ❌ 有 "Navigation aborted" 错误? │
│    → 中间件阻止了导航             │
│ ❌ 有 Hydration 错误?           │
│    → 可能是路由配置问题           │
│ ✅ 没有错误?→ 继续排查           │
└─────────────────────────────────┘

步骤 2:Nuxt DevTools → Routes
┌─────────────────────────────────┐
│ 查看目标路由是否存在              │
│ ❌ 路由不存在?→ 检查 pages/ 目录 │
│ ❌ 中间件标注了红色?→ 检查中间件  │
│ ✅ 路由存在?→ 继续排查           │
└─────────────────────────────────┘

步骤 3:检查代码
┌─────────────────────────────────┐
│ 检查 NuxtLink 的 to 属性         │
│ 检查路由中间件是否 return false   │
│ 检查页面文件是否在正确目录        │
└─────────────────────────────────┘

VS Code 调试

客户端调试配置

在项目根目录创建 .vscode/launch.json

json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Nuxt: Chrome",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}"
    }
  ]
}

使用方法:

  1. 先在终端运行 npm run dev
  2. 在 VS Code 中按 F5(或点击"运行和调试")
  3. 选择 "Nuxt: Chrome" 配置
  4. 浏览器自动打开,可以在 VS Code 中设断点

断点设在哪?

直接在 .vue 文件的 <script setup> 中点击行号旁边,设置断点。VS Code 会在代码执行到该行时暂停。

服务端调试配置

json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Nuxt: Server",
      "runtimeExecutable": "node",
      "runtimeArgs": ["--inspect", ".output/server/index.mjs"],
      "cwd": "${workspaceFolder}",
      "console": "integratedTerminal"
    }
  ]
}

使用方法:

  1. 先运行 nuxt build 生成构建产物
  2. 在 VS Code 中按 F5,选择 "Nuxt: Server"
  3. server/api/ 文件中设断点
  4. 请求 API 时断点会被触发

INFO

注意:服务端调试需要先构建(nuxt build) 因为 VS Code 调试的是构建后的 .output/server/index.mjs,而不是源码。修改源码后需要重新构建

开发时服务端调试(推荐)

如果不想每次都构建,可以用 --inspect 模式开发:

bash
NODE_OPTIONS='--inspect' nuxt dev

然后在 Chrome 中:

  1. 打开 chrome://inspect
  2. 在 "Remote Target" 中找到你的 Nuxt 项目
  3. 点击 "inspect" 打开 DevTools
  4. 在 Sources 面板中找到服务端文件,设置断点

--inspect 做了什么?

它让 Node.js 打开一个调试端口,Chrome DevTools 可以连接到这个端口来调试服务端代码。断点命中时代码暂停执行,你可以查看变量、调用栈等。

VS Code 中调试服务端(开发模式)

更好的方案是在 VS Code 中直接调试开发模式的服务端:

json
{
  "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 会自动在终端显示服务端日志,在浏览器控制台显示客户端日志。

前后端日志的区别

ts
// 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 插件❌ 不执行✅ 浏览器

结构化日志(生产环境推荐)

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 警告。

排查步骤:

  1. 检查是否使用了浏览器 API——windowdocumentlocalStorage 在 SSR 时不存在
  2. 检查是否有时间/随机相关逻辑——Date.now()Math.random() 在 SSR 和 CSR 时结果不同
  3. 检查第三方库是否支持 SSR——有些库只在客户端运行
  4. 检查 HTML 中是否有条件渲染——如 v-if 依赖的值在两端不同

解决方案:

vue
<!-- 方案一:使用 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 中查看组件树,找到问题组件

页面空白

按以下步骤排查:

  1. 打开浏览器控制台——查看是否有 JS 错误
  2. 检查 useFetcherror——数据获取失败但未处理错误
  3. 检查路由注册——在 Nuxt DevTools 中查看路由列表
  4. 检查 app.vue——是否缺少 <NuxtPage />
  5. 检查页面文件——是否在 app/pages/ 目录下
  6. 检查终端——服务端渲染是否报错

API 请求失败

text
步骤 1:Network 面板 → 查看 HTTP 状态码
├── 404 → 路由不存在(检查 server/api/ 目录结构)
├── 400 → 请求参数错误(检查请求体/查询参数)
├── 401 → 未认证(检查 Cookie/Token)
├── 500 → 服务端错误(查看终端日志)
└── CORS 错误 → 配置跨域或检查 baseURL

构建错误

bash
# 清理缓存(解决大多数构建异常)
npx nuxt cleanup

# 重新生成类型(解决类型相关错误)
npx nuxt prepare

# 检查依赖和配置信息
npx nuxt info

# 重新安装依赖
rm -rf node_modules package-lock.json
npm install

nuxt cleanup 做了什么?

删除 .nuxt/ 目录(缓存文件、自动生成代码),下次 nuxt dev 时会重新生成。很多奇怪的构建错误都是缓存导致的。

Source Map 配置

Source Map 让你在浏览器中看到源码而非编译后的代码,是调试的前提:

ts
export default defineNuxtConfig({
  sourcemap: {
    server: true,   // 服务端 Source Map
    client: true,    // 客户端 Source Map
  },
})

INFO

生产环境注意: Source Map 会暴露源码 建议只在开发环境启用。可以用环境变量控制

ts
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,或用开发模式调试配置

知识脉络

text
测试 → 你在这里:调试

         ├─→ 下一步:类型检查

         ├─→ 相关:错误处理(11-错误处理)

         └─→ 相关:生命周期(理解日志出现的位置)

基于 Nuxt 4 官方文档整理编写