My Boundary As Much As I Experienced

vite쓸꺼면 Jest는 쓰지말기 본문

FrontEnd/React

vite쓸꺼면 Jest는 쓰지말기

Bumang 2023. 12. 20. 18:47

요새 유행하는 번들러 환경 Vite에, 가장 유명한 테스팅 라이브러리 Jest를 엮어쓰려고 했으나

Jest는 웹팩 기반 라이브러리라 Vite환경에서 쓰려면 매우 복잡한 설정들을 거쳐야 한다.

아래 글에서 더욱 자세히 알려준다.

 

vite 에서는 import.meta.env.VITE_XXX 와 같이 환경 변수를 사용하는데
WEBPACK 환경에서 위와 같은 환경 변수를 사용하기 위해서는 별도의 babel 관련 설정이 추가되어야 합니다.

https://velog.io/@saeeng/VITE-VITEST-migrate-from-Jest

 

VITE + VITEST (migrate from Jest)

Vite > Vite의 사전 번들링 기능은 Esbuild를 사용하고 있습니다. Go로 작성된 Esbuild는 Webpack, Parcel과 같은 기존의 번들러 대비 10-100배 빠른 번들링 속도를 보였죠. (https://vitejs-kr.github.io/guid

velog.io

 

 

아래는 최근에 vite환경으로 진행했던 팀 프로젝트에 jest를 깔면서 겪은 애로사항들이다.

 

 

1. 설치

// 시도
npm install jest --save-dev //jest 설치
npm install @testing-library/react --save-dev // 같이 쓰는 testing library 설치
npm install ts-jest @types/jest --save-dev // 타입스크립트 타입 설치


// in package.json
{
  "name": "mini-app-testing",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "tsc && vite build",
    "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
    "test": "jest" // script에 jest를 추가
  },

// 여기까지는 기본적인 튜토리얼에서 제공하는 설치 방법

일단 jest를 설치하고, 같이 쓰게 될 react testing library를 설치한다.

그리고 타입스크립트 지원을 위해서 @types/jest도 깔아야 한다.

 

 

 

2. jest.setup.ts와 jest.config.ts 설정

// Error
Cannot find module '@testing-library/jest-dom/extend-expect' from 'jest.setup.ts'

// jest.config.js
module.exports = {
  // ... 다른 설정
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'], 
  // jest.setup.ts파일이 어디 설치되어 있는지 명시
  // ... 다른 설정
};

공식문서에서 보이는대로 jest.setup.ts와 jest.config.ts를 설정하였다.

그러나 위 에러가 떴는데, jest.setup.ts의 설치 경로를 setupFilesAfterEnv에 명시해줘야 한다.

 

 

 

3. jest-dom 설치, 스타일 전처리기 우회 프록시 설치

npm install ts-node @testing-library/jest-dom --save-dev
// testing library가 jest-dom을 쓸 수 있게 해주는 라이브러리
npm install jest-environment-jsdom
// jest가 dom조작을 할 수 있게 해주는 라이브러리
npm install identity-obj-proxy --save-dev
// jest가 css 전처리기를 이해할 수 있게 해주는 우회 프록시.
// 스타일 전처리기를 쓰는데 왜 프록시까지 필요하지..?


// jest.config.ts

export default {
    preset: 'ts-jest',
    testEnvironment: 'jest-environment-jsdom',
    transform: {
        "^.+\\.tsx?$": "ts-jest" 
    // process `*.tsx` files with `ts-jest`
    },
    moduleNameMapper: {
        '\\.(gif|ttf|eot|svg|png)$': '<rootDir>/test/__ mocks __/fileMock.js',
    },
}

이전까지는 Dom 렌더하는 부분에서 계속 에러가 나길래, 찾아봤더니 jest-dom을 깔아야한다고 한다.

공식문서에선 이 부분에 대해서 찾긴 어려웠는데 해외 블로그 찾아보면서 vite에서 jest깔기 글을 참고하여

testing lib의 jest-dom, jsdom을 깔았다.

 

그리고 나서도 테스트 상에서 scss를 불러올 수 없었는데, jest는 scss같은 css 전처리기를 읽을 수 없단다.

이걸 해결하려면 identity-obj-proxy를 깔아야한다는데, 아니 스타일 전처리기 읽을려고 프록시까지 필요한가? 싶긴 했다.

이때부터 jest 사용해야되나에 대해 크나큰 의심이 들기 시작했다.

 

 

 

4. ESM 설정을 commonjs해야지만 돌아감

// error
File is a CommonJS module; it may be converted to an ES module.ts(80001)
Parsing error: ESLint was configured to run on `<tsconfigRootDir>/babel.config.js` using `parserOptions.project`: /users/jeongbeomhwan/desktop/mini_project/fastcatch-frontend/tsconfig.json
// module이 commonjs가 아니어서 나는 에러. babel을 써야 한다.

// in tsconfig.json 
{
  "compilerOptions": {
    "module": "ESNext", 
		// webpack환경은 전통의 commonjs를 사용하지만, vite는 esnext등 최신 모듈을 사용합니다...
    // 다른 설정들...
  },
  // 다른 설정들...
}

// in ESLint
module.exports = {
  // 다른 설정들...
  parserOptions: {
    project: './tsconfig.json',
    // 다른 설정들...
  },
};

// babel같은 구문 변환기를 이용해서 babel.config.js에 설정하여 고치는 방법도 있다고 함.
// webpack 환경에는 babel도 설치되지만 vite환경에선 babel도 별도 설치해줘야 한다.

webpack 환경은 commonjs환경이어서 jest는 commonjs 구문만 처리할 수 있다고 한다.

tsconfig에서 해당 부분이 ES2015, ... , ESNext 등 최신 구문을 기준으로 설정되어 있다면 에러가 발생한다.

이때 commonjs로 바꿔주면 해결될 줄 알았는데, commonJS환경에서 안 돌아가는 또 다른 라이브러리가 있어서 난관에 봉착하게 되었다.

 

 

 

5. 전체 경로를 쓴 import가 있다면 jest.config.ts 설정에 또 추가해줘야합니다.

// Error
Cannot find module '@/constant/categories' from 
'src/components/common/filter/Filter.tsx'
//딱 봐도 경로문제

export default {
  testEnvironment: 'jsdom',
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  moduleNameMapper: {
    '@/(.*)$': '<rootDir>/src/$1', // 절대 경로를 포함할 수 있게 함.
  },
  setupFilesAfterEnv: ['<rootDir>/jest.setup.ts'],
};

절대경로를 또 얘가 못 불러온대요..   moduleNameMapper: { '@/(.*)$': '<rootDir>/src/$1' }, 를 추가해줘야 절대 경로를 잘 불러올 수 있게 된다.

 

 

 

6. esModuleInterop이 true여야 합니다.

// error
If you have issues related to imports, 
you should consider setting `esModuleInterop` to `true` 
in your TypeScript configuration file (usually `tsconfig.json`).


// tsconfig.json
{
  "compilerOptions": {
    "esModuleInterop": true, // esModuleInterop을 true로 해주라 한다. 뭔진 모름..
    // 다른 설정들...
  },
  // 다른 설정들...
}

 

esModuleInterop이 뭔지 궁금하다면 아래 글을 참고할 것. commonJS 모듈도  es6 모듈 사양으로 컨버팅 해주는거 같다.

이렇게.

// Before import difference from 'lodash/difference'; difference();

// After const difference = __importDefault(require('lodash/difference')); difference();

 

더 자세히 알고 싶으면 아래 블로그를 참고할 것.

 

https://pewww.tistory.com/26

 

 

// error
The 'import.meta' meta-property is only allowed // vite환경의 메타데이터...
when the '--module' option is 
'es2020', 'es2022', 'esnext', 'system', 'node16', or 'nodenext'.


// in tsconfig
{
  "compilerOptions": {
    "module": "esnext",
	// 이걸 commonjs로 바꿔야하는데, 최신 구문에 의존하는 라이브러리도 있어서 문제가 됨...
	// jest 설치를 포기
    "target": "esnext",
    // 나머지 옵션들...
  },
  // 나머지 설정들...
}
//

 

import.meta
ES2021(ES12) 에 새로 추가된 기능이다.
모듈 컨텍스트(module context) 특정 meta 데이터를 공개한다고 설명이 되어있다.

 

Vite 는 import.meta.env 를 통해서 속성을 노출시킨다.

이 최신구문을 또 jest께서 못 불러오신다구 한다...

 

이 경우 babel을 깔아서 해결하거나 swc를 통해서 해결할 수 있다고 한다. 자세한 설명은 아래서 참고하면 된다.

 

import.meta가 뭔지:

https://velog.io/@katanazero86/Typescript-%EC%97%90%EC%84%9C-import.meta-%EC%82%AC%EC%9A%A9%EB%B2%95

 

Typescript 에서 import.meta 사용법(Feat. Vite)

ts 에서 import.meta 사용법을 정리

velog.io

 

더욱 구체적인 jest를 깔기위한 에러 핸들링 여정을 읽고 싶다면:

https://medium.com/@Jun_0/react-jest-dac7a8c83910

 

React Jest 테스트 환경설정(with Vite, TS)

이미 개발이 어느 정도 진행되어진 프로젝트에서 FE 테스트 코드 작성을 위한 jest Setup과정을 정리하고자 한다.

medium.com

...이쯤에선 이제 다른 테스팅 라이브러리를 찾아보려고 마음먹었다. 아래는 팀원들과 협의하기 위해 추린 선택지이다.

 

 

 

 

선택지

  1. 모든 에러를 뚫고 jest 설치하기 (… 자신없음)
  2. vite환경에서 jest 설치를 모두 다 마친 보일러플레이팅 라이브러리를 설치해서 jest 사용하기
    1. https://github.com/XionWCFM/vite-mui?tab=readme-ov-file
  3. vitest라는 vite환경 테스트 도구 사용하기
    1. https://velog.io/@saeeng/VITE-VITEST-migrate-from-Jest
  4. playwright를 사용하기

 

결론: 

누군가 이 험난한 과정을 다 처리해서 vite bolierplate 템플릿을 만든게 있어서 이걸 사용하거나, vitest를 사용하는게 어떤지 제안했다.

결국 vite환경을 위한 테스팅 라이브러리인 vitest를 사용하기로 팀원들과 합의했다.