在生产中构建 Next.js 静态网站时获取错误 [英] Fetch error when building Next.js static website in production

查看:15
本文介绍了在生产中构建 Next.js 静态网站时获取错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我导出为生产 npm run build 时,我不理解这些错误,但是当我测试 npm run dev 时,它工作得很好.我使用 getStaticPropsgetStaticPath 从 API 路由获取.

I don't understand these errors when I export as production npm run build , but when I test npm run dev it works just fine. I use getStaticProps and getStaticPath fetch from an API route.

首先当我 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:zummonMain Websitemain-website-next
ode_modules
ode-fetchlibindex.js:272:32
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async getStaticPaths (D:zummonMain Websitemain-website-next.nextserverpagesproduct[slug].js:1324:18)
    at async buildStaticPaths (D:zummonMain Websitemain-website-next
ode_modules
extdistuildutils.js:16:80)
    at async D:zummonMain Websitemain-website-next
ode_modules
extdistuildutils.js:26:612
    at async D:zummonMain Websitemain-website-next
ode_modules
extdistuild	racer.js:1:1441 {
  type: 'invalid-json'
}

pagesproduct[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 但仍然收到类似

Second when I remove the production domain, I run npm run build but still get the error like

TypeError: Only absolute URLs are supported
    at getNodeRequestOptions (D:zummonMain Websitemain-website-next
ode_modules
ode-fetchlibindex.js:1305:9)
    at D:zummonMain Websitemain-website-next
ode_modules
ode-fetchlibindex.js:1410:19
    at new Promise (<anonymous>)
    at fetch (D:zummonMain Websitemain-website-next
ode_modules
ode-fetchlibindex.js:1407:9)
    at getStaticPaths (D:zummonMain Websitemain-website-next.nextserverpages[slug].js:938:21)
    at buildStaticPaths (D:zummonMain Websitemain-website-next
ode_modules
extdistuildutils.js:16:86)
    at D:zummonMain Websitemain-website-next
ode_modules
extdistuildutils.js:26:618
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at async D:zummonMain Websitemain-website-next
ode_modules
extdistuild	racer.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"
  }
}

推荐答案

来自 Next.js 文档:

From Next.js documentation:

您不应使用 fetch() 来调用 getStaticProps 中的 API 路由.相反,直接导入 API 路由中使用的逻辑.您可能需要针对这种方法稍微重构您的代码.从外部 API 获取很好!

You should not use fetch() to call an API route in getStaticProps. Instead, directly import the logic used inside your API route. You may need to slightly refactor your code for this approach. Fetching from an external API is fine!

您可以安全地直接在 getStaticProps/getStaticPaths 中使用您的 API 逻辑作为 这些只发生在服务器端.

You can safely use your API logic directly in getStaticProps/getStaticPaths as these only happen server-side.

请注意,getStaticProps 仅在服务器端运行.(...) 这意味着您可以编写诸如直接数据库查询之类的代码,而无需将它们发送到浏览器.

Note that getStaticProps runs only on the server-side. (...) That means you can write code such as direct database queries without them being sent to browsers.

此外,您的 API 路由在构建时不可用,因为此时服务器尚未启动.

Furthermore, your API routes are not available during build-time, as the server has not been started at that point.

这里是你的代码的一个小重构来解决这个问题.

Here's a small refactor of your code to address the issue.

// /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,
    }
}

这篇关于在生产中构建 Next.js 静态网站时获取错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