NextJS 预渲染错误 - 在开发中工作正常,在构建中中断

Alm*_*itt 5 next.js

我正在构建一个 NextJS 应用程序,并且本地一切正常。它提取所有数据并且不会抛出任何错误。

\n

但是,当我尝试运行时npm run build,出现预渲染错误。我尝试按照文档中的说明进行操作,但我发现它不是很有帮助。

\n

问题可能是我正在使用导入帖子path.join(process.cwd(), \'./posts\'),在这种情况下,当它构建时,路径与开发中的路径有所不同?我想不出还有什么可能遗漏的。

\n

包.json

\n
{\n  ...\n  "scripts": {\n    "dev": "next dev",\n    "build": "next build",\n    "start": "next start",\n    "lint": "next lint"\n  },\n  ....\n}\n
Run Code Online (Sandbox Code Playgroud)\n

完整错误:

\n
{\n  ...\n  "scripts": {\n    "dev": "next dev",\n    "build": "next build",\n    "start": "next start",\n    "lint": "next lint"\n  },\n  ....\n}\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的文件结构:

\n
lib\n \xe2\x94\x97 posts.js\npages\n \xe2\x94\xa3 blog\n \xe2\x94\x83 \xe2\x94\xa3 Blog\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\xa3 Hero\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\x97 [slug].tsx\n \xe2\x94\xa3 knowledge\n \xe2\x94\x83 \xe2\x94\xa3 components\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\xa3 BlogSection\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\xa3 components\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 ArticleBox\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83  \xe2\x94\x97 ArticleBox.tsx\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\xa3 Hero\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\xa3 _app.css\n \xe2\x94\xa3 _app.tsx\n \xe2\x94\xa3 _document.tsx\n \xe2\x94\x97 index.tsx\nposts\n \xe2\x94\xa3 post_1.md\n \xe2\x94\xa3 post_2.md\n \xe2\x94\xa3 post_3.md\n
Run Code Online (Sandbox Code Playgroud)\n

页面/博客/[slug].tsx

\n
Error occurred prerendering page "/blog/Blog". Read more: https://nextjs.org/docs/messages/prerender-error\nTypeError: Cannot read property \'slug\' of undefined\n    at Post (/.next/server/chunks/2648.js:223:21)\n    at d (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:33:498)\n    at bb (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)\n    at a.b.render (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)\n    at a.b.read (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)\n    at Object.exports.renderToString (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)\n    at renderPage (/node_modules/next/dist/server/render.js:736:46)\n    at Object.ctx.renderPage (/.next/server/pages/_document.js:77:26)\n    at Object.defaultGetInitialProps (/node_modules/next/dist/server/render.js:368:51)\n    at Function.getInitialProps (/.next/server/chunks/6859.js:651:16)\npostdirectory /posts\n
Run Code Online (Sandbox Code Playgroud)\n

lib/posts.js

\n
lib\n \xe2\x94\x97 posts.js\npages\n \xe2\x94\xa3 blog\n \xe2\x94\x83 \xe2\x94\xa3 Blog\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\xa3 Hero\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\x97 [slug].tsx\n \xe2\x94\xa3 knowledge\n \xe2\x94\x83 \xe2\x94\xa3 components\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\xa3 BlogSection\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\xa3 components\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 ArticleBox\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83  \xe2\x94\x97 ArticleBox.tsx\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\xa3 Hero\n \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\x83 \xe2\x94\x97 index.tsx\n \xe2\x94\xa3 _app.css\n \xe2\x94\xa3 _app.tsx\n \xe2\x94\xa3 _document.tsx\n \xe2\x94\x97 index.tsx\nposts\n \xe2\x94\xa3 post_1.md\n \xe2\x94\xa3 post_2.md\n \xe2\x94\xa3 post_3.md\n
Run Code Online (Sandbox Code Playgroud)\n

Alm*_*itt 3

感谢@TDiblik 为我指明了正确的方向。正如他提到的, Vercel就是一个很好的例子。

我注意到我没有做的一件事是添加一种方法来处理发布数据不可用的情况。在这种情况下,我需要在接收数据的每个页面/组件的默认导出中添加以下内容。

    const router = useRouter()
    if (!router.isFallback && !post) {
        return <ErrorPage statusCode={404} />
    }
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我的pages/blog/[slug].tsx应该如下所示:

import { getAllPostIds, getPostData, getSortedPostsData } from '../../lib/posts';
import React from 'react';
import Hero from './Hero';
import BlogSection from './Blog';
import { useRouter } from 'next/router'
import ErrorPage from 'next/error'

export interface Props {
    postData: {...},
    posts: {...}[]
}

const BlogArticle: React.FC<Props> = ({ postData, posts }) => {
    const router = useRouter()
    if (!router.isFallback && !postData && !posts) {
        return <ErrorPage statusCode={404} />
    }
    return (
        <>
            <Hero />
            <BlogSection postData={postData} posts={posts} />
        </>
    );
};

export default BlogArticle;

export async function getStaticPaths() {
    const paths = await getAllPostIds();
    return {
        paths,
        fallback: false
    }
}

export async function getStaticProps({ params }) {
    return {
        props: {
            postData: await getPostData(params.slug),
            posts: await getSortedPostsData()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

通过这一更改,我能够构建该项目。