[Solved] Module not found: Can't resolve 'fs' – Javascript

by
Ali Hasan
next.js next.js13 node.js reactjs

The Problem:

When using the latest Next.js app router, the application encounters an error: ‘Module not found: Can’t resolve ‘fs” while attempting to access the ‘fs’ module for file system operations. This error arises when trying to read markdown (MDX) files from the ‘_blog’ directory within the Next.js project structure. The code relies on the ‘fs’ module to read and process markdown files, but it faces issues resolving this module in the updated Next.js setup.

The Solutions:

Solution 1: Use the File System API with caution

In Next.js 13, the getStaticProps function is not supported in the app directory. To resolve the error "Module not found: Can’t resolve ‘fs’", follow these steps:

  1. Move Away from Page Components: Migrate your code to use React components instead of page components. This allows you to access the file system API.

  2. Use Static Generation: Utilize getStaticPaths to pre-generate your pages at build time, eliminating the need for getStaticProps at runtime.

  3. Async File System Operations: Use asynchronous file system operations to avoid blocking the main thread. Consider using import fs from 'fs'; and const posts = await getPosts().

  4. Include File System Permission: Ensure your package.json includes the appropriate file system permission, e.g., "node": "read".

  5. Use Absolute Paths: Always use absolute paths when accessing files to avoid ambiguity.

  6. Handle Errors Gracefully: Handle potential file system errors gracefully to prevent application crashes.

  7. Consider Alternatives: Explore alternative methods to retrieve data without directly accessing the file system, such as using a database or a headless CMS.

Solution 2: Use Next.js' dynamic component

The "fs" module is not available on the client-side in Next.js. To access file contents on the server-side and render them on the client-side, you can use Next.js’ dynamic component.

Updated code:

import Head from 'next/head';
import BlogSidebar from '../../components/blog/sidebar';
import Pagination from '../../components/blog/pagination';
import matter from 'gray-matter';
import { join } from 'path';
import { useRouter } from 'next/router';

export async function getStaticProps() {
  const blogsDirectory = join(process.cwd(), '_blog');
  const files = fs.readdirSync(blogsDirectory);

  let posts = files.map((fileName) => {
    const slug = fileName.replace(/\.md$/, '');
    const fullPath = join(blogsDirectory, `${slug}.md`);
    const readFile = fs.readFileSync(fullPath, 'utf8');
    const { data: frontmatter } = matter(readFile);
    return {
      slug,
      frontmatter,
    };
  });

  posts = posts.sort((job1, job2) => (job1.frontmatter.date > job2.frontmatter.date ? -1 : 1));

  return {
    props: {
      posts,
    },
  };
}

const page = ({ posts }) => {
  const dynamicPost = useRouter().query.post;
  const post = posts.find(post => post.slug === dynamicPost);

  return (
    <div>
      <Head>
        <title>My Blog</title>
      </Head>
      <BlogSidebar />
      <main>
        {post && (
          <article>
            <h1>{post.frontmatter.title}</h1>
            <p>{post.frontmatter.content}</p>
          </article>
        )}
      </main>
      <Pagination />
    </div>
  );
};

export default page;

This code will load the list of posts on the server-side. Then, it will render the post that is specified in the query string. If there is no post specified in the query string, it will render the first post in the list.

Q&A

What is the error and how do I fix it ?

The fs module is not available in the client-side. You can use the next/dynamic component to load the file contents on the server-side and then render them on the client-side.

How do I load the list of posts on the server-side?

You can use the getStaticProps function to load the list of posts on the server-side.

Video Explanation:

The following video, titled "Module not found: Error: Can't resolve '../styles' Compiled with ...", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Module not found: Error: Can't resolve '../styles' Compiled with problems Reactjs styles.css solved. 23K views · 2 years ago ...more ...