[Typescript] Next.js와 Storybook에서 SVG파일을 컴포넌트처럼 사용하기 (with @svgr/webpack)
서론
필자가 최근 프로젝트를 진행하면서, SVG 이미지 파일들을 컴포넌트처럼 import하여 사용하고 싶다는 니즈가 생겼다. 그래서 Next.js와 Storybook 등, Webpack 환경에서 SVG 이미지 파일을 컴포넌트처럼 사용하는 방법을 찾아보았고, 이번 포스팅에선 이를 공유해보려 한다.
SVGR과 @svgr/webpack
SVGR은 SVG 이미지 파일을 React 컴포넌트로 변환해주는 프로젝트이다. 그중에서 @svgr/webpack 패키지를 이용하면, Webpack 번들러를 이용하는 프로젝트에서 SVG 이미지 파일을 컴포넌트처럼 import하여 사용할 수 있게 된다.
아래 명령어로 @svgr/webpack을 설치할 수 있다. 사용하는 매니저에 맞춰 명령어를 사용한다.
npm install -D @svgr/webpack
# or
yarn add -D @svgr/webpack
# or
pnpm add -D @svgr/webpack
프로젝트 내 Webpack 상황별 설치 과정
Webpack에 SVGR을 연동하는 방법은 기본적으로 다 비슷하긴하지만, 프로젝트에 Webpack이 존재하는 형태에 따라 설정방법이 조금씩 상이하다.
(공통) Typescript를 사용중인 경우
Typescript와 함께 SVG 이미지 파일을 컴포넌트처럼 import하여 사용하기 위해선, .d.ts 파일을 통해 .svg module을 정의해주어야 한다. src 폴더 같은 곳에 임의의 .d.ts 파일을 만들어주고 아래와 같이 .svg module을 정의해주면 된다.
그리고 위 .d.ts 파일의 경로를 tsconfig.json include 배열 프로퍼티에 추가해주면 된다.
단 주의할 점은, 우리가 만든 .d.ts가 최대한 배열의 앞쪽에 위치해야 정상적으로 적용되고, tsconfig.json을 수정한 이후에는 IDE나 에디터를 재시작해주는 것을 권장한다.
webpack.config.js 파일이 있는 경우
본격적으로 Webpack에 SVGR을 연동하는 파트이다. webpack.config.js에 module.rules에 해당하는 배열에 다음과 같이 설정을 정의해주면 된다.
Next.js를 사용 중인 경우
Next.js를 사용중이라면 별도의 webpack.config.js가 없을거다. 그래서 next.config.js의 webpack 프로퍼티를 통해 설정을 정의해주어야 한다.
webpack 프로퍼티에 함수를 전달하고, 해당 함수 내부에서 config.module.rules에 설정 객체를 push 해주어야하는 외적인 차이가 있다. 하지만 본질은 크게 다르지 않다.
Storybook을 사용 중인 경우
Storybook을 사용중이라면 대부분 기존 프로젝트에 Storybook이 추가된 형태일 것이라, 기존 프로젝트 Webpack 설정에 SVGR이 연동되어있더라도 따로 Storybook의 SVGR 연동 설정을 정의해주어야 한다. Storybook의 Webpack 설정은 .storybook/main.ts(또는 .storybook/main.js)에서 정의할 수 있다.
SVGR 사용법
정상적으로 SVGR이 설정되었다면 이제 .jsx나 .tsx 파일에서 SVG 파일을 컴포넌트처럼 import하여 사용할 수 있다.
SVGR 컴포넌트의 props는 svg 태그의 props를 그대로 이용할 수 있다(우리가 .d.ts 파일에 정의했었음.)
단 조금 주의할 점이 있는데,
SVG 이미지 파일 내 svg, path 등의 태그에 fill이나 stoke 같은 속성으로 색상이 지정되어있다면 SVGR 컴포넌트의 props으로 색상을 관리할 수 없다. 이런 경우, svg 파일 내의 색상과 관련된 속성을 제거해주면 해결이 가능하다.