create-react-app에서 SVG를 ReactComponent로 사용하기

Acccdang·2021년 7월 12일
0

들어가기에 앞서..

create-react-app(이하 CRA) + electron 환경에서 작업 중에 svg icon 파일을 사용해야 하는 경우가 생겼다. (state에 따라 색상 등을 다르게 주는 등의 작업을 위해..)

사실 이전에도 버튼 안에 svg icon을 넣는 것을 시도해보았으나, 해결하지 못해 임시로 그냥 img 태그에 src로 넣어서 해결해놨었다.

그 이후 다시 구글링하면서 찾아보다가 해결하게 돼서 기록을 남긴다.

프로젝트 설정

일단 나는 CRA + electron으로 사용하고 있는데, CRA의 단점이 바로 webpack, babel 등의 상세한 config를 설정하지 못한다는 것이다. (물론 eject하면 모든 config file들이 나타나지만, 다시 되돌릴 수 없다.)

그래서 사용하는게 craco 이다.
craco 를 이용하면 github README에서 설명하듯이, CRA를 이용한 project에서 eject를 할 필요 없이 webpack, babel, plugin 구성을 추가로 설정할 수 있다.

SVG import 시도 및 에러 확인

우선, CRA에서 공식적으로 svg를 import하는 방법을 여기에서 알려주고 있는데, 방법은 아래와 같다.

import { ReactComponent as LogoIcon } from './logo.svg';

function App() {
  return (
    <div>
      {/* Logo is an actual React component */}
      <Logo />
    </div>
  )
}

그래서 이렇게 해봤는데.. 'Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.' 라고 하면서 에러를 뱉는다.

console.log로 LogoIcon 을 찍어보니 undefined가 나온다. undefined인 컴포넌트를 보여주려고 하니 에러를 뱉는것이다.

해결

craco github README를 잘 따라오면 craco.config.js가 root에 생성되어 있을 것이다.

우선, svg를 따로 로드하기 위해, svg loader를 의존성에 추가한다.

yarn add @svgr/webpack --dev

그 다음, 아래와 같이 webpack 설정을 추가해주자.

module.export = {
  // ...
  webpack: {
    configure: (config, { env, paths }) => {
      config.module.rules.unshift({  /* 중요! unshift를 해야함. */
        test: /\.svg$/,
        use: ['@svgr/webpack'],
      });
      return config;
    }
  }
  // ...
}

처음 구글링을 하며 돌아다닐 때 config.module.rules.push({}) 를 하라길래 해봤는데 달라지지 않았다. 그러던 중 push 대신 unshift 를 사용하니 해결되었다.
아마 우리가 설정하고 싶은 rule ('@svgr/webpack') 을 단순 push하는게 아닌 제일 앞단(unshift)에 위치시켜야 적용되는 듯 하다.
(unshift에 대해 webpack document 등 많이 뒤져봤는데 왜인지 모르겠지만 자세한 내용을 찾기가 어려웠다.. 이후에 좀 더 찾아봐야 할 듯)

이제 다시 react-script를 실행해보면 SVG Component가 정상적으로 나타난다..!

profile
개발이 취미가 되고픈 개발자

0개의 댓글