Next.js+GraphCMS项目Vercel构建失败,报document未定义错误
Next.js + GraphCMS 部署Vercel构建崩溃排查
错误信息
TypeError: Cannot read properties of undefined (reading 'document') at Object.parseRequestExtendedArgs (/vercel/path0/node_modules/graphql-request/dist/parseArgs.js:37:25) at /vercel/path0/node_modules/graphql-request/dist/index.js:422:42 at step (/vercel/path0/node_modules/graphql-request/dist/index.js:63:23) at Object.next (/vercel/path0/node_modules/graphql-request/dist/index.js:44:53) at /vercel/path0/node_modules/graphql-request/dist/index.js:38:71 at new Promise () at __awaiter (/vercel/path0/node_modules/graphql-request/dist/index.js:34:12) at request (/vercel/path0/node_modules/graphql-request/dist/index.js:418:12) at getPosts (/vercel/path0/.next/server/chunks/104.js:1143:82) at getStaticPaths (/vercel/path0/.next/server/pages/post/[slug].js:98:86) Build error occurred Error: Failed to collect page data for /post/[slug] at /vercel/path0/node_modules/next/dist/build/utils.js:959:15 at processTicksAndRejections (node:internal/process/task_queues:96:5) { type: 'Error' } error Command failed with exit code 1.
问题背景
本地环境可正常构建运行,但部署至Vercel时构建崩溃,错误触发链为getStaticPaths调用getPosts,进而调用graphql-request时尝试访问浏览器专属的document对象。
相关代码
pages/post/[slug].js
import React from "react"; import { useRouter } from "next/router"; import { PostDetail, Categories, PostWidget, Author, Comments, CommentsForm, Loader, } from "../../components"; import { getPosts, getPostDetails } from "../../services"; import { AdjacentPosts } from "../../sections"; const PostDetails = ({ post }) => { const router = useRouter(); if (router.isFallback) { return <Loader />; } return ( <> <div className="container mx-auto px-10 mb-8"> <div className="grid grid-cols-1 lg:grid-cols-12 gap-12"> <div className="col-span-1 lg:col-span-8"> <PostDetail post={post} /> <Author author={post.author} /> <AdjacentPosts slug={post.slug} createdAt={post.createdAt} /> <CommentsForm slug={post.slug} /> <Comments slug={post.slug} /> </div> <div className="col-span-1 lg:col-span-4"> <div className="relative lg:sticky top-8"> <PostWidget slug={post.slug} categories={post.categories.map((category) => category.slug)} /> <Categories /> </div> </div> </div> </div> </> ); }; export default PostDetails; // Fetch data at build time export async function getStaticProps({ params }) { const data = await getPostDetails(params.slug); return { props: { post: data, }, }; } // Specify dynamic routes to pre-render pages based on data. // The HTML is generated at build time and will be reused on each request. export async function getStaticPaths() { const posts = await getPosts(); return { paths: posts.map(({ node: { slug } }) => ({ params: { slug } })), fallback: false, }; }
getPosts 查询
export const getPosts = async () => { const query = gql` query MyQuery { postsConnection { edges { cursor node { author { bio name id photo { url } } createdAt slug title excerpt displayedDate featuredImage { url } categories { name slug } } } } } `; const result = await request(graphqlAPI, query); return result.postsConnection.edges; };
getPostDetails 查询
export const getPostDetails = async (slug) => { const query = gql` query GetPostDetails($slug: String!) { post(where: { slug: $slug }) { title excerpt featuredImage { url id } author { name bio photo { url } } createdAt slug content { raw } categories { name slug } displayedDate } } `; const result = await request(graphqlAPI, query, { slug }); return result.post; };
排查方案
1. 环境变量验证
确认Vercel项目设置的环境变量中,graphqlAPI对应的GraphCMS端点以及API密钥已正确配置,且勾选了"在构建时暴露"选项。本地.env文件的变量需要同步到Vercel。
2. 修复graphql-request版本问题
该错误大概率是graphql-request版本兼容问题,部分新版本在Node.js环境(Vercel构建时为服务端环境)中错误地调用了浏览器的document对象:
- 卸载当前版本:
npm uninstall graphql-request - 安装稳定兼容版本:
npm install graphql-request@4.3.0(此版本经过验证可在服务端环境正常运行)
3. 检查graphql-request调用参数
确保调用request方法时,没有传递依赖浏览器环境的参数(如包含document.cookie的headers),所有请求配置需适配Node.js环境。
4. 本地模拟构建测试
在本地执行next build命令,模拟Vercel的构建流程,若能复现错误,可直接在本地调试,更快定位问题。
内容的提问来源于stack exchange,提问作者SuperPanda
相关产品推荐
相关产品推荐

