[React] svg ํ์ผ → ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ๋ณํํ๊ธฐ - React SVGR
๊ธฐ๋ณธ ์ฌ์ฉ๋ฒ
์ค์น
yarn add "@svgr/cli"
yarn add -D "@svgr/webpack"
CLI ๋ช ๋ น์ด
๐ก ๊ฒฝ๋ก๋ง ์
๋ ฅํ๋ฉด svg path๋ฅผ ์ง์ ํ๋ ๊ฒ๊ณผ ๋์ผ. --
double dash๋ ์ปค๋งจ๋ ์ต์
์ด ๋๋๋ค๋๊ฑธ ์๋ฏธํ๋ฏ๋ก(์ฐธ๊ณ ๊ธ) --
๋ค์ ๊ฒฝ๋ก๋ฅผ ์
๋ ฅํ๋ฉด svg path๊ฐ ์ง์ ๋จ(์ต์
์ด ์๋ค๋ฉด ๊ตณ์ด ์๋ถ์ฌ๋ ๋จ).
# config ํ์ผ์ด ์์ ๋
# svgr <svg-path> -d <output-path>
svgr ./assets/icons/raw/bulb.svg -d ./assets/icons/dist
# config ํ์ผ์ด ์์ ๋
# svgr --config-file <config-file-path> <svg-path> -d <output-path>
svgr --config-file ./svgr.config.js ./assets/icons/raw/bulb.svg -d ./assets/icons/dist
# config ํ์ผ์ output ๊ฒฝ๋ก๋ฅผ ์ค์ ํ์ ๋
svgr --config-file ./svgr.config.js -- ./assets/icons/raw/bulb.svg
# config ํ์ผ์ output ๊ฒฝ๋ก๋ฅผ ์ค์ ํ๊ณ , ํน์ ํด๋(์๋์์ raw)์ ์๋ ๋ชจ๋ svg๋ฅผ ๋ณํํ ๋
svgr --config-file ./svgr.config.js -- ./assets/icons/raw
๐ก package.json
ํ์ผ scripts
์์ฑ์ ์๋์ฒ๋ผ ๋ฑ๋กํด๋๊ณ ์ฌ์ฉํ๋ฉด ํธ๋ฆฌํ๋ค. ์๋ ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ฉด(npm run generate
) ./assets/icons/raw
(svg path) ํด๋์ ์๋ ๋ชจ๋ svg ํ์ผ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ณํํ ํ svgr.config.js ์ค์ ํ์ผ์(outDir ์์ฑ) ๋ช
์ํ output ํด๋์ ์ ์ฅํ๋ค. svg path๋ ํ๋ก์ ํธ์์ ์ฌ์ฉํ๋ ์ ์ ํ output ๊ฒฝ๋ก๋ฅผ ์
๋ ฅํ๋ค.
// package.json (./assets/icons/raw ์ ์๋ ๋ชจ๋ svg ํ์ผ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ณํ)
"scripts": {
// ...
"generate": "svgr --config-file ./svgr.config.js -- ./assets/icons/raw"
},
์์ฑ ์์
์ง์ ํ output ๊ฒฝ๋ก์ SVG ๋ฆฌ์กํธ ์ปดํฌ๋ํธ ํ์ผ๊ณผ export ํ ์ ์๋ index.ts ํ์ผ์ด ์๋์ผ๋ก ์์ฑ๋๋ค.
// ๋ณํ๋ svg ์ปดํฌ๋ํธ ์์ — assets/icons/dist/MagnifierOutlined.tsx
import * as React from 'react';
import { SVGProps } from 'react';
const SvgMagnifierOutlined = (props: SVGProps<SVGSVGElement>) => (
// svg ์ธ๋ถ ๋ด์ฉ ์๋ต
<svg {...props}>
<path />
</svg>
);
export default SvgMagnifierOutlined;
// assets/icons/dist/index.ts ํ์ผ์ ๋ณํํ svg ์ปดํฌ๋ํธ๊ฐ ์๋ ์ถ๊ฐ๋๋ค
export { default as MagnifierOutlined } from './MagnifierOutlined';
export { default as Spinner } from './Spinner';
// ...
// ๋ค๋ฅธ ์ปดํฌ๋ํธ์์ import ์์
import { MagnifierOutlined } from '@/assets/icons/dist';
config ํ์ผ ์์
svgr.config
ํ์ผ์ js
ํ์ฅ์๋ง ์ฌ์ฉํ ์ ์๋ค.
// svgr.config.js
module.exports = {
icon: true, // use "1em" as width and height
typescript: true, // ํ์
์คํฌ๋ฆฝํธ ์ฌ์ฉ์ true
outDir: './assets/icons/dist', // output ๊ฒฝ๋ก
replaceAttrValues: {
// ์์ฑ ๊ฐ์ด #282829๋ฉด ๋ชจ๋ currentColor๋ก ๋ณ๊ฒฝ๋จ
'#282829': 'currentColor',
},
};
NextJS์์ React ์ปดํฌ๋ํธ๋ก ๋ฐ๋ก import ํ๊ธฐ
์์์ ์ค๋ช ํ svgr ์ฌ์ฉ ๋ฐฉ๋ฒ์ svgr cli ํฐ๋ฏธ๋ ๋ช ๋ น์ด๋ฅผ ์ด์ฉํด svg ํ์ผ์ React ์ปดํฌ๋ํธ๋ก ๋ฏธ๋ฆฌ ๋ง๋ค์ด๋๊ณ ์ฌ์ฉํ๋ ๋ฐฉ์์ด๋ค. ํํธ, React CRA์์ ๋ณ๋ค๋ฅธ ์ค์ ์์ด ๊ทธ๋๊ทธ๋ ํ์ํ svg ํ์ผ์ React ์ปดํฌ๋ํธ๋ก ๋ถ๋ฌ์์ ์ฌ์ฉํ ์ ์๋๋ฐ(๋ฏธ๋ฆฌ ๋ณํ ์์ด), svgr์ ์ฌ์ฉํ๋ฉด NextJS์์๋ ๋์ผํ ๋ฐฉ๋ฒ์ผ๋ก ์ฌ์ฉํ ์ ์๋ค.
// svg ํ์ผ → ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฌ์ค๊ธฐ ์์ — React CRA
import { ReactComponent as BulbIcon } from './assets/icons/bulb.svg';
// ์ปดํฌ๋ํธ ๋ฆฌํด๋ฌธ
return <BulbIcon />;
NextJS์์ svg ํ์ผ์ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฌ์์ ๋ฐ๋ก ์ฌ์ฉํ ์ ์๋๋ก ํ๊ธฐ ์ํด next.config.js
์ค์ ํ์ผ์ ์๋ ๋ด์ฉ์ ์ถ๊ฐํ๋ค. config ํ์ผ ์์ ํ์ ์ดํ๋ฆฌ์ผ์ด์
์ ์ฌ์์ํด์ผ ์ ์ฉ๋๋ค.
// NextJS ์ฌ์ฉ์ — next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// ...
webpack(config) {
config.module.rules.push({
test: /\.svg$/,
use: ['@svgr/webpack'],
});
return config;
},
};
module.exports = nextConfig;
์ด ๋ฐฉ๋ฒ์ svgr cli๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฏ๋ก @svgr/cli
ํจํค์ง๋ ์ค์นํ์ง ์์๋ ๋๋ค(๋ฌผ๋ก @svgr/webpack
ํจํค์ง๋ ์ค์นํด์ผ ๋๋ค). ์ฐธ๊ณ ๋ก svgr.config.js
ํ์ผ์ ์ญ์ ํด์ผ ์ ์์ ์ผ๋ก ์๋ํ๋ค.
// svg ํ์ผ → ๋ฆฌ์กํธ ์ปดํฌ๋ํธ๋ก ๋ถ๋ฌ์ค๊ธฐ ์์ — NextJS
import BulbIcon from '@/assets/icons/raw/bulb.svg';
// ์ปดํฌ๋ํธ ๋ฆฌํด๋ฌธ
return <BulbIcon />;
CLI ์ต์
๊ตฌ๋ฌธ: svgr [options] <file|directory>
์์: svgr --replace-attr-values "#fff=currentColor" icon.svg
์ต์ ํ๋๊ทธ | ์ค๋ช |
-V, --version | output the version number |
--config-file <file> | specify the path of the svgr config |
--no-runtime-config | disable runtime config (".svgrrc", ".svgo.yml", ".prettierrc") |
-d, --out-dir <dirname> | output files into a directory |
--ignore-existing | ignore existing files when used with --out-dir |
--ext <ext> | specify a custom file extension (default: "js") |
--filename-case <case> | specify filename case ("pascal", "kebab", "camel") (default: "pascal") |
--icon | use "1em" as width and height |
--native | add react-native support with react-native-svg |
--memo | add React.memo into the result component |
--ref | forward ref to SVG root element |
--no-dimensions | remove width and height from root SVG tag |
--expand-props [position] | disable props expanding ("start", "end", "none") (default: "end") |
--svg-props <property=value> | add props to the svg element |
--replace-attr-values <old=new> | replace an attribute value |
--template <file> | specify a custom template to use |
--index-template <file> | specify a custom index.js template to use |
--no-index | disable index file generation |
--title-prop | create a title element linked with props |
--prettier-config <fileOrJson> | Prettier config |
--no-prettier | disable Prettier |
--svgo-config <fileOrJson> | SVGO config |
--no-svgo | disable SVGO |
--silent | suppress output |
--stdin | force reading input from stdin |
--stdin-filepath | path to the file to pretend that stdin comes from |
-h, --help | output usage information |
๊ธ ์์ ์ฌํญ์ ๋ ธ์ ํ์ด์ง์ ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๋ฐ์๋ฉ๋๋ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํด ์ฃผ์ธ์
'๐ช Programming' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๋๊ธ
์ด ๊ธ ๊ณต์ ํ๊ธฐ
-
๊ตฌ๋
ํ๊ธฐ
๊ตฌ๋ ํ๊ธฐ
-
์นด์นด์คํก
์นด์นด์คํก
-
๋ผ์ธ
๋ผ์ธ
-
ํธ์ํฐ
ํธ์ํฐ
-
Facebook
Facebook
-
์นด์นด์ค์คํ ๋ฆฌ
์นด์นด์ค์คํ ๋ฆฌ
-
๋ฐด๋
๋ฐด๋
-
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
๋ค์ด๋ฒ ๋ธ๋ก๊ทธ
-
Pocket
Pocket
-
Evernote
Evernote
๋ค๋ฅธ ๊ธ
-
[React] ๋ฆฌ์กํธ ์ฟผ๋ฆฌ(React Query) staleTime์ ์ค์ ํ๋ 3๊ฐ์ง ๋ฐฉ๋ฒ
[React] ๋ฆฌ์กํธ ์ฟผ๋ฆฌ(React Query) staleTime์ ์ค์ ํ๋ 3๊ฐ์ง ๋ฐฉ๋ฒ
2024.05.12 -
[Git] ๋ณํฉ(Merge) ์ถฉ๋ ๋ฐฉ์ง๋ฅผ ์ํ ๋ฆฌ๋ฒ ์ด์ค Rebase
[Git] ๋ณํฉ(Merge) ์ถฉ๋ ๋ฐฉ์ง๋ฅผ ์ํ ๋ฆฌ๋ฒ ์ด์ค Rebase
2024.05.12 -
[React] ๋ฆฌ์กํธ Context API ๋ ๋๋ง ์ต์ ํํ๊ธฐ
[React] ๋ฆฌ์กํธ Context API ๋ ๋๋ง ์ต์ ํํ๊ธฐ
2024.05.11 -
[HTML/CSS] form ์ธ๋ถ์์ form ์ฐ๊ฒฐ / document ๊ฐ์ฒด๋ก form ์ ๊ทผํ๊ธฐ
[HTML/CSS] form ์ธ๋ถ์์ form ์ฐ๊ฒฐ / document ๊ฐ์ฒด๋ก form ์ ๊ทผํ๊ธฐ
2024.05.11