React 환경에서 jest로 테스트 코드 환경을 구축하고 있는데 이런 에러를 발견했습니다.
test를 실행하면
Jest encountered an unexpected token
Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not conf
igured to support such syntax.
Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.
By default "node_modules" folder is ignored by transformers.
Here's what you can do:
• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation
Details:
...\node_modules\uuid\dist\esm-browser\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { default as v1 } from './v1.js';
^^^^^^
SyntaxError: Unexpected token 'export'
> 1 | import { createInstance } from '@something';
이런 에러가 발생했습니다.
에러를 살펴보면 Jest가 file을 parse 실패하였다고 합니다.
이 경우는 표준이 아닌 javascript syntax 이거나 Jest 가 해당 syntax를 사용할 수 있도록 설정되지 않을 때 발생한다고 적혀있습니다.
에러 원인
jest는 Node.js 기반으로 동작합니다.
Node.js 는 ECMAScript 가 아니라 CommonJS 방식으로 모듈을 사용합니다.
위의 에러가 난 부분의 코드를 보면 CommonJS 가 아니라 ECMAScript 방식입니다.
ECMAScript
> 1 | import { createInstance } from '@something';
따라서 jest 가 동작하기 위해 에러가 나고 있는 uuid 라이브러리를 commonJS 방식으로 변환해줘야 합니다.
공식 문서에 보면 transformIgnorePatterns 를 사용하라고 나오는데
.babelrc 에서 이걸 사용해 봐도 도무지 해결되지 않았습니다.
이외에도 ts-jest 를 쓰는 방법,
@babel/preset-env를 설치하는 방법 등
모두 성공하지 못했습니다.
해결 방법
제가 성공한 방법 알려드립니다.
1. .babelrc 삭제하고 babelrc에 있던 내용 babel.config.js 만들어 옮기기
2. jest.config.js 에 transformIgnorePatterns 추가하고 에러 나는 모듈 넣어주기
<jest.config.js>
module.exports = {
...
transformIgnorePatterns: [
'node_modules/(?!(something|something2)/)',
]
}
위와 같이 입력하면
정규식 A(?!)B 은 B 문자열이 뒤에 붙지 않은 A 문자열과 매칭됩니다.
즉 node_modules/something 과 node_modules/something2 이외의
node_modeuls 하위 모든 라이브러리들은
transform을 ignore 하게 되고
something과 something2는 ECMAScript -> commonJS로 transform 하게 됩니다.
이로 버그를 해결할 수 있었습니다.
테스트를 실행할 때 마다 라이브러리를 transformIgnorePatterns 배열에 추가해줘야 하니
그냥 모든 라이브러리를 변환하게 하면 안 될까 하여
transformIgnorePatterns: [
'node_modules/(?!.*/)',
]
이렇게 해봤더니
테스트하는데 100초가 넘기 걸립니다.
그래서 모든 라이브러리를 변환하게는 하지 말고
테스트할 때 에러 나는 부분만 추가하자고 결론 내었습니다.
배운 점
처음에 에러 로그를 검색하면서 해결해보려 했는데 잘 되지 않았습니다.
transformIgnorePatterns 가 문제이지 않을까 하여
이를 파보니 해결 방법을 찾을 수 있었습니다.
단순히 에러 로그만을 검색하는 것이 아닌
원리를 이해하여 에러가 되는 원인을 파는 것이
해결을 빠르게 할 수 있다는 것을 알게 되었습니다.
레퍼런스
https://stackoverflow.com/questions/50147915/jest-transformignorepatterns-not-working
https://jestjs.io/docs/ecmascript-modules
https://jestjs.io/docs/configuration#transformignorepatterns-arraystring
https://jestjs.io/docs/code-transformation
https://junhyunny.github.io/react/jest/module-import-error-on-jest/
'dev' 카테고리의 다른 글
useDeferredValue 는 언제, 어떻게 쓰는걸까? (0) | 2023.11.05 |
---|---|
강원랜드 카지노 필승법 카드 카운팅 웹앱 개발 후기 (1) | 2023.10.05 |
Reactive Native Webview 의 장단점 (0) | 2023.07.19 |
틸드tilde(~)와 캐럿caret(^)의 차이, 어떤 걸 써야할까? (이슈 회고) (0) | 2023.06.26 |
2023년 상반기 주류 이커머스 스타트업 프론트엔드 개발 회고 (0) | 2023.06.13 |
댓글