msw 와 nextjs 연결을 위해 msw 공식 문서로 설정을 완료 했다.
하지만, 오류가 발생했다. 이미 유명한 오류였다. (해당 이슈)
nextjs 서버 사이드에서 msw 모킹 불가 문제로 이해했다.
서버사이드 프로세스에 server.listen() 실행이 문제다.
두가지 방법이 issue 에 있다.
나는 두번째 방법으로 해결했다.
먼저 msw 공식문서 설정을 해야한다. msw 문서 (node 와 browser 모두해줘야함)
next config 파일에 필드를 설정한다.
// next.config.mjs
const nextConfig = {
experimental: {
instrumentationHook: true,
},
};
export default nextConfig;
app 폴더 라인에 instrumentation.ts 파일을 추가한다.
// src/instrumentation.ts
// app 폴더와 같은 위치에 정의되어야한다.
// nextjs 서버에서 instrumentation 기능을 이용하여 server 를 한번 실행시킨다.
export async function register() {
console.log(
'[instrumentation] server.listen()...',
process.env.NEXT_RUNTIME,
typeof window,
);
if (process.env.NEXT_RUNTIME === 'nodejs') {
const { server } = await import('@/src/mocks/node'); // setupServer 로 정의한 인스턴스
server.listen({
onUnhandledRequest: 'bypass',
});
}
}
initMsw.ts 에 worker 를 실행시키기위한 함수를 정의한다.
// src/mocks/initMsw.ts
export const initMsw = async () => {
if (process.env.NEXT_RUNTIME !== 'nodejs') { // 브라우저 환경에서만 worker 를 실행시킨다.
const { worker } = await import('./browser');
await worker.start({
onUnhandledRequest: 'bypass',
});
}
};
initMsw 함수 로 worker 가 실행 완료후 하위 컴포넌트를 렌더링시킨다.
// 정의한 initMsw를 실행시킨다.
'use client';
import { useEffect, useState } from 'react';
import { initMsw } from '@/src/mocks/initMsw';
export const MSWComponent = ({ children }: { children: React.ReactNode }) => {
const [isInit, isSetInit] = useState(false);
useEffect(() => {
if (!isInit) {
initMsw().then(() => isSetInit(true));
}
}, [isInit]);
if (!isInit) {
return null;
}
// worker 가 실행 완료되면 하위 컴포넌트들을 실행시킨다.
return <>{children}</>;
};
<MSWComponent>
{children}
</MSWComponent>