webpack5 + tw.macro + typescript 에서 svg 사용하기

Song-Minhyung·2023년 2월 10일
1

webpack

목록 보기
1/1
post-thumbnail

❓ 문제1 - svg를 컴포넌트로 쓰고싶다.

처음에는 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로는 사용을 하지 못했다.

❓ 문제2 - 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로 인식을 하게 됐다.

📝 정리

svgr/webpack 설치

npm i -D @svgr/webpack

위 명령어로 @svgr/webpack 를 설치해준다.

webpack.config.js파일 수정

module.exports = {
  ...
  module: {
    rules:[
      ...
      {
        test: /\.svg$/,
        oneOf: [
          {
            use: ['@svgr/webpack'],
            issuer: /\.[jt]sx?$/,
            resourceQuery: { not: [/url/] },
          },
          {
            type: 'asset',
            resourceQuery: /url/, // *.svg?url
          },
        ],
      },
    ]
  }
}

svg.d.ts 파일 생성

나는 루트폴더/@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;
}

tsconfig.json 파일 수정

해당 d.ts파일을 인식시키기 위해 include에 폴더를 추가해준다.

{
  ...
  "include": [..., "@types"],
}

📌 css, url, component로 svg 사용하기

1. svg를 css에서 사용

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 });
`;

2. svg를 컴포넌트로 사용

그냥 컴포넌트 쓰듯이 쓰면된다.

import Svg from 'path/name.svg';

<Svg />

3. svg를 url로 사용 사용

경로 끝에 ?url반드시 넣어줘야한다.

import svg from 'path/name.svg?url';

<img src={svg} />
profile
기록하는 블로그

0개의 댓글