Next.js에서 MSW 세팅하기

Doeunnkimm·2023년 10월 12일
4

Next

목록 보기
3/3
post-thumbnail

🍎 저는 지금 이런 환경인데요!

Next.js App router, 컴파일 옵션은 es5(기본으로 세팅되어 있는) 환경 입니다.

🫨 일단 Setup 하기

1. msw install

$ yarn add -D msw

2. mocks 폴더에 mock api 만들어주기

// @/mocks/apis/study.apis.ts

import { rest } from 'msw'

const getCreatedStudyList = rest.get('/api/study', (_, res, ctx) => {
  return res(ctx.status(200), ctx.json({ message: 'success!!' }))
})

3. handlers 만들어주기

// @/mocks/handlers.ts

import * as apis from './apis'

export const handlers = [...Object.values(apis)]

4. worker에 handlers 등록하기

// @/mocks/browser.ts

import { setupWorker } from 'msw'
import { handlers } from './handlers'

export const worker = setupWorker(...handlers)

5. server에 handlers 등록하기

api 테스트 코드 작성 예정이기에 미리 세팅했습니다.

// @/mocks/server.ts

import { setupServer } from 'msw/node'
import { handlers } from './handlers'

export const server = setupServer(...handlers)

6. 초기화 함수 만들기

브라우저 환경에서 동작하는지, 서버 환경에서 동작하는지에 따라 다른 인스턴스를 실행합니다.

// @/mocks/index.ts

const initMocks = async () => {
  const isServer = typeof window === 'undefined'

  if (isServer) {
    const { server } = await require('./server')
    server.listen({ onUnhandledRequest: 'bypass' }) // 처리되지 않은 요청이라도 통과시키도록
  } else {
    const { worker } = await require('./browser')
    worker.start({ onUnhandledRequest: 'bypass' }) // 처리되지 않은 요청이라도 통과시키도록
  }
}
export default initMocks

❓ 처리되지 않은 요청이라도 통과?

  • 모든 api를 mock으로 하지 않았더라도 (일부는 실제 api일 수 있기 때문) server/worker가 통과시키도록 합니다.

7. providers(클라이언트 사이드) 파일에서 초기화 함수 실행

환경에 따라 설정을 다르게 해줄 수 있도록 env를 이용했습니다.

env파일에서 바로 enable/disable 해줌에 따라 msw를 구동할 수도 하지 않을 수도 있습니다.

// @/app/providers.tsx

'use client'

import initMocks from '@/mocks'
import { PropsWithChildren } from 'react'

if (process.env.NEXT_PUBLIC_API_MOCKING === 'enable') {
  initMocks()
}

const Providers = ({ children }: PropsWithChildren) => {
  return <div>{children}</div>
}

export default Providers
// env

NEXT_PUBLICK_API_MOCKING='enable'

8. msw init 해주기

$ npx msw init public/

잘 동작하는 것을 확인할 수 있었습니다 👍

📺 Next.js는 서버 사이드에서, MSW는 클라이언트 사이드에서 동작한다 원래..

Next.js는 서버 사이드에서 렌딩하기 때문에 브라우저의 Service Worker API를 사용하여 네트워크 요청을 가로채고 모의 응답을 제공하는 msw는 서버 사이드에서 제대로 초기화되지 못합니다.

✨ 따라서 Next.js에서는 클라이언트 사이드 컴포넌트에서 초기화되어야 합니다.

그런 이유 때문에 use client 되어 있는 providers 파일에서 init을 했던 겁니다 :)


이번 디버깅 과정을 통해서 브라우저에서 초기화되어야만 하는 특성이 존재함을 알게 되었고, 이를 Next.js에서 반영해주기 위해서는 어떻게 해야하는지를 알게 되었습니다 🙌

그리고 기존에 msw를 세팅할 때 development 환경에서는 msw가 구동되도록 했었습니다. 그래도 개발 환경 중 실제 api의 반영을 확인해야 하는 순간들이 존재합니다. 그럴 때 주석을 했다 풀었다하며 변경 사항이 발생하던 불편함이 있었는데요. 이를 env에서 설정하는 방법 덕분에 해소할 수 있었습니다 😉

app.tsx 파일에서 주석 추가했다가 제거했다가 커밋 내역에는 포함되지 않도록 하려고 신경쓰고 했던 기억이 새록새록하네요 🤔

profile
개발자와 사용자 모두의 눈👀을 즐겁게 하는 개발자가 되고 싶어요 :) 👩🏻‍💻

0개의 댓글