服务端阅读 05月28日 02:26
Nuxt.js 中如何处理错误和进行调试?
Nuxt.js 的错误处理和调试涉及多个层次:页面级、组件级、服务端 API 级,以及全局兜底。不同版本的 Nuxt(2 vs 3)API 差异较大,下面分别说明核心机制。页面级错误处理Nuxt 通过错误页面捕获路由渲染阶段的异常,给用户友好的降级体验。Nuxt 2 在 layouts/error.vue 中定义错误页,组件接收 error prop(含 statusCode 和 message):```vue 页面不存在 服务器错误 {{ error.message }} 返回首页 export default { props: ['error'], layout: 'blank'}```Nuxt 3 错误页改为项目根目录的 ~/error.vue(与 app.vue 同级),写法基于 Composition API:```vueconst props = defineProps({ error: Object })const handleError = () => clearError({ redirect: '/' }) {{ error.statusCode }} {{ error.message }} 返回首页 ```关键区别:Nuxt 3 使用 clearError() 清除错误状态,而不是自动恢复。数据获取中的错误捕获异步数据获取是错误高发区,Nuxt 2 和 3 的处理方式不同。Nuxt 2 在 asyncData 中用 error() 函数跳转到错误页:```javascriptexport default { async asyncData({ params, $axios, error }) { try { const user = await $axios.$get(`/api/users/\${params.id}`) return { user } } catch (err) { error({ statusCode: 404, message: '用户不存在' }) } }}```Nuxt 3 使用 useFetch / useAsyncData,通过 createError() 抛出结构化错误:```javascriptconst { data, error } = await useFetch(`/api/users/\${route.params.id}`)if (error.value) { throw createError({ statusCode: 404, message: '用户不存在' })}```useFetch 返回的 error 是响应式引用,可以直接在模板中展示,不必跳转错误页。组件级错误边界Nuxt 3 提供了 <NuxtErrorBoundary> 组件,隔离组件内的客户端错误,避免整个页面崩溃:```vue 组件加载失败:{{ error.message }} 重试 ```适合用在仪表盘、信息流等局部模块,一个模块出错不影响其他区域。服务端 API 错误处理Nuxt 3 的 server routes 需要正确抛出 HTTP 错误:```javascript// server/api/users/[id].jsexport default defineEventHandler(async (event) => { const id = getRouterParam(event, 'id')const user = await db.user.findById(id) if (!user) { throw createError({ statusCode: 404, statusMessage: 'User not found' }) }return user})```服务端的 createError() 会自动设置 HTTP 状态码和响应体,客户端通过 useFetch 的 error 接收。注意不要在错误消息中拼接用户输入,避免注入风险。全局错误钩子Nuxt 3 提供了生命周期钩子统一捕获错误:```javascript// plugins/error-handler.jsexport default defineNuxtPlugin((nuxtApp) => { nuxtApp.hook('vue:error', (error, instance, info) => { console.error('Vue error:', error, info) // 上报到 Sentry })nuxtApp.hook('app:error', (error) => { console.error('App error:', error) })})```vue:error:Vue 组件渲染或生命周期中未捕获的错误app:error:Nuxt 初始化、插件加载等阶段的错误配合 Sentry 或 LogRocket 可以实现错误监控和报警。中间件中的错误处理路由中间件里不能直接 throw,要用 abortNavigation() 中断导航:```javascript// middleware/auth.jsexport default defineNuxtRouteMiddleware((to, from) => { const token = useCookie('token') if (!token.value) { return abortNavigation( createError({ statusCode: 401, message: '请先登录' }) ) }})```Nuxt 2 的中间件则用 redirect() 或 error() 处理,逻辑类似但 API 不同。调试方法开发环境调试:nuxt dev 启动开发服务器,热重载 + source maps,直接在浏览器 DevTools 断点Nuxt DevTools(Nuxt 3 专有):集成组件树、路由信息、payload 检查、auto-imports 可视化,通过 nuxi dev --enable-devtools 开启Vue DevTools:查看组件 props、响应式数据、事件流服务端调试:```javascript// nuxt.config.tsexport default defineNuxtConfig({ devServer: { debug: true }})```配合 VS Code 的 Node.js 调试配置,可以给 server routes 加断点:```json{ "type": "node", "request": "launch", "name": "Nuxt Server", "program": "\${workspaceFolder}/node_modules/.bin/nuxi", "args": ["dev"], "console": "integratedTerminal"}```构建产物分析:```bashnpx nuxi analyze```分析打包体积,定位过大的依赖,优化加载性能。SSR 水合不匹配排查:服务端渲染的 HTML 与客户端 hydration 不一致时,控制台会报 Hydration mismatch 警告。常见原因:使用了 Date.now() 等运行时不确定的值条件渲染依赖了 window 等仅客户端的对象解决方案:用 <ClientOnly> 包裹客户端专属内容,或用 onMounted 延迟赋值常见问题chunk 加载失败:新部署后旧页面的 JS chunk URL 失效,Nuxt 3 会自动硬重载;Nuxt 2 需手动监听 window.onerror 中的 chunk 错误并刷新。500 错误定位:优先检查 server routes 的 try-catch 是否遗漏,用 console.error 打印完整堆栈,确认 API 调用参数和返回格式。asyncData 报错但页面空白:Nuxt 2 中 asyncData 未调用 error() 时,错误会被静默吞掉。确保 catch 块中调用 error() 或至少 console.error。