我正在构建一个NextJS应用程序,本地一切都运行良好。它拉入所有数据,没有抛出任何错误。
然而,当我尝试运行npm run build
时,我得到一个Prerender错误。我已经尝试按照the documentation中的说明操作,但我发现它没有多大帮助。
问题是我使用path.join(process.cwd(), './posts')
导入帖子,在这种情况下,当它构建时,路径与开发中的路径不同吗?我想不出还有什么可以遗漏的。
package.json
{
...
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
....
}
完整错误:
Error occurred prerendering page "/blog/Blog". Read more: https://nextjs.org/docs/messages/prerender-error
TypeError: Cannot read property 'slug' of undefined
at Post (/.next/server/chunks/2648.js:223:21)
at d (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:33:498)
at bb (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:36:16)
at a.b.render (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:42:43)
at a.b.read (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:41:83)
at Object.exports.renderToString (/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:52:138)
at renderPage (/node_modules/next/dist/server/render.js:736:46)
at Object.ctx.renderPage (/.next/server/pages/_document.js:77:26)
at Object.defaultGetInitialProps (/node_modules/next/dist/server/render.js:368:51)
at Function.getInitialProps (/.next/server/chunks/6859.js:651:16)
postdirectory /posts
下面是我的文件结构:
📦lib
┗ 📜posts.js
📦pages
┣ 📂blog
┃ ┣ 📂Blog
┃ ┃ ┗ 📜index.tsx
┃ ┣ 📂Hero
┃ ┃ ┗ 📜index.tsx
┃ ┗ 📜[slug].tsx
┣ 📂knowledge
┃ ┣ 📂components
┃ ┃ ┣ 📂BlogSection
┃ ┃ ┃ ┣ 📂components
┃ ┃ ┃ ┃ ┗ 📂ArticleBox
┃ ┃ ┃ ┃ ┗ 📜ArticleBox.tsx
┃ ┃ ┃ ┗ 📜index.tsx
┃ ┃ ┣ 📂Hero
┃ ┃ ┃ ┗ 📜index.tsx
┃ ┗ 📜index.tsx
┣ 📜_app.css
┣ 📜_app.tsx
┣ 📜_document.tsx
┗ 📜index.tsx
📦posts
┣ 📜post_1.md
┣ 📜post_2.md
┣ 📜post_3.md
pages/blog/[slug].tsx
import { getAllPostIds, getPostData, getSortedPostsData } from '../../lib/posts';
import React from 'react';
import Hero from './Hero';
import BlogSection from './Blog';
export interface Props {
postData: {...},
posts: {...}[]
}
const BlogArticle: React.FC<Props> = ({ postData, posts }) => {
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()
}
}
}
lib/posts.js
import fs from 'fs'
import path from 'path'
import matter from 'gray-matter'
const postsDirectory = path.join(process.cwd(), './posts')
export async function getSortedPostsData() {
const fileNames = fs.readdirSync(postsDirectory)
const allPostsData = fileNames.map(fileName => {
const slug = fileName.replace(/\.md$/, '')
const fullPath = path.join(postsDirectory, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const matterResult = matter(fileContents)
return {
slug,
...matterResult.data
}
})
}
export async function getAllPostIds() {
const fileNames = fs.readdirSync(postsDirectory)
return fileNames.map(fileName => {
return {
params: {
slug: fileName.replace(/\.md$/, '')
}
}
})
}
export async function getPostData(slug) {
const fullPath = path.join(postsDirectory, `${slug}.md`)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const { data: frontmatter, content } = matter(fileContents)
return {
slug,
content,
frontmatter
}
}
谢谢大家!
1条答案
按热度按时间nnsrf1az1#
感谢@TDiblik为我指明了正确的方向。正如他提到的,有一个good example from Vercel。
我注意到我没有做的一件事是添加一种方法来处理post数据不可用的情况。在这种情况下,我需要在接收数据的每个页面/组件的默认导出中添加以下内容。
在本例中,我的pages/blog/[slug].tsx应该如下所示:
有了这个变化,我就能够构建这个项目了。
再次感谢托马斯!