MSW가 2.0으로 바뀌고 문서가 너무 없었다.
서론
Next.js도 처음이고 MSW도 처음이라 더 어려웠습니다.
다른 블로그를 따라서 적용하니 CSR로 api 요청을 보냈을 때 msw가 로딩되기 전에 api요청이 끝나서 404에러가 발생했습니다.
pages router + msw2를 사용하는 경우의 해결책을 찾을 수 없었습니다.
app router+ msw2를 사용하거나 pages router + msw1을 사용하는 경우들 뿐이었습니다.
틈틈히 삽질한 결과 해결책을 찾게되어 글을 쓰게 되었습니다.
설정 방법
먼저 Next.js는 CSR도 하고 SSR도 하기 때문에
브라우저측 서버측 모두 설정이 필요합니다.
// /mocks/browser.js
import { setupWorker } from "msw/browser";
import { handlers } from "./handlers";
export const worker = setupWorker(...handlers);
// /mocks/browser.js
import { setupWorker } from "msw/browser";
import { handlers } from "./handlers";
export const worker = setupWorker(...handlers);
가짜 응답을 작성할 handlers.ts를 작성합니다.
// /mocks/handlers.ts
import { http, HttpResponse } from "msw";
export const handlers = [
http.get("/hello", () => {
return HttpResponse.json(
{ text: "hello" },
{
status: 200,
}
);
}),
];
브라우저인지 서버인지 구분하는 코드를 작성합니다.
이 부분을 다르게 작성해서 고생을 했는데요
msw1까지는 woker를 return하지 않아도 잘 작동이 되었었나 봅니다.
다른 블로그의 코드를 보면 return문 없이 함수만 호출합니다.
하지만 msw2 공식문서를 따르면 return까지 해줘야합니다.
// /mocks/index.ts
async function initMSW() {
if (typeof window === "undefined") {
const { server } = await import("./server");
return server.listen();
} else {
const { worker } = await import("./browser");
return worker.start();
}
}
export { initMSW };
msw가 준비되기 전까지 렌더링을 지연시키기 위해서 MSWProvider를 작성합니다.
// /mocks/MSWProvider
import { initMSW } from "@/mocks";
import { useEffect, useState } from "react";
function MSWProvider({ children }: { children: React.ReactNode }) {
const mockingEnabled = !!process.env.NEXT_PUBLIC_API_MOCKING;
const [shouldRender, setShouldRender] = useState(!mockingEnabled);
useEffect(() => {
if (mockingEnabled) {
import("../mocks").then(async ({ initMSW }) => {
await initMSW();
setShouldRender(true);
});
}
}, []);
return shouldRender ? <>{children}</> : <>MSW 로딩중...</>;
}
export default MSWProvider;
그리고 _app.tsx에 다음과 같이 MSWProvider를 추가해주면 됩니다.
// pages/_app.tsx
import "@/styles/globals.css";
import type { AppProps } from "next/app";
import MSWProvider from "../mocks/MSWProvider";
export default function App({ Component, pageProps }: AppProps) {
return (
<MSWProvider>
<Component {...pageProps} />
</MSWProvider>
);
}
마지막으로 아래 명령어를 입력해줍니다.
npx msw init ./public
경로는 꼭 public 디렉토리여야합니다.(공식문서에서 그렇게 알려줬기 때문입니다.)
개발자도구의 콘솔에서 Mocking enabled. 라고 뜨면 성공입니다.
이해를 돕기 위해 Next.js에 MSW2를 적용한 깃허브 링크도 첨부하도록 하겠습니다.
https://github.com/HiBixby/msw-nextjs-pages-router
MSW가 2.0으로 바뀌고 문서가 너무 없었다.
서론
Next.js도 처음이고 MSW도 처음이라 더 어려웠습니다.
다른 블로그를 따라서 적용하니 CSR로 api 요청을 보냈을 때 msw가 로딩되기 전에 api요청이 끝나서 404에러가 발생했습니다.
pages router + msw2를 사용하는 경우의 해결책을 찾을 수 없었습니다.
app router+ msw2를 사용하거나 pages router + msw1을 사용하는 경우들 뿐이었습니다.
틈틈히 삽질한 결과 해결책을 찾게되어 글을 쓰게 되었습니다.
설정 방법
먼저 Next.js는 CSR도 하고 SSR도 하기 때문에
브라우저측 서버측 모두 설정이 필요합니다.
// /mocks/browser.js import { setupWorker } from "msw/browser"; import { handlers } from "./handlers"; export const worker = setupWorker(...handlers);
// /mocks/browser.js import { setupWorker } from "msw/browser"; import { handlers } from "./handlers"; export const worker = setupWorker(...handlers);
가짜 응답을 작성할 handlers.ts를 작성합니다.
// /mocks/handlers.ts import { http, HttpResponse } from "msw"; export const handlers = [ http.get("/hello", () => { return HttpResponse.json( { text: "hello" }, { status: 200, } ); }), ];
브라우저인지 서버인지 구분하는 코드를 작성합니다.
이 부분을 다르게 작성해서 고생을 했는데요
msw1까지는 woker를 return하지 않아도 잘 작동이 되었었나 봅니다.
다른 블로그의 코드를 보면 return문 없이 함수만 호출합니다.
하지만 msw2 공식문서를 따르면 return까지 해줘야합니다.
// /mocks/index.ts async function initMSW() { if (typeof window === "undefined") { const { server } = await import("./server"); return server.listen(); } else { const { worker } = await import("./browser"); return worker.start(); } } export { initMSW };
msw가 준비되기 전까지 렌더링을 지연시키기 위해서 MSWProvider를 작성합니다.
// /mocks/MSWProvider import { initMSW } from "@/mocks"; import { useEffect, useState } from "react"; function MSWProvider({ children }: { children: React.ReactNode }) { const mockingEnabled = !!process.env.NEXT_PUBLIC_API_MOCKING; const [shouldRender, setShouldRender] = useState(!mockingEnabled); useEffect(() => { if (mockingEnabled) { import("../mocks").then(async ({ initMSW }) => { await initMSW(); setShouldRender(true); }); } }, []); return shouldRender ? <>{children}</> : <>MSW 로딩중...</>; } export default MSWProvider;
그리고 _app.tsx에 다음과 같이 MSWProvider를 추가해주면 됩니다.
// pages/_app.tsx import "@/styles/globals.css"; import type { AppProps } from "next/app"; import MSWProvider from "../mocks/MSWProvider"; export default function App({ Component, pageProps }: AppProps) { return ( <MSWProvider> <Component {...pageProps} /> </MSWProvider> ); }
마지막으로 아래 명령어를 입력해줍니다.
npx msw init ./public
경로는 꼭 public 디렉토리여야합니다.(공식문서에서 그렇게 알려줬기 때문입니다.)
개발자도구의 콘솔에서 Mocking enabled. 라고 뜨면 성공입니다.
이해를 돕기 위해 Next.js에 MSW2를 적용한 깃허브 링크도 첨부하도록 하겠습니다.
https://github.com/HiBixby/msw-nextjs-pages-router