Frontend Engineer - 박준형

Published on

Next.js + Msw + Apollo Example

Authors
  • Name
    Twitter

왜 만들었는가?

(출처 : 카카오 Tech : Mocking으로 생산성까지 챙기는 FE 개발)

이상

요구사항분석 및 기획 -> 백엔드 개발 -> 프론트엔드 개발

현실

MSW를 도입하기 위한 동기부여 및 배경사항은 출처 링크에서 확인하면 되고,
도입 기술 스택에 맞추어 보일러플레이트를 만들기 위하여 해당 레포지토리를 생성하였다.

Getting Started

npx create-next-app Apollo_Msw --typescript
npx msw init pubic/ --save
mkdir src && mkdir /static/images/DEV/msw/src/mocks
cd /static/images/DEV/msw/src/mocks
touch browser.ts
touch server.ts
touch handler.ts
touch index.ts
// browser.ts
import { setupWorker } from 'msw'
import { handlers } from '/static/images/DEV/msw/handlers'

export const worker = setupWorker(...handlers)
// server.ts
import { setupServer } from 'msw/node'
import { handlers } from '/static/images/DEV/msw/handlers'

export const server = setupServer(...handlers)
// handler
import { graphql } from 'msw'

const user = { ...userInfo }

export const handlers = [
  graphql.query('fetchUserInfo', (req, res, ctx) => {
    return res(
      ctx.data({
        user,
      })
    )
  }),
]
// index.ts
async function initMocks() {
  if (typeof window === 'undefined') {
    const { server } = await import('/static/images/DEV/msw/server')
    server.listen()
  } else {
    const { worker } = await import('/static/images/DEV/msw/browser')
    worker.start()
  }
}

initMocks()

export {}
// _app.tsx
import React from 'react'
import { ApolloProvider } from '@apollo/client'
import type { AppProps } from 'next/app'

import './static/images/DEV/msw/styles/globals.css'
import { useApollo } from './static/images/DEV/msw/lib/apolloClient'

if (process.env.NEXT_PUBLIC_API_MOCKING === 'enabled') {
  import('./static/images/DEV/msw/mocks')
}

export default function MyApp({ Component, pageProps }: AppProps) {
  const client = useApollo(pageProps)
  return (
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  )
}
// index.tsx
import React from 'react';
import type { GetServerSideProps, NextPage } from 'next';

import { initializeApollo } from './static/images/DEV/msw/lib/apolloClient';
import { FETCH_USER_INFO_QUERY } from './static/images/DEV/msw/shared/usersGraphql';
import { Main } from '/static/images/DEV/msw/styles';

const Home: NextPage = ({ data: { user }, loading, networkStatus }: any) => {
  if (loading) return <p>loading..</p>;

  return View...
};

export default Home;

export const getServerSideProps: GetServerSideProps = async () => {
  const client = initializeApollo();
  const { data, loading, networkStatus } = await client.query({
    query: FETCH_USER_INFO_QUERY,
  });

  return {
    props: { data, loading, networkStatus },
  };
};

결과물