You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next13 Todo应用Vercel构建失败问题求助

Next13 Todo应用Vercel构建错误解决方案

1. 解决 SyntaxError: Unexpected token T in JSON at position 0

这个错误本质是代码尝试解析非JSON格式的响应,多数和Prisma查询失败或环境配置有关:

  • 确认Vercel构建环境变量:Vercel的构建阶段和运行阶段是分离的,确保DATABASE_URL在「构建环境变量」中也已配置(不是只加在运行时),因为Next13 Server Component会在构建时执行数据查询。
  • 给Prisma查询加异常捕获:Server Component顶层的Prisma查询如果抛出错误,会返回错误文本而非JSON,导致解析失败。用try-catch包裹避免构建崩溃:
// app/page.tsx (Server Component)
import prisma from '@/lib/prisma'

export default async function Home() {
  let todos = []
  try {
    todos = await prisma.todo.findMany()
  } catch (err) {
    console.error('Prisma查询失败:', err)
    // 可返回友好提示,避免构建中断
  }
  return <div>{/* 渲染逻辑 */}</div>
}
  • 检查Railway数据库SSL配置:Railway的PostgreSQL默认要求SSL连接,确保DATABASE_URL末尾加上?sslmode=require,本地开发可能不需要,但Vercel部署必须配置。

2. 修复 TypeError: The body has already been consumed

这个错误是重复读取Response对象的body导致的,常见于API Route或数据获取逻辑:

  • API Route避免重复读取请求体:如果自定义了API Route,确保只读取一次request body:
// app/api/todos/route.ts
export async function GET(request: Request) {
  // 错误示例:多次调用request.json()会触发错误
  // 正确做法:读取一次后缓存结果
  let requestBody
  try {
    requestBody = await request.json()
  } catch (e) {
    // 处理非JSON格式的请求
  }

  const todos = await prisma.todo.findMany()
  return Response.json(todos)
}
  • Server Component中避免重复处理响应:调用外部API时,只解析一次响应:
async function fetchTodos() {
  const res = await fetch('/api/todos')
  const data = await res.json() // 仅调用一次
  return data
}

3. 客户端组件+useEffect的正确用法

如果你切换到客户端组件,注意两个核心问题:

  • Prisma不能直接在客户端运行:必须通过API Route间接操作数据库,客户端组件只能调用API获取数据。
  • useEffect中处理异常:避免未捕获的错误导致部署失败:
'use client'

import { useState, useEffect } from 'react'

export default function Home() {
  const [todos, setTodos] = useState([])
  const [error, setError] = useState('')

  useEffect(() => {
    const getTodos = async () => {
      try {
        const res = await fetch('/api/todos')
        if (!res.ok) throw new Error('数据获取失败')
        const data = await res.json()
        setTodos(data)
      } catch (err) {
        setError((err as Error).message)
        console.error(err)
      }
    }
    getTodos()
  }, [])

  if (error) return <div>错误:{error}</div>
  return <div>{/* 渲染逻辑 */}</div>
}

4. 额外调试技巧

  • 本地模拟Vercel构建:运行npx vercel build命令,在本地复现构建错误,方便快速调试。
  • 查看Vercel构建日志详情:在Vercel控制台的构建日志中,找到错误对应的代码行,精准定位问题。

内容的提问来源于stack exchange,提问作者Satoshi Okazaki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:35:46