Mac Dev
Mac Dev

Reputation: 103

NextJs Render Erorrs

I receive the following errors when trying to build my page using "Yarn Build"

Automatically optimizing pages ...
Error occurred prerendering page "/design/des". Read more: https://err.sh/next.js/prerender-error:
Error: Cannot find module './des.md'

Error occurred prerendering page "/blog/po". Read more: https://err.sh/next.js/prerender-error:
Error: Cannot find module './po.md'

Error occurred prerendering page "/photo/pho". Read more: https://err.sh/next.js/prerender-error:
Error: Cannot find module './pho.md'

Error occurred prerendering page "/art/a". Read more: https://err.sh/next.js/prerender-error:
Error: Cannot find module './a.md'

I have tried running yarn upgrade to upgrade all modules, I have also looked through all of my files and nowhere in any pages are there any mentions of pho.md or any of the other listed items. Any idea on what might be causing these errors?

File Structure

package.json
├── README.md
├── src
│   ├── components
│   │   ├── ArtList.js
│   │   ├── BlogList.js
│   │   ├── ContactForm.js
│   │   ├── DesignList.js
│   │   ├── Header.js
│   │   ├── Layout.js
│   │   ├── Meta.js
│   │   ├── PhotoList.js
│   │   ├── Singular.js
│   │   └── Social.js
│   ├── data
│   │   └── config.json
│   ├── markdown
│   │   ├── arts
│   │   │   ├── art1.md
│   │   │   ├── art2.md
│   │   │   └── art3.md
│   │   ├── design
│   │   │   ├── des1.md
│   │   │   ├── des2.md
│   │   │   └── des3.md
│   │   ├── photos
│   │   │   ├── 43qf.md
│   │   │   ├── 5 (copy).md
│   │   │   ├── 5.md
│   │   │   ├── a (copy).md
│   │   │   ├── a.md
│   │   │   ├── a#.md
│   │   │   ├── b (copy).md
│   │   │   ├── b.md
│   │   │   ├── c (copy).md
│   │   │   ├── dsfg (copy).md
│   │   │   ├── dsfg.md
│   │   │   ├── g.md
│   │   │   ├── photo-1 copy (copy).md
│   │   │   ├── photo-1 (copy).md
│   │   │   ├── photo-1 copy.md
│   │   │   ├── photo-1.md
│   │   │   ├── photo-2 copy (copy).md
│   │   │   └── photo-2 copy.md
│   │   └── posts
│   │       ├── cat-ipsum.md
│   │       └── cupkaes.md
│   ├── pages
│   │   ├── about.js
│   │   ├── art
│   │   │   └── [slug].js
│   │   ├── art.js
│   │   ├── blog
│   │   │   └── [slug].js
│   │   ├── blog.js
│   │   ├── contact.js
│   │   ├── design
│   │   │   └── [slug].js
│   │   ├── design.js
│   │   ├── index.js
│   │   ├── music.js
│   │   ├── photo
│   │   │   └── [slug].js
│   │   └── photography.js
│   └── public
│       └── static
│           ├── art
│           │   ├── art1.jpg
│           │   └── art2.png
│           ├── design
│           │   ├── des1.jpg
│           │   └── des2.jpg
│           ├── fonts
│           │   └── photography
│           ├── main
│           │   ├── aboutimg.png
│           │   ├── click.png
│           │   ├── lucy.png
│           │   └── nextjs-black-logo.svg
│           ├── photo
│           │   ├── test2.jpg
│           │   ├── test3.jpg
│           │   ├── test4.jpg
│           │   ├── test.jpeg
│           │   └── test.jpg
│           └── post-img
│               ├── disenchantment.svg
│               └── dough.svg
└── yarn.lock

Full getStaticProps

export async function getStaticProps({ ...ctx }) {
  const { slug } = ctx.params
  const content = await import(`../../markdown/posts/${slug}.md`)
  const config = await import(`../../data/config.json`)
  const data = matter(content.default)

  return {
    props: {
      siteTitle: config.title,
      frontmatter: data.data,
      markdownBody: data.content,
    },
  }
}

