๋ฐ˜์‘ํ˜•

๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•


์„ค์น˜

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

 


๊ธ€ ์ˆ˜์ •์‚ฌํ•ญ์€ ๋…ธ์…˜ ํŽ˜์ด์ง€์— ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ•ด ์ฃผ์„ธ์š”
๋ฐ˜์‘ํ˜•