Vite + React(typescript) で SVGファイルをコンポーネントとして読み込む方法
create-react-appで作成したアプリの場合、デフォルトで svg ファイルをコンポーネントとして読み込むことができます。
import { ReactComponent as Hart } from './assets/hart.svg';
export function App() {
return (
<Hart style={{stroke:'gray', fill:'lightblue', width:'300px', height:'300px'}}/>
);
}
viteで作成したreactアプリは、デフォルトで svg ファイルをコンポーネントとして読み込むことができません。
そこで svg ファイルをコンポーンネントとして読み込むためのライブラリをインストールします。
ライブラリはたくさんありますが、2022年3月16日時点で主要そうなところをピックアップしました。
no | plugin | Weekly Downloads | Unpacked Size | Last publish | Git Star |
---|---|---|---|---|---|
1 | vite-plugin-svgr | 29,992 | 6.44 kB | 2 months ago | 93 |
2 | vite-plugin-react-svg | 11,253 | 5.75 kB | a year ago | 91 |
3 | Vite SVG loader | 10,762 | 175 kB | 2 months ago | 134 |
- 「vite-plugin-svgr」はURL、コンポーネントとして、svg ファイルを importすることができます。
importの書き方は、create-react-appで作成したアプリと同じです。
import { ReactComponent as MyIcon } from './my-icon.svg'
- 「vite-plugin-react-svg」 は1年ほど前から更新が止まってるようなのでパスします。
- 「Vite SVG loader」はURL、文字列、コンポーネントとして、svg ファイルを importすることができます。
パッケージサイズが大きいのが気になります。
// 接尾辞「?url」を使用して、URLとしてインポートする
// '/assets/my-icon.2d8efhg.svg'
import iconUrl from './my-icon.svg?url'
// 接尾辞「?raw」を使用して、文字列としてインポートする
// '<?xml version="1.0"?>...'
import iconRaw from './my-icon.svg?raw'
// 接尾辞「?component」を使用して、コンポーネントとしてインポートする
// <IconComponent />
import IconComponent from './my-icon.svg?component'
文字列としてファイルを読み込む要件はありませんので、「1.vite-plugin-svgr」を採用しました。
vite-plugin-svgr の導入
Vite + React + typescript に vite-plugin-svgr を導入します。
インストール
npm install vite-plugin-svgr --save-dev
2022年3月16日時点で vite-plugin-svgr は v1.0.1です。
vite.config.ts
vite.config.ts に下記項目を追加します。
古い書き方
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
+ const svgrPlugin = require('vite-plugin-svgr')
// https://vitejs.dev/config/
export default defineConfig({
resolve: {
alias: [{ find: '@', replacement: '/src' }]
},
plugins: [
react({
jsxImportSource: '@emotion/react'
}),
+ svgrPlugin({
+ svgrOptions: {
+ icon: true,
+ // ...svgr options (https://react-svgr.com/docs/options/)
+ }
+ })
]
})
2022/05/17 追記 新しい設定内容
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
+ import svgr from 'vite-plugin-svgr'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
+ svgr()
]
})
tsconfig.json
tsconfig.json に下記項目を追加します。
"compilerOptions": {
・・・
+ "types": ["vite-plugin-svgr/client"]
},
2022/04/19 追記
tsconfig.json の typesを指定すると、jestなどのテストライブラリが型情報を読み込めずエラーになります。
下記のようにjest関連のパッケージも読み込むように設定します。
"types": [ "node", "jest", "@testing-library/jest-dom", "vite-plugin-svgr/client"]
デフォルトでは、node_modules/@types の全ての型情報のパッケージがコンパイル時にインクルードされます。
tsconfig.json の types に指定すると、指定したものだけが読み込まれるため、vite-plugin-svgr/client
以外に必要な型情報パッケージがあれば、個別に追記する必要があります。
動作確認
App.tsxでsvgファイルを読み込んでみます。
create-react-appで作成したアプリと同じ書き方で svg ファイルが読み込めます。
import { ReactComponent as Hart } from './assets/hart.svg';
export function App() {
return (
<Hart style={{stroke:'gray', fill:'lightblue', width:'300px', height:'300px'}}/>
);
}
Discussion