export async function getStaticPaths() {
  //get all .md files in the posts dir
  const blogs = glob.sync('src/markdown/posts/**/*.md')

  //remove path and extension to leave filename only
  const blogSlugs = blogs.map(file =>
    file
      .split('/')[2]
      .replace(/ /g, '-')
      .slice(0, -3)
      .trim()
  )

  // create paths with `slug` param
  const paths = blogSlugs.map(slug => `/blog/${slug}`)
  return {
    paths,
    fallback: true,
  }
}

New Errors

> Build error occurred
TypeError: __webpack_require__(...).parse is not a function
    at /home/mac/Documents/lucy-portfolio/src/.next/server/static/F_8nzvuKI79UB0iqKIVhG/pages/blog/[slug].js:914:67
    at Array.map (<anonymous>)
    at getStaticPaths (/home/mac/Documents/lucy-portfolio/src/.next/server/static/F_8nzvuKI79UB0iqKIVhG/pages/blog/[slug].js:914:27)
    at buildStaticPaths (/home/mac/Documents/lucy-portfolio/node_modules/next/dist/build/utils.js:18:86)
    at Object.isPageStatic (/home/mac/Documents/lucy-portfolio/node_modules/next/dist/build/utils.js:25:548)
    at execFunction (/home/mac/Documents/lucy-portfolio/node_modules/jest-worker/build/workers/processChild.js:155:17)
    at execHelper (/home/mac/Documents/lucy-portfolio/node_modules/jest-worker/build/workers/processChild.js:139:5)
    at execMethod (/home/mac/Documents/lucy-portfolio/node_modules/jest-worker/build/workers/processChild.js:143:5)
    at process.<anonymous> (/home/mac/Documents/lucy-portfolio/node_modules/jest-worker/build/workers/processChild.js:64:7)
    at process.emit (events.js:315:20) {
  type: 'TypeError'
}

Code as follows

export async function getStaticPaths() {
  const path = require
  //get all .md files in the posts dir
  const blogs = glob.sync('src/markdown/posts/**/*.md')

  //remove path and extension to leave filename only
  const blogSlugs = blogs.map(file => path.parse(file).name);
  // create paths with `slug` param
  const paths = blogSlugs.map(slug => `/blog/${slug}`)
  return {
    paths,
    fallback: true,
  }
}

Upvotes: 1

Views: 5325

Answers (1)

Cedomir Rackov
Cedomir Rackov

Reputation: 1092

Here is the simplified code. Keep the glob as is, it seems to be working fine. The issue is in how you parse the names from the list.

In this snippet you will see the issue of the blogSlugs from your code and the newBlogSlugs as a solution.

What the newBlogSlugs code does?

file.replace(/^.*[\\\/]/, '').split('.')[0]

Replace methods replaces all the path parts except the last one and we get "cupcakes.md". Then we split the string on the dot and use only the first part and get "cupcakes".

// This represent the output of your glob function. You don't nee to copy the list. That is just for clarity on how the blogs array looks.
const blogs = [
  "src/markdown/posts/cupcakes.md",
  "src/markdown/posts/cat-stuff.md"
];

// This is your blogSlugs contstant
const blogSlugs = blogs.map(file =>
  file
    .split('/')[2]
    .replace(/ /g, '-')
    .slice(0, -3)
    .trim()
)

// This is the new solution that you should use instead of your blogSlugs
// !!! UPDATED HERE
const newBlogSlugs = blogs.map(file => file.replace(/^.*[\\\/]/, '').split('.')[0]);

console.log("Original", blogSlugs);
console.log("Fixed", newBlogSlugs);

EDIT: Mentioned that I used path module.

EDIT2: Changed the naming of the variables so they look more like the code in question.

EDIT3: In the original answer i used the path module for getting the slug, changed it to string replace. Remove the path module, it is producing the error.

Upvotes: 2

Related Questions