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

Next.js 13.4.12部署Vercel时遇SyntaxError: Unexpected token <错误求助

部署Vercel时Next.js 13构建失败:JSON解析错误

本地开发时项目运行正常,但部署到Vercel时构建持续失败,报错JSON解析异常。使用Next.js 13.4.12,项目包含app/projects/page.tsx和app/api/projects/route.ts,相关代码如下:

页面组件代码(app/projects/page.tsx)

const ProjectList = async () => {
  const baseUrl =
    process.env.NODE_ENV === "development"
      ? "http://localhost:3000"
      : "https://www.example.com";

  const response = await fetch(`${baseUrl}/api/projects`);
  const data = await response.json();
  const projects: Project[] = data.projects;

  return (
    <div>
      {projects?.map((project) => <h1>{project?.name}</h1>)} // etc. etc.
    </div>
  );
};

API路由代码(app/api/projects/route.ts)

export async function GET() {
    try {
      // Retrieve the "projects" collection from Firestore
      const projectsCollection = collection(db, "projects");
      const projectsSnapshot = await getDocs(projectsCollection);

      // Map the documents in the collection to an array of project objects
      const projects = projectsSnapshot.docs.map((doc) => ({
        id: doc.id,
        ...doc.data(),
      }));

      return NextResponse.json(JSON.stringify({ projects: projects }));
    } catch (error) {
      console.error("Error retrieving projects:", error);
      return NextResponse.error();
    }
}

部署时错误信息

SyntaxError: Unexpected token < in JSON at position 0
11:13:00.318        at JSON.parse (<anonymous>)
11:13:00.318        at parseJSONFromBytes (node:internal/deps/undici/undici:6571:19)
11:13:00.318        at successSteps (node:internal/deps/undici/undici:6545:27)
11:13:00.319        at node:internal/deps/undici/undici:1211:60
11:13:00.319        at node:internal/process/task_queues:140:7
11:13:00.319        at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
11:13:00.319        at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
11:13:00.319        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
11:13:00.336    
11:13:00.336    Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
11:13:00.336    SyntaxError: Unexpected token < in JSON at position 0
11:13:00.336        at JSON.parse (<anonymous>)
11:13:00.336        at parseJSONFromBytes (node:internal/deps/undici/undici:6571:19)
11:13:00.337        at successSteps (node:internal/deps/undici/undici:6545:27)
11:13:00.340        at node:internal/deps/undici/undici:1211:60
11:13:00.340        at node:internal/process/task_queues:140:7
11:13:00.340        at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
11:13:00.340        at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8)
11:13:00.340        at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
11:13:00.340    
11:13:00.340    > Export encountered errors on following paths:
11:13:00.340        /page: /
11:13:00.340    - info Generating static pages (5/5)
11:13:00.398    Error: Command "npm run build" exited with 1

解决方案

1. 修复API路由的JSON返回逻辑

NextResponse.json()会自动将传入的对象序列化为JSON字符串,不需要手动调用JSON.stringify。手动序列化会导致返回的数据是字符串形式的JSON,客户端解析时会出错。修改API路由:

// 替换原来的return语句
return NextResponse.json({ projects: projects });

2. 移除服务器组件中的外部URL调用

在App Router的服务器组件中,调用内部API直接使用相对路径即可,无需拼接完整域名。构建预渲染阶段,外部URL可能无法正常访问,导致返回HTML错误页面(这就是错误中Unexpected token <的原因——返回的是HTML而非JSON)。修改页面组件:

const ProjectList = async () => {
  // 直接使用相对路径调用内部API
  const response = await fetch('/api/projects');
  const data = await response.json();
  const projects: Project[] = data.projects;

  return (
    <div>
      {projects?.map((project) => <h1>{project?.name}</h1>)} // etc. etc.
    </div>
  );
};

3. 更优方案:直接在服务器组件中调用Firestore

既然是服务器组件,完全可以跳过API路由,直接在组件内获取Firestore数据,减少额外请求,也避免此类跨环境问题:

const ProjectList = async () => {
  try {
    const projectsCollection = collection(db, "projects");
    const projectsSnapshot = await getDocs(projectsCollection);
    const projects: Project[] = projectsSnapshot.docs.map((doc) => ({
      id: doc.id,
      ...doc.data(),
    }));

    return (
      <div>
        {projects?.map((project) => <h1>{project?.name}</h1>)}
      </div>
    );
  } catch (error) {
    console.error("Error retrieving projects:", error);
    return <div>Failed to load projects</div>;
  }
};

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 11:07:12