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

IT技术 javascript node.js next.js
2021-03-04 21:00:43

当我作为 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的脚本

{
  "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"
  }
}
1个回答

从 Next.js文档

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

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

请注意,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,
    }
}
确保检查您的数据以避免访问undefined触发此类错误的道具。
2021-04-16 21:00:43
谢谢你我现在明白了更多,但是这次显示Error occurred prerendering page "/en/product/[slug]"-TypeError: Cannot read property 'contents' of undefined相反。但对于测试服务器运行正常
2021-04-22 21:00:43
非常感谢,这应该已经解决了我提出的问题的错误。对于我面临的下一个错误超出范围,还有一些我可以自己修复但我还没有看到 *我认为只是测试npm run dev工作很好,但在生产构建时显然不一样
2021-05-10 21:00:43