Next.js 와 Svg, Material UI SvgIcon 다루는 방법 알아보기
디자이너가 직접 만들어준 아이콘을 Material UI SvgIcon에 넣어 사용하고 싶었다.
차근차근 진행했던 방법을 기록해보고자 한다.
1. Material UI SvgIcon
디자이너는 나에게 svg 아이콘을 파일로 제공했다. 그래서 이 파일을 컴포넌트로 만들어 Material UI SvgIcon에 넣고 싶었다.
관련한 예제는 Material UI SvgIcon Component Prop 에서 확인할 수 있는데,
import ArrowIcon from './Arrow.svg';
<SvgIcon component={ArrowIcon} inheritViewBox />
위처럼 바로 적용해서 되면 참 좋겠지만, 그렇지 않았다. Svg 파일을 리액트 컴포넌트처럼 사용하기 위해서는 svgr 라이브러리가 필요했다.
끙
2. Svgr
다행히 공식문서 를 보면 쉽게 적용이 가능하다. Next.js 메뉴로 가서 절차대로 진행한다.
npm install --save-dev @svgr/webpack
# or use yarn
yarn add --dev @svgr/webpack
설치를 위 명령어로 실행하고
// next.config.js
const moduleExports = {
// ...
webpack: (config) => {
// ...
config.module.rules.push({
test: /\.svg$/,
use: '@svgr/webpack',
})
return config
},
}
next.config.js에 웹팩 설정으로 .svg 파일을 svgr 라이브러리를 사용해서 컴포넌트로 만들겠다고 지정해준다. 다른 config.module.rules.push로 설정해주는게 있다면 (ex. yaml-loader) 그 밑에 다음 config.module.rules.push를 붙여주면 된다.
이제 준비는 끝났다.
3. 아이콘 사용하기
이제 위 1번에서처럼 아이콘 사용이 가능할 것이다.
import ArrowSvg from '../assets/icons/ArrowSvg.svg'
export const ArrowIcon = () => <SvgIcon component={ArrowSvg} />
위처럼 적용하면
<ArrowIcon color="primary" />
ArrowIcon을 Material Icon처럼 JSX 형식으로 사용할 수 있고 Material Icon에서 제공하는 props를 사용할 수도 있다.
물론 svg파일이 color props가 fill로 잘 들어가게 구조가 맞아야 하지만...
4. Jest 적용하기
이로써 아이콘 작업이 끝난 줄 알았는데... 테스트 코드를 돌렸더니 에러가 발생했다.
알고보니 Jest 설정에도 svgr에 관한 설정을 추가해줘야 했다. 이 문제 또한 svgr 공식문서 에서 가이드되고 있었다.
이제 적용해보자. 우선 jest.config.js에 아래 설정을 추가해주자.
// jest.config.js
// ...
moduleNameMapper: {
'^.+\\.(svg)$': '<rootDir>/__mocks__/svg.js',
},
위처럼 추가해줬다면 위 코드에서 보이는 바와 같이 루트 디렉토리에 __mocks__/svg.js 파일을 생성해야 한다. 생성하러 가보자!
// __mocks__/svg.js
// eslint-disable-next-line import/no-anonymous-default-export
export default 'svgr-url'
export const ReactComponent = 'div'
루트 디렉토리에 __mocks__ 폴더를 생성하고 안에 svg.js 파일을 생성한다.
그리고 위 코드를 넣어주면 svgr을 사용해 만든 svg 컴포넌트가 테스트에 돌아가도 문제가 생기지 않을 것이다.
얏호!

우여곡절 많았던 Next.Js에서 Svg 아이콘 사용하기 성공!