📑 오류기록

[ axios && jest ERROR] Cannot use import statement outside a module

Po_tta_tt0 2023. 1. 5. 17:40
반응형

 

 

0. 오류 상황 발생

따라하며 배우는 리액트 테스트 강의를 듣던 중, 관련 오류를 겪었다.
강사님은 성공하는데 왜 나는 오류가 생기지?
axios도 분명히 설치되어있고, 코드도 같은데 발생한 문제인지라, 빠르게 구글링을 통해 문제를 해결할 수 있었다.

문제 상황 발생 시 내 코드 (볼 필요 없습니당!)

 

Type.jsx

import React, { useEffect, useState } from "react";
import axios from "axios";
import Products from "./Products";

const Type = ({ orderType }) => {
  const [items, setItmes] = useState([]);
  useEffect(() => {
    loadItems(orderType);
  }, [orderType]);

  const loadItems = async (orderType) => {
    try {
      let response = await axios.get(`http://localhost:5000/${orderType}`);
      setItmes(response.data);
    } catch (error) {
      console.error(error);
    }
  };

  const ItemComponents = orderType === "products" ? Products : null;

  const optionItems = items.map((item) => (
    <ItemComponents
      key={item.name}
      name={item.name}
      imagePath={item.imagePath}
    />
  ));

  return <div>{optionItems}</div>;
};

export default Type;

Type.test.js

import { render, screen } from "@testing-library/react";
import Type from "../Type";

test("display product images from server", async () => {
  render(<Type orderType="products" />);

  const productImages = await screen.findAllByRole("img", {
    name: /product$/i,
  });
  expect(productImages).toHaveLength(2);

  const altText = productImages.map((element) => element.alt);
  expect(altText).toEqual(["America product", "England product"]);
});

 

1. 시도

구글링 결과, 역시. axios github 페이지에서도 관련 이슈가 등록되어 있었다
Jest tests failed after upgrading axios to v1.1.2
axios 1.1.2버전에서 발생하는 오류라고.

해결 방법은 다음과 같다.


package.json에서

  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test", // ✨ 여기
    "eject": "react-scripts eject"
  },

test를

"test": "react-scripts test --transformIgnorePatterns \"node_modules/(?!axios)/\"",

or

"test": "react-app-rewired test --transformIgnorePatterns \"node_modules/(?!axios)/\"",

로 변경해주면 된다
첫 번째 방법으로 변경 후, 테스트에 통과했다 ㅇㅖ이~😚

 

 

Try upgrading jest to latest (>29.2.x), it worked for me without having to change jest config.

jest를 29.2 이상 버전으로 업그래이드 해도 된다고 한다.(시도해본적은 없으니 되면 댓글에 공유해주시면 감사하겠습니다~!)

 

2. 궁금증

 

그렇다면 왜 axios의 최신버전이 jset에서 실행되지 않았을까?

그 이야기도 issue 페이지에 등록되어 있었다 확실한 정답인지 모릅니다! 주의하세요!

issue 링크

For context: Problem seem to be that Axios is now built as ES Module instead of CommonJs when not run in Node. Problem with Jest is that it runs code in Node, but application is built for web-clients.
This is why telling Jest to transform Axios works.

그러니까, Axios는 Node에서 실행되지 않을 때 CommonJs가 아니라 ES Module에서 built된다.
그런데 Jest는 Node에서 실행된다.
=> 하지만 application은 web-clients에서 실행된다..!
따라서 문제가 생겼던 것! // 이라고는 하지만 맞는 정답인지는 잘 모르겠어요(그래도 contributer니까 믿을만 하지 않을까요..?)

 

transformIgnorePatterns은 뭔데 갑자기 등장했지?

jest 공식문서
짜잔, 여기에 있어서 갑자기 등장하게 되었습니다!

 

공식문서의 일부를 가져왔어요

transformIgnorePatterns array

Default: ["/node_modules/", "\\.pnp\\.[^\\\/]+$"]

 

An array of regexp pattern strings that are matched against all source file paths before transformation. If the file path matches any of the patterns, it will not be transformed.

Providing regexp patterns that overlap with each other may result in files not being transformed that you expected to be transformed. For example:

  • JavaScript
  • TypeScript
/** @type {import('jest').Config} */
const config = {
  transformIgnorePatterns: ['/node_modules/(?!(foo|bar)/)', '/bar/'],
};

module.exports = config;

The first pattern will match (and therefore not transform) files inside /node_modules except for those in /node_modules/foo/ and /node_modules/bar/. The second pattern will match (and therefore not transform) files inside any path with /bar/ in it. With the two together, files in /node_modules/bar/ will not be transformed because it does match the second pattern, even though it was excluded by the first.

Sometimes it happens (especially in React Native or TypeScript projects) that 3rd party modules are published as untranspiled code. Since all files inside node_modules are not transformed by default, Jest will not understand the code in these modules, resulting in syntax errors. To overcome this, you may use transformIgnorePatterns to allow transpiling such modules. You'll find a good example of this use case in React Native Guide.

These pattern strings match against the full path. Use the string token to include the path to your project's root directory to prevent it from accidentally ignoring all of your files in different environments that may have different root directories.

 

 

영어 읽으시느라 고생 많으셨어요. 주요 내용은 이렇습니다.

 가끔(특히 React Native나 TypeScript 프로젝트에서) 서드 파티 모듈이 변환되지 않은 채 게시되는 경우가 있습니다.
그 때문에 node module에 있는 모든 파일이 변환되지 않고, 이 때문에 Jest는 그 모듈을(변환되지 않은 특정 모듈들)을 인식하지 못합니다.
이 문제를 해결하기 위해 transformIgnorePatterns를 사용하면 됩니다! 짜잔~

 

 

 

 

 

 

끝!

반응형