처음에는 svg를 컴포넌트처럼 쓰고싶었다.
하지만 여기서 문제가 생겨서 문제는 나중에 해결하기로 하고
그냥 아래처럼 img
태그의 src를 바꿔서 사용했다.
import svg = '.../name.svg';
<img src={svg}/>
이 문제는 웹팩에서 svg파일은 svgr/webpack
loader를 사용해서 해결했다.
나는 typescript를 쓰고있었기에 아래처럼 svg.d.ts파일을 만들어서 타입을 인식시켜줬다.
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
그런데 이러면 svg파일을 url로는 사용을 하지 못했다.
그러기 위해서는 웹팩의 설정을 조금 바꿔주면 됐다.
{
test: /\.svg$/,
oneOf: [
{
use: ['@svgr/webpack'],
issuer: /\.[jt]sx?$/,
resourceQuery: { not: [/url/] },
},
{
type: 'asset',
resourceQuery: /url/, // *.svg?url
},
],
},
위처럼 해주면 파일을 불러올때 끝에 ?url이 붙으면 asset 모듈로 번들링을 하고
그렇지 않다면 svgr/webpack 로더로 번들링을 수행한다.
asset 모듈은 웹팩5에서 file-loader, url-loader등을 대체하는 모듈이다.
참조: https://webpack.kr/guides/asset-modules/
그리고 이를위해 svg.d.ts 파일을 조금 더 수정해줬다.
...
declare module '*.svg?url' {
const content: any;
export default content;
}
svg 파일을 import할때 끝에 ?url을 붙여주면 이제 url로 인식을 하게 됐다.
npm i -D @svgr/webpack
위 명령어로 @svgr/webpack 를 설치해준다.
module.exports = {
...
module: {
rules:[
...
{
test: /\.svg$/,
oneOf: [
{
use: ['@svgr/webpack'],
issuer: /\.[jt]sx?$/,
resourceQuery: { not: [/url/] },
},
{
type: 'asset',
resourceQuery: /url/, // *.svg?url
},
],
},
]
}
}
나는 루트폴더/@types 에 해당 파일을 생성해줬다.
declare module '*.svg?url' {
const content: any;
export default content;
}
declare module '*.svg' {
import React = require('react');
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}
해당 d.ts파일을 인식시키기 위해 include에 폴더를 추가해준다.
{
...
"include": [..., "@types"],
}
tw.macro는 동적인 스타일링을 해줄수 없다.
그래서 css로 처리를 해줘야한다.
참조: https://github.com/ben-rogerson/twin.macro/discussions/605
import { css } from '@emotion/react';
import svg from 'path/name.svg?url';
const svgcss = css`
background-image: url(${ svg });
`;
그냥 컴포넌트 쓰듯이 쓰면된다.
import Svg from 'path/name.svg';
<Svg />
경로 끝에 ?url
을 반드시 넣어줘야한다.
import svg from 'path/name.svg?url';
<img src={svg} />