簡體   English   中英

在生產中構建 Next.js static 網站時獲取錯誤

[英]Fetch error when building Next.js static website in production

當我導出為生產npm run build時,我不理解這些錯誤,但是當我測試npm run dev時,它工作得很好。 我使用getStaticPropsgetStaticPath從 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腳本時,我的 package.json

{
  "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"
  }
}

您不應該在getStaticProps中調用內部 API 路由。 相反,您可以直接在getStaticProps / getStaticPaths中安全地使用您的 API 邏輯。 這些只發生在服務器端,因此您可以直接編寫服務器端代碼

由於getStaticProps僅在服務器端運行,它永遠不會在客戶端運行。 它甚至不會包含在瀏覽器的 JS 包中,因此您可以編寫直接數據庫查詢,而無需將它們發送到瀏覽器。

這意味着您可以直接在getStaticProps中編寫服務器端代碼,而不是從getStaticProps獲取API 路由(它本身從外部源獲取數據)。

此外,您的 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,
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM