인프런 영문 브랜드 로고
인프런 영문 브랜드 로고

인프런 커뮤니티 질문&답변

강주호님의 프로필 이미지

작성한 질문수

Next + React Query로 SNS 서비스 만들기

next용 msw 컴포넌트

msw ssr 관련 질문입니다.

작성

·

63

0

안녕하세요 제로초님


next 15버전으로 바뀌고나서 새로 처음부터 다시 강의를 들으면서 만들어 보고 있습니다.

 

next 15버전으로 바뀌고 나서 옛날꺼랑 msw 설정이 바뀌었더라구요
그런데 강의대로 msw 설정을 하니 ssr 적용이 제대로 안되는 것 같습니다.

msw 설정 후 페이지의 network 탭에 localhost document의 미리보기 내용이 없습니다.

 

ssr이 된다면 document에 미리보기에 내용이 넘어와야 하는데 msw 설정 후에 없습니다.

 

옛날에 만들어 놓았던, next14 버전으로 했었던 프로젝트에서는 미리보기에 내용이 잘 담겨 ssr이 잘되고 있고,

15버전으로 진행한 프로젝트에서

layout에 있는 mswprovider 컴포넌트를 없애주니 다시 미리보기에 내용이 생기는 것으로 보아 msw 설정에서 문제가 생긴 것으로 추측됩니다.

 

아래는 옛날 14 버전으로 진행했던 코드입니다. msw 2.1 버전입니다.

"use client";

import { useEffect } from "react";

export const MSWComponent = () => {
  useEffect(() => {
    if (typeof window !== "undefined") {
      if (process.env.NEXT_PUBLIC_API_MOCKING === "enabled") {
        require("@/mocks/browser");
      }
    }
  }, []);

  return null;
};

아래는 지금 하고있는 코드입니다. msw 2.7.3 버전입니다.

"use client";

import { Suspense, use } from "react";
import { handlers } from "@/mocks/handlers";

const mockingEnabledPromise =
  typeof window !== "undefined" // browser일 때
    ? import("@/mocks/browser").then(async ({ default: worker }) => {
        if (process.env.NODE_ENV === "production") {
          return;
        }
        await worker.start({
          // msw가 처리할 수 없는 요청이 들어왔을 때
          onUnhandledRequest(request, print) {
            if (request.url.includes("_next")) {
              // next가 내부적으로 처리하는 url이기 때문에 msw가 처리할 필요 없음 그래서 return
              return;
            }
            print.warning();
          },
        });
        worker.use(...handlers);
        (module as any).hot?.dispose(() => {
          worker.stop();
        });
        console.log(worker.listHandlers());
      })
    : Promise.resolve();

export function MSWProvider({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  // If MSW is enabled, we need to wait for the worker to start,
  // so we wrap the children in a Suspense boundary until it's ready.
  return (
    <Suspense fallback={null}>
      <MSWProviderWrapper>{children}</MSWProviderWrapper>
    </Suspense>
  );
}

function MSWProviderWrapper({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  // use 사용해서 promise 실행 기다리고 children return
  use(mockingEnabledPromise);
  return children;
}

 

제 추측으로는 MSWProvider에 있는 Suspense때문에 ssr 이 안되는 것 같은데, 맞는지 궁금합니다.

그리고 맞다면 next 사용시 msw로 데이터를 mocking 하게 되면 ssr 확인을 어떻게 해야 할까요??

답변 1

0

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

이거 15버전부터는 배포 빌드를 해야지만 ssr이 되는 게 보이는 걸로 바뀌었을 겁니다

미리보기에만 안 보이지, HTML 안에 이미 SSR된 결과물들이 들어 있습니다.

강주호님의 프로필 이미지
강주호
질문자

방금 mswprovider에 있는 suspense를 지우니 document 미리보기에 내용이 잘 담기는 걸로 보아 ssr이 되는 것으로 보입니다.

export function MSWProvider({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  // If MSW is enabled, we need to wait for the worker to start,
  // so we wrap the children in a Suspense boundary until it's ready.
  return <MSWProviderWrapper>{children}</MSWProviderWrapper>;
}

 

mswprovider에 있는 suspense는 fallback이 null인데 왜 사용하는 것인지 궁금합니다.

그리고 꼭 사용해야 한다면 ssr이 되는지 안되는지 확인을 못하는데 개발단계에서 어떻게 해야하는 건지도 궁금합니다.

 

제로초님이 답변해주신 "15버전부터는 배포 빌드를 해야지만 ssr이 되는 게 보이는 걸로 바뀌었을 겁니다."

 

라는 것이 이해가 잘 안되는데 조금만 자세히 설명해 주실 수 있을까요..

배포, 빌드 단계에서는 어차피 msw가 아닌 실제 데이터를 사용하기 때문에 msw가 사용이 안되서 상관없다는 뜻인가요..?

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

주석에 적혀있는대로 워커가 실행되길 기다려야 해서 프로미스를 기다리기 위한(use) 것이고요. 개발단계에서는 ssr할 필요가 없어서 제외입니다

강주호님의 프로필 이미지
강주호
질문자

개발 단계에서는 ssr할 필요가 없어서 제외라면

개발중에 컴포넌트가 서버사이드에서 렌더링이 되었는지, 클라이언트 사이드에서 렌더링이 되었는지 확인은 어떻게 해야 하는 것인가요??

 

저는 개발자도구에서 document에 담긴 미리보기로 어떤 컴포넌트들이 프리 렌더링 되었는지 확인을 했었습니다.

 

이해가 부족해서 많은 질문 죄송합니다 ㅠㅠ

 

제로초(조현영)님의 프로필 이미지
제로초(조현영)
지식공유자

근데 생각해보니 지금 ssr이 되고 있을 것 같은데요. 미리보기에만 안 뜨지(layout div가 hidden 상태라서) HTML에 태그가 다 들어있습니다.

Suspense가 있더라도 Suspense children이 서버 컴포넌트이면 서버컴포넌트 resolve된 뒤에 ssr 완료됩니다.