작업에 사용될 파일 구조
1. MSW 설치
npm i -D msw@1.3.2
[Usage] npx msw init <PUBLIC_DIR> [options]
npx msw init public
public 폴더 아래 mockServiceWorker.js 파일이 생성된 것을 확인
package.json 에 msw workinDirectory 세팅 된 것을 확인
"msw": {
"workerDirectory": "public"
}
2. MSW 구동 세팅
1. fake api/data 세팅
- api/mocks/fake-api/search-api.ts
import { rest } from "msw";
import { validData } from "../fake-data/search-data";
// GET method인 /get-names를 호출하면 다음과 같이 response가 되도록 mocking 정의
const getSearchProducts = () => rest.get("/get-names", (req, res, ctx) => res(ctx.status(200), ctx.json(validData)));
const searchHandlers = [getSearchProducts()];
export default searchHandlers;
- api/mocks/fake-data/search-data.ts
// 검색 결과 있는 경우
export const validData = {
searchedProducts: [
{
id: 0,
name: "test product 1",
imgSrc: "test_img.png",
price: 650,
stockState: "Out of Stock",
},
{
id: 1,
name: "test product 2",
imgSrc: "test_img.png",
price: 650,
stockState: "Out of Stock",
},
{
id: 2,
name: "test product 3",
imgSrc: "test_img.png",
price: 650,
stockState: "Out of Stock",
},
{
id: 3,
name: "test product 4",
imgSrc: "test_img.png",
price: 650,
stockState: "Out of Stock",
},
],
};
2. 통합 handlers.ts 세팅
- api/mocks/handlers.ts
import searchHandlers from "./fake-api/search-api";
export const handlers = [...Object.values(searchHandlers)];
다른 fake-api 들도 추가되는대로 나열하여 작성
3. browser 에서 API mocking 실행 스크립트 작성
- api/mocks/browser.ts
import { setupWorker } from "msw";
import { handlers } from "./handlers";
export const worker = setupWorker(...handlers);
4. server 에서 API mocking 실행 스크립트 작성
- api/mocks/server.ts
import { setupServer } from "msw/node";
import { handlers } from "./handlers";
export const server = setupServer(...handlers);
5. 초기화 시점에 따라 brower / server 스크립트 실행
- api/mocks/index.ts
export async function initMSW() {
if (typeof window === "undefined") {
const { server } = await import("./server");
server.listen({
onUnhandledRequest: "bypass",
});
} else {
const { worker } = await import("./browser");
worker.start({
onUnhandledRequest: "bypass",
});
}
}
6. 클라이언트 단에서만 mocking 을 하기 위한 MswProvider 컴포넌트 작성
- components/provider/MswProvider.tsx
"use client";
import { useState, type PropsWithChildren, useEffect } from "react";
const isDev = process.env.NODE_ENV === "development";
interface Props {}
export default function MswProvider({ children }: PropsWithChildren<Props>) {
const [ready, setReady] = useState(false);
const init = async () => {
if (isDev) {
const initMock = await import("@/api/mocks/index");
await initMock.initMSW();
setReady(() => true);
}
};
useEffect(() => {
if (ready) return;
init();
}, [ready]);
if (!isDev) return null;
return <>{children}</>;
}
- .env 에 NODE_ENV 세팅
NODE_ENV=development
7. 루트 layout 에서 mocking 스크립트 실행
- app/layout.tsx
import MswProvider from "@/components/provider/MswProvider";
export default async function RootLayout({
children,
params,
}) {
return (
<html lang={lang}>
<body className={fontClassName}>
<MswProvider>
<ReactQueryProvider>
<NextIntlClientProvider locale={lang} messages={dict}>
<Header />
<div id="main-contents">{children}</div>
<Footer lang={lang} />
</NextIntlClientProvider>
</ReactQueryProvider>
</MswProvider>
</body>
</html>
);
}
8. 실제 api 호출 테스트
- components/searchModal.tsx
// 검색 API 호출
const { isLoading, error, data } = useQuery({
queryKey: ["search", inputValue],
queryFn: () => getSearchProducts(inputValue),
enabled: !!inputValue,
});
- api/search.ts
// GET order summary 가져오기
export const getSearchProducts = async (query: string) => {
const res = await fetch(`/get-names`);
const json = await res.json();
return json;
};
Network 탭에서 데이터 확인
mocking 할 데이터를 수정하는 경우에 브라우저 새로고침 해주어야 함!
'programming > React' 카테고리의 다른 글
Next.js 에서 Client Side Fetch 를 React-Query + 기본 Fetch 조합으로 사용하기 (0) | 2024.05.29 |
---|---|
Next.js 의 Fast Refresh 는 하나의 브라우저 세션과만 동작한다 (0) | 2024.05.24 |
리액트 에러 바운더리를 사용하여 에러 핸들링하기 (+ react-query) (0) | 2024.02.05 |
[immer] Array for문 돌리면서 연속적인 setState 안되는 이슈 (0) | 2024.01.03 |
[React Custom Hook] 수동으로 새로고침한 경우에만 특정 함수를 trigger 시키는 hook(url Params 삭제) (useDeleteUrlParamsWhenManualRefresh) (0) | 2024.01.03 |