Search code examples
next.jsvercelproduction

Module not found: Can't resolve '../header/main-header.js' in Next.js building error


1

In layout.js file I get an error "Module not found: Can't resolve '../header/main-header.js'"

My layout.js imports header such as import MainHeader from "../header/main-header.js";

I know I have a hyphen in filename, but it doesn't seem to affect anything for other files. Everything works fine in production and when I build only this file gets an error.

main.header.js exports itself such as export default MainHeader;

I think the problem might be in my next.config below:

I can't figure out how to use const nextConfig with webpack(config) together:

Also I have tried using import MainHeader from "../header/main-header.js" without .js extension and other global paths and it still wouldn't work while building.

/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"],

  reactStrictMode: true,
};

module.exports = {
  webpack(config) {
    const fileLoaderRule = config.module.rules.find((rule) => rule.test?.test?.(".svg"));

    config.module.rules.push(
      {
        ...fileLoaderRule,
        test: /\.svg$/i,
        resourceQuery: /url/,
      },

      {
        test: /\.svg$/i,
        issuer: /\.[jt]sx?$/,
        resourceQuery: { not: /url/ },
        use: ["@svgr/webpack"],
      }
    );

    fileLoaderRule.exclude = /\.svg$/i;

    return config;
  },
};

Just in case here my main-header.js and layout.js files:

import MainHeader from "../header/main-header.js";
import { Inter } from "@next/font/google";
import Footer from "../footer/footer";
import { useRouter } from "next/router";
import ErrorPage from "@/pages/404";
import { useState, useEffect } from "react";
import SquareLoader from "react-spinners/SquareLoader";

const inter = Inter({
  weight: ["300", "400", "500", "600", "700"],
  subsets: ["latin"],
});

const Layout = (props) => {
  const router = useRouter();
  const [pageLoading, setPageLoading] = useState(false);

  const storage = typeof window !== "undefined" ? window.localStorage.theme : "light";

  const override = {
    display: "block",
    margin: "0 auto",
    borderRadius: "3px",
    borderColor: "blue",
  };

  useEffect(() => {
    const handleStart = () => {
      setPageLoading(true);
    };
    const handleComplete = () => {
      setPageLoading(false);
    };

    router.events.on("routeChangeStart", handleStart);
    router.events.on("routeChangeComplete", handleComplete);
    router.events.on("routeChangeError", handleComplete);
  }, [router]);

  return router.pathname !== "/404" ? (
    <div
      className={`${inter.className} ${
        pageLoading ? "background__loading_theme" : "background-theme"
      }`}
    >
      <MainHeader />
      {pageLoading ? (
        <div className="loading-theme">
          <SquareLoader
            color={storage === "light" ? "#2b2b2b" : "#ffffff"}
            loading={pageLoading}
            cssOverride={override}
            size={70}
            aria-label="Loading Spinner"
            data-testid="loader"
          />
        </div>
      ) : (
        <main className="background">{props.children}</main>
      )}
      <Footer />
    </div>
  ) : (
    <div className={`${inter.className} error-theme`}>
      <ErrorPage />
    </div>
  );
};

export default Layout;


import Link from "next/link";
import { useState, useEffect } from "react";
import styles from "./main-header.module.css";
import menustyles from "./menu-icon.module.css";
import Image from "next/image";
import logo from "../../public/images/my-logo.png";
import logoDark from "../../public/images/my-logo-dark.png";
import SunIcon from "../../public/images/sun.svg";
import MoonIcon from "../../public/images/moon.svg";
import { useRouter } from "next/router";
import { useRef } from "react";
import MenuIcon from "./menu-icon";

