본문 바로가기

React/실험실

[React] MSW

프론트엔드 개발을 하다보면 API를 사용하는 경우가 당연히 있다. 

로그인 처리, 게시글 목록 등등 아주 다양하게 당연하게 필요하다. 

 

이것을 가져와서 연동하는 작업을 수행하기 위해서 따로 모킹 서버를 만들어줄 수 있지만,

아주 번거로운 작업이다. 

 

이것을 Mock Service Worker를 통해서 해결할 수 있다. 

 

어떤 방법으로? 

풀 네임 그대로 Service Worker를 사용해서 기능을 제공한다. 

 

간략하게 Service Worker에 대해서 설명하자면, 일종의 대리 서버로 리소스 요청을 가로채 

수정을 할 수 있고, 리소스를 세부적으로 캐싱해 조작할 수 있다. 

이것을 활용해서 네트워크를 사용하지 못하는 환경에서도 어떤 방식으로 동작하는지 조작이 가능하다

https://www.simicart.com/blog/pwa-service-worker/

MSW도 Service Worker와 비슷하게 동작한다. 

https://mswjs.io/docs/

브라우저가 request를 보내면 Service Worker가 가로챈 뒤 msw를 통해서 모킹된 response를 

브라우저에게 보내준다. 

 

원래라면 실제 API 서버에서 데이터를 받아야 하지만 msw 를 사용해서 요청을 가로채 

임의의 데이터를 응답해줄 수 있다. 

 

axios-mock-adapter 와의 차이점은?

mocking을 할 때 언급 되는 것 중 하나가 axios-mock-adapter가 있다. 

 

이것과 msw의 차이점은 " 실제 사용자처럼 사용할 수 있냐 없냐 " 가 있다. 

 

실제 사용자와 같은 방식이란. 

query, body, params 등에 따라 msw는 처리 및 오류 처리 등이 가능하다. 

그러므로 추후 서버 API가 완료되어 연동할 때 코드를 따로 변경할 필요가 없다는 장점이 있다.

 

사용해보기! 

작업하는 환경은 React Query를 사용한 환경에서 그대로 진행할 것이다. 

 

npm install --save-dev msw

 추가로 msw를 개발 모듈에 설치해준다. 

 

src 폴더 안에 mocks 폴더를 만들어주고 내부에 browser.js와 handlers.js를 만들어준다. 

서비스 워커 코드 생성 

msw는 브라우저에서 서비스 워커를 통해서 작동하기 때문에 서비스 워커 등록을 위해서는 

기본적인 코드가 필요하다. 

 

이것을 직접 작성할 필요 없이 msw에서 제공하는 cli 도구를 사용하면 쉽게 만들 수 있다. 

npx msw init [ 정적 리소스 폴더 ] --save

정적 리소스 폴더는 일반적으로 public 폴더이기 때문에 public/ 을 넣어주면 된다. 

 

서비스 워커 핸들러 작성

// handler.js

import { rest } from "msw";

const userInfo = { name: "잉여", age: "369", job: "fish" };

const handlers = [
  rest.get("/users/check", async (req, res, ctx) => {
    const { user } = req.cookies;

    console.log(user);

    if (user) return res(ctx.status(201), ctx.json(userInfo));
    else return res(ctx.status(400));
  }),
];

export default handlers;

 

rest를 사용해서 get 또는 post를 선택하고 첫 번째 매개변수는 요청한 url이 된다. 

해당 url로 요청을 보내면 msw가 가로채서 내부 로직을 수행한다. 

 

req와 res는 각각 request와 response를 뜻하고 ctx를 통해서 상태, json 등 데이터를

보낼 수 있다. 

 

cookies 부분이 나와서 하는 이야기지만 msw의 cookie는 브라우저의 애플리케이션에 있는

cookie가 아닌 msw로 cookies를 넘겨줘야지 사용할 수 있다. 

실제 브라우저에 쿠키 데이터가 있어도 msw에서는 해당 쿠키를 확인할 수 없다. 

msw에서 만든 쿠키여야지 확인이 가능하다. 

 

쿠키를 보내는 방법으로는 

res(ctx.status(200), ctx.cookie("user", "test!@"));

다음과 같이 ctx의 cookie 함수를 사용해서 지정해줄 수 있다. 

 

서비스 워커 생성

// browser.js

import { setupWorker } from "msw";
import handlers from "./handlers";

export const worker = setupWorker(...handlers);

browser에서는 서비스 워커를 생성한다. 

setWorker 함수를 사용해서 서비스 워커를 생성하고 인자로 앞서 만든 핸들러를 불러와 넘겨준다. 

 

서비스 워커 실행

// index.js

// ...

if (process.env.NODE_ENV === "development") {
  const { worker } = require("./mocks/browser");

  worker.start();
}

// ...

const root = ReactDOM.createRoot(document.getElementById("root"));

// ...

선택적으로 서비스 워커가 실행되야 하므로 NODE_ENV를 비교해서 개발자 모드에서만 실행한다. 

 

여기까지 작성했으면 애플리케이션을 구동 후 콘솔을 확인했을 때 활성화 메세지가 출력될 것이다. 

그러면 완료이다!

반응형