본문 바로가기
개발

React+Webpack Boilerplate에서 SVG를 사용하기

by 보그몽 2020. 6. 29.

포스팅 타이틀

React Boilerplate를 제작하고, svg를 사용하는 과정에서

1. 모듈을 찾을 수 없습니다. - Cannot find module

2. SVG Component의 width,height을 css로 설정해 주었더니 컴포넌트가 화면상에 보이지 않습니다.

와 같은 에러를 발견했을 때 문제를 해결하는 경험에 대해서 이야기한다.

 

사실 Create React App 을 사용했을 때 이런 문제를 겪어본 적은 없다.
CRA에서는 import {ReactComponent as Icon} from "../icons"와 같은 형태로 svg를 컴포넌트 형태로 사용할 수 있다.

하지만, Webpack 설정을 통해 SVG를 사용할 수 있도록 설정하게 되면 webpack config file을 설정해야만 하고, 이 과정에서 문제가 발생했다.

 

문제가 재현될 수 있는 상황은 다음과 같다.

1. React, typescript, eslint, webpack을 이용하여 리액트를 시작한다.

2. 나는 svg를 Component로 쓰고 싶다.

3. webpack svg loader를 @svgr/webpack을 사용한다.

 

문제 해결과정을 요약하면 다음과 같다.

1. custom.d.ts 파일을 작성하여 이것을 tsconfig의 include에 추가한다. (모듈을 찾을 수 없습니다. 해결)

2. webpack module option을 설정하여서 svg의 width, height, viewBox를 설정한다.

3. SVG를 import한다.

 

 

1. custom.d.ts 파일을 작성하여 이것을 tsconfig의 include에 추가한다. (모듈을 찾을 수 없습니다. 해결)

custom.d.ts

declare module '*.svg' {
  import React = require('react');

  export const ReactComponent: React.SFC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

 

그리고 

tsconfig.json의 가장 마지막 부분을 다음과 같이 변경

주의할 점은 custom.d.ts의 경로를 작성해야한다. 나의 경우 tsconfig.json과 custom.d.ts의 디렉토리 레벨이 동일했다.

  "include": ["src", "custom.d.ts"]

 

 

2. webpack module option을 설정하여서 svg의 width, height, viewBox를 설정한다.

원본 svg를 봤더니 width:"512" height:"512" viewBox:"0 0 512 512"가 설정되어 있었는데 icon으로 만들었더니 값이 이상하게 설정되어 있어서 아래 옵션을 다음과 같이 변경해 주었다.

 

webpack.config.js

module: {
    rules: [
      /* ...other modules */
      {
        test: /\.svg$/,
        use: [
          {
            loader: '@svgr/webpack',
            options: {
              template: (
                { template },
                opts,
                { imports, componentName, props, jsx, exports }
              ) => template.ast`
              ${imports} 
              
              const ${componentName} = (${props}) => {
                props = {...props, width:'512', height:'512', viewBox:'0 0 512 512'};
                return ${jsx};
          };
          export default ${componentName}`,
            },
          },
          // 'url-loader',
        ],
      },
    ],
  },

 

3. SVG를 import

*.tsx

import MoonIcon from '../icons/moon.svg';
import SunIcon from '../icons/sun.svg';

 

 

끝맺음.

webpack의 option 설정을 진행해보았다.

width, height 설정이 안 되어서 이것저것 찾아보다가 svg의 속성들에 대해서도 좀 공부할 수 있게 되었던 좋은 기회였다. 

 

 

참고

https://ryujek.tistory.com/entry/viewBox

 

viewBox

viewBox란? viewBox는 svg요소가 가지는 svg의 요소가 svg요소의 viewport의 경계범위까지 확장 또는 축소, 위치지정 및 분할을 할 수 있게 해주는 속성입니다. viewBox는 4개의 값을 가지게 되는데, 이는 다�

ryujek.tistory.com

https://www.robinwieruch.de/react-svg-icon-components

 

How to use SVG Icons as React Components? - RWieruch

A walkthrough on how to use SVG Icons in React applications. SVGR + Webpack are the perfect fit to make it happen...

www.robinwieruch.de

https://brunch.co.kr/@kkak10/3

 

SVG 시작하기#1

처음 시작하는 SVG | 동기 그동안 SVG에 대해 막연하게 알고 있었다. "백터 기반이라서 사이즈가 변경되어도 안 깨지고 XHTML 문법으로 이루어져서 CSS 및 Event Handle이 가능하다" 딱 이 정도만 알고 있

brunch.co.kr

https://css-tricks.com/scale-svg/

 

How to Scale SVG | CSS-Tricks

The following is a guest post by Amelia Bellamy-Royds. Amelia has lots of experience with SVG, as the co-author of SVG Essentials and author of the

css-tricks.com

 

댓글