Next.js app router 기반에서 msw(browser) 세팅하기(module not found 오류 해결)

HappyFrog·2023년 12월 8일
3

MSW 세팅에 관한 내용이므로 개념에 관한 부분은 설명하지 않고 넘어갑니다. 개념은 공식문서를 참고하거나 다른 레퍼런스를 참고해 주세요

개요

과거에 page route 시절 msw를 세팅 해본적이 있어, app router 기반에서도 유사하게 구성 해보았으나 잘 되지 않았다(정확히는 빌드과정 중에 module not found 에러가 지속적으로 발생 하였다)
결국 구글링 도중 msw github에 올라온 유사한 증상에 관한 이슈를 보고 문제를 해결 하게 되었다

문제 발생점

먼저 browser의 경우 client component에서 사용해주기 위해 다음과 같이 작성해 주었다.

"use client";
import { useEffect, useRef } from "react";

const Initializer = () => {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!ref.current) return;
    // browser 환경, client에서 사용하기 위한 worker 세팅
    async function setupWokrer() {
      if (typeof window === "undefined") {
        console.log("window is undefined");
        return;
      }
      const { worker } = await import("./mocks/browser");
      await worker.start();
      console.log("worker started");
    }
    setupWokrer();
  }, []);

  return <div ref={ref} />;
};

export default Initializer;

이렇게 만들어진 이니셜 라이저 컴포넌트를 root layout에서 import 시켜 주었다

// app > layout.tsx
// ... 상단 코드 생략

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body className={inter.className}>
        {children}
        <Initializer />
      </body>
    </html>
  );
}

하지만 빌드과정에서 지속적으로 module not found 에러가 발생하였다(즉, setupWokrer를 import 해주는 코드에서 지속적으로 에러가 발생하여 정상적으로 작동하지 않았다)

// mocks > browser.ts
"use client";
import { setupWorker } from "msw/browser"; // 문제가 발생 하였던 부분

export const worker = setupWorker();

에러사진

문제 발생 원인


위 사진에 적힌 내용처럼, msw 패키지에는 위와 같은 스니펫이 포함 되어 있다고 한다, 여기서 node의 경우에는 브라우저에서 호출 되지 않지만 문제는 웹팩의 빌드 타임때에는 상관없이 불러지면서 이때 module not found에러가 발생하는 문제였다.

문제 해결(webpack 수정)

위 글의 작성자는 친절하게도 문제에 대한 해결 방법도 올려 두었다

// next.config.js 파일
/** @type {import('next').NextConfig} */
const nextConfig = {
	webpack: (config, { isServer }) => {
    	if (isServer) {
          if (Array.isArray(config.resolve.alias))
            // server일시 browser를 제외 시킨다
            config.resolve.alias.push({ name: "msw/browser", alias: false });
          else config.resolve.alias["msw/browser"] = false;
        } else {
          if (Array.isArray(config.resolve.alias))
            config.resolve.alias.push({ name: "msw/node", alias: false });
          else config.resolve.alias["msw/node"] = false;
        }
        return config;
    }
}

module.exports = nextConfig;

해당 코드를 next.config.js 파일에 적용 시킨 후 재실행 시켜 아래 사진처럼 module not found에러를 해결 하고 세팅을 진행 할 수 있었다

레퍼런스

https://github.com/mswjs/msw/issues/1801

profile
성장하고 싶은 긍정 개구리

0개의 댓글