[Next.js] Next 15에 MSW(Mock Service Worker) 세팅하기

2025. 8. 21. 20:26·Next.js
반응형

 

1. MSW란?

MSW(Mock Service Worker)는 API를 흉내 내는(mocking) 라이브러리이다.

Service Worker를 활용해서 네트워크 요청을 가로채고 응답을 가짜로 돌려준다.

MSW를 쓰면 백엔드 API가 준비되지 않은 상태에서도 프론트엔드에서 미리 개발이 가능하다.

 

MSW 공식문서를 보면서 따라해보자!

다만 Next.js에서는 MSW가 완벽하게 연동되지 않는다.

SSR Fetch를 위해 추가적으로 작성해줘야 하는 코드가 있다.

MSW에서 제공하는 Next.js + MSW 예제가 있는데 이거랑 Next.js(MSW 포함) 강의 들었던 거랑 다 참고해서 세팅했다.

 

2. 패키지 설치

일단 msw 패키지부터 설치한다.

npm i msw --save-dev

 

3. 클라이언트 환경(브라우저) 설정

mocks 폴더 아래에 handlers.ts, browser.ts, server.ts 세 파일을 만든다.

만약 SSR까지 mocking 할 필요는 없고 클라이언트 사이드 요청만 mocking 할 거면 server.ts는 안 만들어도 된다.

handlers.ts
: 어떤 요청에 어떤 응답을 줄지 작성
import { http, HttpResponse } from 'msw';

const baseUrl = process.env.NEXT_PUBLIC_BASE_URL;

export const handlers = [
  http.get(`${baseUrl}/user`, () => {
    return HttpResponse.json({
      id: 'abc-123',
      firstName: 'John',
      lastName: 'Maverick',
    });
  }),
];

 

browser.ts
import { setupWorker } from 'msw/browser';
import { handlers } from './handlers';

const worker = setupWorker(...handlers);

export default worker;

 

server.ts
import { setupServer } from 'msw/node';
import { handlers } from './handlers';

export const server = setupServer(...handlers);

 

4. msw-provider

Next.js App Router에서는 클라이언트에서 워커가 시작되기 전까지 Suspense로 기다려야 하기 때문에 Provider를 만들어야 된다.

즉, Provider는 워커 준비가 끝난 뒤에만 children을 렌더링 하도록 보장하는 역할이다.

 

강의에서는 mockingEnabledPromise의 import.meta.hot?.dispose(() => {...}) 이 부분이 (module as any).hot?.dispose(() => {...})였다.

any가 있으면 빌드가 안 돼서 지피티한테 물어봐서 아래 코드로 바꾸긴 했는데.. 타입만 추가로 선언한 거라 괜찮겠지?ㅠ

지피티 말로는 Turbopack 환경에서 import.meta.hot, Webpack 환경에서 import.meta.webpackHot이라는데 내 dev 환경은 Turbopack인데도 둘 다 됐다 음.. 하나만 넣어도 되는 건가 기존 강의 코드에서도 hot으로 되어 있었기 때문에 그냥 hot만 넣어뒀다.

 

공식 예제코드엔 없던 코드인데 HMR(핫 리로드) 시에 MSW 워커를 정리(stop)해서 핸들러가 중복 등록되거나 이미 워커가 떠 있는 이상 동작을 막는 역할인 것 같다.

'use client';

import { Suspense, use } from 'react';
import { handlers } from '@/mocks/handlers';

declare global {
  interface ImportMeta {
    hot?: { dispose(cb: () => void): void };
  }
}

const mockingEnabledPromise =
  typeof window !== 'undefined'
    ? import('@/mocks/browser').then(async ({ default: worker }) => {
        if (process.env.NODE_ENV === 'production') {
          return;
        }
        await worker.start({
          onUnhandledRequest(request, print) {
            if (request.url.includes('_next')) {
              return;
            }
            print.warning();
          },
        });
        worker.use(...handlers);

        import.meta.hot?.dispose(() => {
          worker.stop();
        });
        console.log(worker.listHandlers());
      })
    : Promise.resolve();

export const MSWProvider = ({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) => {
  // If MSW is enabled, we need to wait for the worker to start,
  // so we wrap the children in a Suspense boundary until it's ready.
  return (
    <Suspense fallback={null}>
      <MSWProviderWrapper>{children}</MSWProviderWrapper>
    </Suspense>
  );
};

const MSWProviderWrapper = ({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) => {
  use(mockingEnabledPromise);
  return children;
};

 

5. 서버 환경(Node.js/SSR) 설정

app 폴더 안의 layout.tsx 파일을 수정한다.

  • MSWProvider를 import 해서 children을 감싼다.
  • server-side MSW integration을 위한 instrumentation hook을 추가한다.

서버 환경에서는 Service Worker가 없으므로 Node.js 환경에서 요청을 가로채는 setupServer()를 따로 실행해야 한다. (2번에서 만든 server.ts)

SSR 단계에서 발생하는 fetch 요청까지 가로채기 위함이다.

import type { Metadata } from 'next';
import localFont from 'next/font/local';
import './globals.css';
import { MSWProvider } from '@/app/providers/msw-provider';

if (process.env.NEXT_RUNTIME === 'nodejs' && process.env.NODE_ENV !== 'production') {
  const { server } = await import('@/mocks/server');
  server.listen();
}

export const metadata: Metadata = {
  title: "Create Next App",
  description: "Generated by create next app",
};

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

 

여기까지 하면 CSR(클라이언트) / SSR(서버) 모두 지원하는 MSW 준비가 완료되었다..!

이제 핸들러에 원하는 요청/응답을 추가해서 사용하면 된다.

반응형

'Next.js' 카테고리의 다른 글

[Next.js] Next에서 svg 사용하기  (0) 2024.10.22
[Next.js] Page Router 총정리  (0) 2024.09.23
[Next.js] Page Router - 페이지 라우팅 설정  (0) 2024.09.11
'Next.js' 카테고리의 다른 글
  • [Next.js] Next에서 svg 사용하기
  • [Next.js] Page Router 총정리
  • [Next.js] Page Router - 페이지 라우팅 설정
올콩
올콩
콩 심은 데 콩 난다
  • 올콩
    콩스토리
    올콩
  • 전체
    오늘
    어제
    • 분류 전체보기 (196) N
      • SSAFY (10)
      • Algorithm (114) N
        • 이론 (6)
        • 백준 (BOJ) (107) N
        • 프로그래머스 (1)
      • Trouble Shooting (9)
      • Frontend (6)
      • React (17)
      • Next.js (4)
      • Vue (4)
      • Node.js (2)
      • HTML (9)
      • DevOps (4)
        • Git (4)
      • Language (9)
        • JavaScript (0)
        • Java (9)
      • Embedded (1)
      • CS (5)
        • Network (1)
        • Blockchain (4)
      • 자격증 (2)
  • 블로그 메뉴

    • GitHub
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    구현
    알고리즘
    파이썬
    bfs
    재귀
    React
    DP
    브루트포스
    백준
    순열
    중복순열
    싸피
    Error
    Algorithm
    Heap
    중복조합
    백트래킹
    강의
    Java
    오블완
    티스토리챌린지
    우선순위큐
    dfs
    SSAFY
    Next.js
    수학
    힙
    SSAFYcial
    블록체인
    html5
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
올콩
[Next.js] Next 15에 MSW(Mock Service Worker) 세팅하기
상단으로

티스토리툴바