Skip to content

[TS] Webpack 환경에서 MSW v2 이슈

MYONG JAEWI edited this page Aug 9, 2024 · 1 revision

# 문제상황

MSW가 http 요청을 가로채지 못했돠..

  1. useQuery를 사용하는 hook과 fetch 함수는 문제가 없음을 확인, api url도 확인하였다.
  2. MSW handler에서 console.log를 찍어보았는데, 찍히지 않았다.

→ MSW 서버가 제대로 동작하지 않음을 확인하였다.

# 원인 분석

vite 환경과 달리 webpack환경에서 msw v2의 이슈가 있음을 확인하였다. [공식문서](https://mswjs.io/docs/migrations/1.x-to-2.x/)에서도 이를 언급하였다(Frequent issues 부분)

하지만 공식문서의 해결방안을 그대로 따랐음에도 해결되지 않았따..

우선 원인은 기존의 node의 util의 TextDecoder, TextEncoder 가 호환이 되지 않는 이슈가 있어서, 따로 패키지를 받아 패키지의 TextDecoder, TextEncoder 를 오버라이딩해줘야하는듯 했다.

# 해결방안

  1. jest.config.ts에 다음 옵션들을 추가한다.
 setupFiles: ['./jest.polyfills.js'],
  testEnvironmentOptions: {
    customExportConditions: [''],
  },
  setupFilesAfterEnv: ['./setupTests.ts'],
  1. jest.polyfills.js 파일은 config파일과 동등한 위치에 추가한다. 잘 보면 공식문서에서 제공하는 polyfills에서 더 추가된 부분이 있다. 해당 부분은 [버건디](https://github.com/woowacourse-teams/2024-devel-up/pull/83/files)의 도움으로 알게되었다.

    const { ReadableStream, TransformStream } = require('node:stream/web');
    const { TextDecoder, TextEncoder } = require('node:util');
    
    Object.defineProperties(globalThis, {
      TextDecoder: { value: TextDecoder },
      TextEncoder: { value: TextEncoder },
      ReadableStream: { value: ReadableStream },
      TransformStream: { value: TransformStream },
    });
    
    Object.defineProperties(globalThis, {
      TextDecoder: { value: TextDecoder },
      TextEncoder: { value: TextEncoder },
      ReadableStream: { value: ReadableStream },
    });
    
    const { Blob, File } = require('node:buffer');
    const { fetch, Headers, FormData, Request, Response } = require('undici');
    
    Object.defineProperties(globalThis, {
      fetch: { value: fetch, writable: true },
      Blob: { value: Blob },
      File: { value: File },
      Headers: { value: Headers },
      FormData: { value: FormData },
      Request: { value: Request },
      Response: { value: Response },
    });
    
    globalThis.setImmediate = (callback, ...args) => setTimeout(callback, 0, ...args);
    
    globalThis.clearImmediate = (immediateId) => {
      clearTimeout(immediateId);
    };
  2. package.json에는 다음 두 패키지를 추가한다.

util 패키지는 공식문서에는 언급되지 않은 패키지이다. 하지만 해당 패키지를 설치하지 않고 공식문서 그대로만 한다면 node:util에서 TextDecoder, TextEncoder 이 두 친구를 찾지 못한다고 에러를 뱉었다.

"undici": "^6.19.2",
"util": "^0.12.5",
  1. setupTests.ts 파일을 역시 config 파일과 동등한 위치에 생성해준다.(파일명이나 경로는 바꾸어도 된다. jest.config에서 올바른 경로로 수정만 해주자)

    해당 파일에서 RTL의 jest-dom 패키지를 import하고 있으나 package.json에서는 해당 패키지를 설치하지 않았다. 그럼에도 동작하니 일단 넘어갔다. ㅎㅎ

    생각해보니 setupTests를 제대로 작성해주지 않아서 MSW 서버가 제대로 동작하지 않았나? 하는 생각이 든다. 시간이 될 때 에러가 났던 환경에서 다시 시도해보면 좋겠으나 일단 넘어가자.

    import { beforeAll, afterAll, afterEach } from '@jest/globals';
    import '@testing-library/jest-dom'; // did'nt install this package yet
    import { server } from './src/mocks/server';
    
    beforeAll(() => server.listen({ onUnhandledRequest: 'error' }));
    afterEach(() => server.resetHandlers());
    afterAll(() => server.close());
  2. 이렇게 생성된 파일들이 ts에러나 eslint 에러가 난다면 적당히 exclude하여 에러를 제외시켜 주자.

이렇게까지 하면 http요청을 잘 가로채서 테스트코드가 통과한다.

(vite 짱..)

참고 문헌

https://oliveyoung.tech/blog/2024-01-23/msw-frontend/

⚡️ 코드zap

프로젝트

규칙 및 정책

공통

백엔드

프론트엔드

매뉴얼

백엔드

기술 문서

백엔드

프론트엔드

회의록


Clone this wiki locally