Vite에서 SVG 사용방법

미어캣의 개발일지·2025년 2월 14일
post-thumbnail

SVG란?

SVG(Scalable Vector Graphics)는 벡터 그래픽포맷의 하나로, XML 기반으로 2D 그래픽을 표현한다. 픽셀 단위로 저장하는 다른 이미지 포맷(PNG, JPEG, GIF 등)과 달리 수학적 좌표와 도형 정보로 그래픽을 표현하기 때문에 확대하거나 축소해도 품질이 변하지 않는 특징이 있다.

성능 비교SVGPNG
파일 크기단순한 도형은 작지만, 복잡한 것은 크다.이미지 크기에 따라 다름, 일반적으로 크다
확대/축소 품질무한 확장 가능 (벡터 기반)확대 시 품질 저하 (픽셀 기반)
렌더링 속도복잡한 도형일수록 느리다.빠르다.
애니메이션CSS 및 JavaScript로 가능하다.지원되지 않는다.
SEO 친화성검색 엔진이 읽을 수 있다.검색 엔진이 내용을 해석할 수 없다.



SVG 사용하기

svg는 <img> 태그로 사용할 수 있다.

<img src="/assets/icon.svg" alt="아이콘" width="100" height="100" />

하지만 <img>로 불러온 SVG는 CSS로 세부적인 스타일(예: 색상, 경계선) 조정이 어렵다

이 문제를 해결하기 위해서는 컴포넌트로 사용하면된다.

사용 방법으로는 다음과 같다.

import { ReactComponent as Logo } from 'assets/icon.svg';

<Logo />

이 코드는 Create-React-App에서 사용하는 방법으로

Vite 환경에서 실행을하면

'".svg"' 모듈에 내보낸 멤버 'ReactComponent'이(가) 없습니다. 대신 '".svg"에서 ReactComponent 가져오기'를 사용하시겠습니까?

에러가 발생한다.


Vite + Typescript에서 SVG 사용하기

1) vite-plugin-svgr 설치

npm install --save-dev vite-plugin-svgr
  • vite-plugin-svgr은 Vite 빌드 과정에만 필요한 플러그인이므로, --save-dev를 붙여 프로덕션 환경에서 제외시킨다.

2) vite.config.ts 코드 추가

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import svgr from 'vite-plugin-svgr'

export default defineConfig({
  plugins: [react(), svgr()],

  server: {
    open: true,
  },
});

3) vite-env.d.ts 코드 추가

/// <reference types="vite/client" />
/// <reference types="vite-plugin-svgr/client" />

4) svg.d.ts 파일 생성

// src/svg.d.ts
declare module "*.svg?react" {
  import { FC, SVGProps } from "react";
  const ReactComponent: FC<SVGProps<SVGSVGElement>>;
  export { ReactComponent };
}

svg.d.ts 파일이 필요한가?

  • TypeScript는 기본적으로 .svg 파일을 모듈로 취급하지 않으며, 이를 React 컴포넌트로 변환하려면 타입 정의가 필요하다.

declare module "*.svg?react":

  • TypeScript에게 .svg?react로 끝나는 파일을 React 컴포넌트로 처리하도록 알려줌

5) tsconfig.node.json에 타입 추가

{
  "compilerOptions": {
    ...
    "types": ["vite-plugin-svgr/client"]
  },
  "include": ["vite.config.ts", "svg.d.ts"]
}

tsconfig.node.json에 추가하는 이유

  • vite-plugin-svgr와 같은 Vite 플러그인을 사용하는 경우, Vite 설정 파일인 vite.config.ts와 타입 정의 파일인 svg.d.ts를 TypeScript가 인식할 수 있도록 해야 한다.



사용

import MyIcon from './assets/icon.svg?react';

const MyComponent = () => (
  <div>
    <MyIcon width={50} height={50} />
  </div>
);

왜 ?react를 붙이는가?

  • **?react**는 Vite의 SVGR 플러그인 지시어로, SVG 파일을 React 컴포넌트로 변환하기 위해 사용된다.



참조

React에서-SVG-컴포넌트로-불러오기
SVG 파일, React Component로 가져오기 (Vite + TypeScript)

profile
이게 왜 안되지? 이게 왜 되지?

0개의 댓글