개발여행

[TypeScript] Vite + React에서 svg 컴포넌트로 사용하기 본문

Web/React

[TypeScript] Vite + React에서 svg 컴포넌트로 사용하기

Titan. 2024. 5. 9. 23:56

Vite를 사용하지 않고 React만 단독으로 빌드하면 별도의 과정없이 svg를 컴포넌트로 사용할 수 있다.

하지만 Vite를 함께 사용하는 경우 라이브러리를 추가로 설치해야한다.

 

그마저도 public 디렉토리에 저장한 svg를 사용하기 쉽지않고 src에 저장해야 간편하게(?) 쓸 수 있다.

 

우선 `vite-plugin-svgr`이라는 라이브러리를 설치해야 한다. 원하는 패키지 관리자로 설치하자.

# npm
npm install --save-dev vite-plugin-svgr

# yarn
yarn add -D vite-plugin-svgr

# pnpm
pnpm add -D vite-plugin-svgr

 

아래의 라이브러리 페이지에서 사용법을 설명하고 있는데 이대로 사용한다면 svg를 사용할 순 있지만 props는 전달하지 못하는 반쪽자리 컴포넌트로만 사용할 수 있다.

https://www.npmjs.com/package/vite-plugin-svgr

 

props를 함께 사용하기 위해서 몇가지 과정이 필요하다.

 

1. vite.config.ts  수정

// 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()],
});

 

2. 루트 디렉토리에 svg.d.ts 파일 생성

// svg.d.ts

declare module "*.svg" {
  const content: React.FC<React.SVGProps<SVGElement>>;
  export default content;
}

 

3. tsconfig.json 수정

// tsconfig.json

{
  "compilerOptions": {
    // ...
    "types": ["vite-plugin-svgr/client"],

    /* Bundler mode */
    // ...
  },
  "include": ["src", "svg.d.ts"],
  // ...
}

 

4. 타입스크립트를 사용한다면 vite-env.d.ts 파일에 참조 타입으로 "vite-plugin-svgr/client"를 추가하면 타입 정의 관련 도움을 받을 수 있다.

// vite-env.d.ts

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

 

 

이렇게 파일들을 작성하고 나면 svg를 컴포넌트처럼 사용할 수 있다.

import SomeSvg from "../../assets/some.svg";

const SomeComponent: React.FC = () => {
  // ...
  
  return (
    <div>
      // ...
      <SomeSvg fill="blue" />
    </div>
  );
};

 

다만, svg 파일은 public 디렉토리가 아닌 src 디렉토리에 위치해야 한다.

구글링을 하다보니 vite-plugin-svgr 3.x.x 버전까지는 public에 svg를 넣고 "@assets/some.svg" 경로로 접근할 수 있었던것 같은데 4.2.0 버전에서는 작동하지 않았다. 플러그인을 3.3.0 버전으로 바꿔볼까 했더니 vite 4.x.x 버전까지만 호환이 되는데 현재 5 버전을 사용중이라 굳이 테스트해보진 않았다.

 

아래 링크에 있는 코드를 약간 수정해서 편법을 쓰면 public 디렉토리에 있는 파일도 접근이 가능했지만 vite에서 public 경로에 있는 파일을 동적으로 import 할 수 없어서 역시나 사용하기 불편한건 마찬가지였다. 그냥 src 폴더에 넣자..

https://stackblitz.com/edit/vitejs-vite-ecerjs?file=src%2FuseSvg.ts

 

 

svg 컴포넌트 쓰는데 이렇게 삽질을 하게 될 줄이야...