const MainHeader = () => {
  const storage = typeof window !== "undefined" ? window.localStorage.theme : "light";
  const [themeMode, setThemeMode] = useState(storage);
  const [clientLoaded, setClientLoaded] = useState(false);

  const themeModeHandle = (e) => {
    e.preventDefault();
    setThemeMode((prev) => (prev === "dark" ? "light" : "dark"));
  };

  const navRef = useRef();
  const iconRef = useRef();
  const sunIconRef = useRef();

  const router = useRouter();

  const handleAnimation = () => {
    iconRef.current.classList.toggle(`${menustyles.openmenu}`);
  };

  const showNavbar = () => {
    navRef.current.classList.toggle(`${styles.responsive__nav}`);
    if (!sunIconRef.current.classList.contains(`${styles.responsive__icon}`)) {
      sunIconRef.current.classList.add(styles.responsive__icon);
    }
  };

  const closeNavbar = () => {
    navRef.current.classList.remove(`${styles.responsive__nav}`);
    if (iconRef.current.classList.contains(`${menustyles.openmenu}`)) {
      handleAnimation();
    }
    if (!sunIconRef.current.classList.contains(`${styles.responsive__icon}`)) {
      sunIconRef.current.classList.add(styles.responsive__icon);
    } else {
      sunIconRef.current.classList.remove(styles.responsive__icon);
    }
  };

  useEffect(() => {
    document.body.dataset.theme = themeMode;
    window.localStorage.setItem("theme", themeMode);
  }, [themeMode]);

  useEffect(() => {
    setClientLoaded(true);
  }, []);

  return (
    <header className={styles.header}>
      <div className={styles.header__main}>
        <div className={styles.header__menu}>
          <Link href="/">
            {(themeMode === "light" || themeMode === undefined) && clientLoaded ? (
              <Image
                src={logo}
                alt="website logo"
                className={styles.header__logo}
                priority={true}
              />
            ) : (
              <Image src={logoDark} alt="website logo" className={styles.header__logo} />
            )}
          </Link>
          <nav className={styles.navigation} ref={navRef}>
            <ul className={styles.navigation__ul}>
              <li
                onClick={closeNavbar}
                className={router.asPath === "/" ? `${styles.li__active}` : ""}
              >
                <Link href="/">Portfolio</Link>
              </li>
              <li
                onClick={closeNavbar}
                className={router.asPath === "/about" ? `${styles.li__active}` : ""}
              >
                <Link href="/about">About</Link>
              </li>
              <li
                onClick={closeNavbar}
                className={router.asPath === "/blog" ? `${styles.li__active}` : ""}
              >
                <Link href="/blog">Blog</Link>
              </li>
              <li
                onClick={closeNavbar}
                className={router.asPath === "/projects" ? `${styles.li__active}` : ""}
              >
                <Link href="/projects">Projects</Link>
              </li>
            </ul>
            <button className={styles.navigation__modalicons}>
              {themeMode === "light" && clientLoaded ? (
                <div ref={sunIconRef}>
                  <SunIcon
                    onClick={themeModeHandle}
                    className={`${styles.navigation__sun} ${styles.sun} `}
                  />
                </div>
              ) : (
                <div ref={sunIconRef}>
                  <MoonIcon
                    onClick={themeModeHandle}
                    className={`${styles.navigation__sun} ${styles.moon} `}
                  />
                </div>
              )}
            </button>
          </nav>
          <button
            className={styles.navigation__btn}
            onClick={showNavbar}
            aria-label="Button menu icon"
          >
            <MenuIcon animation={handleAnimation} ref={iconRef} />
          </button>
        </div>
        <button
          className={styles.navigation__icons}
          aria-label="Icon to change a theme of a website"
        >
          {themeMode === "light" && clientLoaded ? (
            <SunIcon
              onClick={themeModeHandle}
              className={`${styles.header__sun} ${styles.sun}`}
            />
          ) : (
            <MoonIcon
              onClick={themeModeHandle}
              className={`${styles.header__sun} ${styles.moon}`}
            />
          )}
        </button>
      </div>
    </header>
  );
};

export default MainHeader;

Solution

  • I found the problem was that some of my folders on github were named with capital letters. I must have named them with capital letters when I first uploaded the project and later changed it to lowercase locally. Since github isn't case sensitive to changes, they were never picked up until I tried to go into a production.

    Make sure to check your file names in your repository and local production.