在生产中构建 Next.js 静态网站时获取错误
Posted
技术标签:
【中文标题】在生产中构建 Next.js 静态网站时获取错误【英文标题】:Fetch error when building Next.js static website in production 【发布时间】:2021-07-08 00:09:52 【问题描述】:当我导出为生产 npm run build
时,我不理解这些错误,但是当我测试 npm run dev
时,它工作得很好。我使用 getStaticProps
和 getStaticPath
从 API 路由获取。
第一次当我npm run build
FetchError: invalid json response body at https://main-website-next.vercel.app/api/products reason: Unexpected token T in JSON at position
0
at D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:272:32
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async getStaticPaths (D:\zummon\Main Website\main-website-next\.next\server\pages\product\[slug].js:1324:18)
at async buildStaticPaths (D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:16:80)
at async D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:26:612
at async D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\tracer.js:1:1441
type: 'invalid-json'
\pages\product\[slug]
import assetPrefix from '../../next.config'
export default function Page()...
export const getStaticProps = async ( params: slug , locale ) =>
const res = await fetch(`$assetPrefix/api/products/$slug`)
const result = await res.json()
const data = result.filter(item => item.locale === locale)[0]
const title, keywords, description = data
return
props:
data,
description,
keywords,
title
export const getStaticPaths = async () =>
const res = await fetch(`$assetPrefix/api/products`)
const result = await res.json()
const paths = result.map(( slug, locale ) => ( params: slug: slug , locale ))
return
fallback: true,
paths,
next.config.js
const isProd = process.env.NODE_ENV === 'production'
module.exports =
assetPrefix: isProd ? 'https://main-website-next.vercel.app' : 'http://localhost:3000',
i18n:
localeDetection: false,
locales: ['en', 'th'],
defaultLocale: 'en',
API 路由
// pages/api/products/index.js
import data from '../../../data/products'
export default (req, res) =>
res.status(200).json(data)
// pages/api/products/[slug].js
import db from '../../../data/products'
export default ( query: slug , res) =>
const data = db.filter(item => item.slug === slug)
if (data.length > 0)
res.status(200).json(data)
else
res.status(404).json( message: `$slug not found` )
// ../../../data/products (data source)
module.exports = [
locale: "en", slug: "google-sheets-combine-your-cashflow",
title: "Combine your cashflow",
keywords: ["Google Sheets","accounting"],
description: "...",
,
...
]
第二次删除生产域时,我运行 npm run build
但仍然收到类似的错误
TypeError: Only absolute URLs are supported
at getNodeRequestOptions (D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:1305:9)
at D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:1410:19
at new Promise (<anonymous>)
at fetch (D:\zummon\Main Website\main-website-next\node_modules\node-fetch\lib\index.js:1407:9)
at getStaticPaths (D:\zummon\Main Website\main-website-next\.next\server\pages\[slug].js:938:21)
at buildStaticPaths (D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:16:86)
at D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\utils.js:26:618
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async D:\zummon\Main Website\main-website-next\node_modules\next\dist\build\tracer.js:1:1441
type: 'TypeError'
删除后我的next.config.js
const isProd = process.env.NODE_ENV === 'production'
module.exports = //remove
assetPrefix: isProd ? '' : 'http://localhost:3000',
i18n:
localeDetection: false,
locales: ['en', 'th'],
defaultLocale: 'en',
我的package.json
当我npm run build
脚本
"name": "main-website-next",
"version": "0.1.0",
"private": true,
"scripts":
"dev": "next dev",
"build": "next build && next export",
"start": "next start"
,
"dependencies":
"next": "10.0.6",
"react": "17.0.1",
"react-dom": "17.0.1"
【问题讨论】:
你能分享你的 API 路由代码吗?与其调用 API 路由,不如直接在getStaticProps
/getStaticPaths
中使用数据获取逻辑。
谢谢。我在上面的问题中添加了更多信息,如果我理解正确,如果这不是你要找的,请告诉我你需要什么。我对下一个 js 真的很陌生
@juliomalves 直接使用数据获取逻辑fetch('$assetPrefix/api/products/$slug')
更改为fetch('$assetPrefix/data/products')
或fetch(/next/server...)
对吗?但我不知道正确的那个。另外我只是在其项目中获取数据
【参考方案1】:
您不应在getStaticProps
内调用内部 API 路由。相反,您可以直接在getStaticProps
/getStaticPaths
中安全地使用您的 API 逻辑。这些只发生在服务器端,所以你可以write server-side code directly。
由于
getStaticProps
只在服务器端运行,它永远不会在服务器端运行 客户端。它甚至不会包含在 JS 包中 浏览器,因此您可以编写直接的数据库查询而无需它们 发送到浏览器。这意味着不是从
getStaticProps
(它本身从外部源获取数据), 可以直接在getStaticProps
写服务端代码。
此外,您的 API 路由在构建时不可用,因为此时服务器尚未启动。
这里是你的代码的一个小重构来解决这个问题。
// /pages/product/[slug]
import db from '../../../data/products'
// Remaining code..
export const getStaticProps = async ( params: slug , locale ) =>
const result = db.filter(item => item.slug === slug)
const data = result.filter(item => item.locale === locale)[0]
const title, keywords, description = data
return
props:
data,
description,
keywords,
title
export const getStaticPaths = async () =>
const paths = db.map(( slug, locale ) => ( params: slug: slug , locale ))
return
fallback: true,
paths,
【讨论】:
谢谢我现在明白了更多,但是这次显示Error occurred prerendering page "/en/product/[slug]"
- TypeError: Cannot read property 'contents' of undefined
。但测试服务器运行正常
确保检查您的数据以避免访问undefined
触发类似错误的道具。
非常感谢,这应该已经解决了我提出的问题的错误。对于我面临的下一个错误超出范围,还有一些我可以自己修复但我还没有看到的东西 *我认为只是测试 npm run dev
工作得很好,但它显然不一样生产构建
@juliomalves 我如何执行未定义的检查?
@Sushilzzz 在访问其属性之一之前检查对象不是undefined
。以上是关于在生产中构建 Next.js 静态网站时获取错误的主要内容,如果未能解决你的问题,请参考以下文章
Vercel 中的 Next.js 与 Sentry - 在生产中忽略源映射
getServerSideProps 在生产中不渲染动态页面,并显示 404 错误