My future is created by what I do today, not tomorrow.
Projects
(약간은 험난했던) Next.js 13에 MSW 도입기
Millie2023. 8. 21. 14:08
1. MSW 도입 배경
Next.js 13버전으로 진행 중인 프로젝트에 MSW를 도입하고 싶다는 생각이 들었다.
나는 다른 React 프로젝트에서 MSW를 도입해 유용하게 활용한 적이 있다. 백엔드 팀원들과 함께 API 스펙에 대해서 논의가 끝났는데 아직 구현이 덜 되어 API를 프론트 측에서 사용할 수 없는 상황이라면, 마냥 기다리기엔 시간이 아깝다. 바로 이 때 API를 Mocking한다면, 프론트에서도 기능/UI 구현 작업을 이어나갈 수 있다. 추후 API가 개발된다면, 자연스럽게 실제 API로 대체하면 된다.
또현 현재 나의 프로젝트에는 OAuth 로그인을 도입한 상태다. 로그인 후에는 서버로부터 쿠키를 통해 access token이 발급되는데, 추후 API 요청을 할 때 이 access token을 함께 Request Header에 실어서 보내야 한다.
그런데 개발 환경인 localhost:3000 에서는 실제 도메인과 다르기 때문에, access token을 받을 수가 없다. 그렇기 때문에 추후 API 요청에서도 access token을 실어서 보낼 수가 없다.
그렇다면 이러한 API 요청이 포함된 컴포넌트를 개발할 때마다, Next.js 앱을 실제 도메인에 배포해서 구현이 잘 되었는지 확인을 해야 한다는 것인데, 이는 다음과 같은 문제점이 있다.
이 방식은 번거롭기도 하고, 결과물을 확인하기까지 시간이 소요된다. 커밋을 하고, 푸시를 하고, 빌드를 기다려야 하는데 최소 2분에서 길면 3~4분까지 소요가 된다.
막상 결과물을 확인했더니 로컬에서 확인하지 못했던 에러가 발생하는 경우가 있다. 이럴 경우에는 커밋을 reset해서 다시 과거 상태로 돌리고 작업을 하게 되는데 이는 굉장히 비효율적이다.
이러한 불편함과 비효율을 없애 로컬 작업 환경을 쾌적하게 만들기 위해 MSW를 도입하고 싶었다.
그런데 Next.js 13 버전, 그리고 app router를 쓰는 환경에서는 MSW를 도입하는 것이 약간 난관이었는데, 내가 마주한 문제점과 해결책을 정리해 보았다.
이 문제를 해결하는 데 일등 공인은 코드스쿼드 부트캠프의 같은 기수 수료생인 콜라이다. 콜라는 이미 다른 프로젝트에서 이 문제를 해결해 본 경험이 있었고, 나에게 아주 자세하고 친절하게 설명해 주셔서 정말 감사했다.(감사의 의미로 기프티콘을 보내드렸다☕️) 콜라와 이야기를 나누는 과정에서 배운 것이 많아 휘발되지 않도록 그 과정을 정리하고 기록해 보았다.
2. MSW의 동작 방식
본격적으로 MSW를 설정하기 전, MSW가 무엇이고 어떤 방식으로 동작하는지 간략하게만 짚고 넘어가보자.
MSW는 무엇이고, 하는 주된 일은 무엇인가?
MSW는 Mock Service Worker. Mock은 ‘모의’, ‘모조’, ‘가짜’ 라는 뜻이다.
이름 안에 Service Worker가 있는 것처럼, Web에서 제공하는 Service Worker API를 사용해서 HTTP 요청을 가로챈다.
Service Worker: 웹 애플리케이션의 메인 스레드와 분리된 별도의 백그라운드 스레드에서 실행시킬 수 있는 기술. 이를 통해 애플리케이션의 UI Block 없이 연산 처리를 할 수 있다. Service Worker를 통해 네트워크 요청이나 응답을 가로채 조작할 수 있게 된다.
MSW는 실제 API 요청이 발생하면, 이 요청을 가로채서 미리 준비해 뒀던 Mock data로 응답해준다.
MSW를 사용하면 Mock Server를 따로 구축하지 않아도 API를 Mocking할 수 있어서 효율성이 증대된다.
Mock Service Worker의 request 흐름
아래 도식은 Mock Service Worker의 request가 어떤 식으로 흘러가는지 큰 그림으로 표현한 것이다. 공식문서를 참조했다.
브라우저에서 요청을 보낸다.
Service Worker는 요청을 받고, 해당 요청을 복제한다. 복제한 요청을 MSW에게 보낸다.
MSW는 요청과 일치하는 목업을 생성한다.
MSW가 모킹한 응답을 Service Worker에게 보낸다.
Service Worker가 모킹된 응답을 브라우저에게 보내고, 브라우저가 최종적으로 이 응답을 받는다.
3. MSW 세팅 과정
MSW가 어떤 흐름으로 Mocking을 해 주는 것인지 파악했으니, 이제 본격적으로 프로젝트에 세팅을 할 차례다.
/api/checklist/today로 API를 요청하게 되면, { isTodayChecklistCreated: true } 라는 json을 반환하도록 getTodayChecklist 함수를 구현했다.
3. worker를 설정해준다.
// src/mocks/browser.jsimport { setupWorker } from'msw'import { handlers } from'./handlers'// This configures a Service Worker with the given request handlers.exportconst worker = setupWorker(...handlers)
카카오에서 MSW를 왜 도입했는지가 자세히 언급되고 있다. MSW를 사용하지 않고 Mocking을 했을 때 어떤 어려움을 겪었는지, MSW는 그 문제를 어떻게 해결해 주었는지가 나와 있다. 특히 MSW를 사용해서 현업에서 개발 과정이 어떻게 달라졌는지 상세히 풀어 쓰여져 있는 부분이 좋았다.