在生产中构建 Next.js 静态网站时获取错误

zum*_*mon 18 javascript node.js next.js

当我导出为生产时,我不明白这些错误npm run build,但当我测试时npm run dev它工作得很好。我使用API 路由getStaticProps并从中获取。getStaticPath

首先当我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'
}
Run Code Online (Sandbox Code Playgroud)

\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,
  }
}
Run Code Online (Sandbox Code Playgroud)

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',
  }
}
Run Code Online (Sandbox Code Playgroud)

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: "...",
  },
    ...
]
Run Code Online (Sandbox Code Playgroud)

其次,当我删除生产域时,我运行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'
}
Run Code Online (Sandbox Code Playgroud)

我的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',
  }
}
Run Code Online (Sandbox Code Playgroud)

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"
  }
}
Run Code Online (Sandbox Code Playgroud)

jul*_*ves 27

您不应该在getStaticProps. getStaticProps相反,您可以直接在/中安全地使用 API 逻辑getStaticPaths。这些仅发生在服务器端,因此您可以直接编写服务器端代码

\n
\n

由于getStaticProps仅在服务器端运行,因此它永远不会在客户端运行。它甚至不会包含在浏览器的 JS 包中,因此您可以编写直接数据库查询,而无需将它们发送到浏览器。

\n

这意味着可以直接getStaticPropsgetStaticProps.

\n
\n

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

\n
\n

这是对代码的一个小重构以解决该问题。

\n
// /pages/product/[slug]\n\nimport db from \'../../../data/products\'\n\n// Remaining code..\n\nexport const getStaticProps = async ({ params: { slug }, locale }) => {\n    const result = db.filter(item => item.slug === slug)\n    const data = result.filter(item => item.locale === locale)[0]\n    const { title, keywords, description } = data\n    return {\n        props: {\n            data,\n            description,\n            keywords, \n            title\n        }\n    }\n}\n\nexport const getStaticPaths = async () => {\n    const paths = db.map(({ slug, locale }) => ({ params: { slug: slug }, locale }))\n    return {\n        fallback: true,\n        paths,\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n