
Очень часто при разработке React-приложения нам приходится работать с большим количеством иконок в проекте. Наверное, каждый разработчик стремится максимально упростить и автоматизировать подобные рутинные задачи. Есть несколько способов работы с иконками в веб-приложениях, но я хочу поделиться с вами именно тем, который кажется мне наиболее удобным. Данная статья поможет frontend-разработчику сделать работу с иконками комфортнее, используя их в качестве React-компонентов.
Для чего это нужно?
Наши иконки будут встраиваться напрямую в HTML-разметку в виде svg-элементов, что позволит в свою очередь взаимодействовать с их атрибутами и стилями. Также все иконки будут импортироваться из одного компонента, тем самым сохранив наши импорты в чистоте и порядке.

Как это реализовать?
Для того, чтобы развернуть подобную систему иконок, нам потребуется использовать пакет SVGR, который как раз и отвечает за основное преобразование svg-иконки в react-компонент.
Шаг 1
Первым шагом в проекте необходимо создать папку, где у нас будут храниться исходные svg-иконки, например src/assets/icons.
Шаг 2
Устанавливаем SVGR согласно официальной документации, либо копируем эту строчку в командную строку:
npm install --save-dev @svgr/cli
Шаг 3
После того, как мы установили необходимые пакеты, нам нужно в корне проекта создать файл с названием svgr.config.js. В конфиге нам необходимо указать конечную папку, где будут храниться преобразованные иконки в виде компонентов и задать шаблон того вида, как будут выглядеть итоговые компоненты. Более подробнее про настройку шаблона можно прочесть также в официальной документации.
// svgr.config.js const path = require('path'); const outDir = './src/ui/icons'; // путь, до папки, где будут храниться преобразованные иконки // Шаблон компонента с иконкой const iconTemplate = (variables, { tpl }) => tpl` ${variables.imports}; ${variables.interfaces}; const ${variables.componentName} = (${variables.props}) => ( ${variables.jsx} ); ${variables.exports}; `; // Шаблон файла index.js, который будет экспортировать все сгенерированные компоненты иконок function indexTemplate(files) { const compoundExportEntries = []; const importEntries = files.map(file => { const componentName = path.basename(file.path, path.extname(file.path)); compoundExportEntries.push(componentName); return `import { default as ${componentName} } from './${componentName}';`; }); return `${importEntries.join('\n')} export const Icons = { ${compoundExportEntries.join(',\n ')} }; `; } // Базовая настройка конфига module.exports = { outDir, icon: true, typescript: false, replaceAttrValues: { '#000': 'currentColor', }, indexTemplate, template: iconTemplate, };
Шаг 4
Всё, что осталось сделать — это обновить список npm-команд. Нам нужно добавить новую команду, которая будет запускать SVGR-преобразование, например npm run icons. Для удобства добавим выполнение этой команды каждый раз, когда мы собираем билд или запускаем наш проект, чтобы на этих этапах у нас всегда были актуальные компоненты иконок.
// package.json ... "icons": "svgr ./src/assets/icons", "dev": "npm run icons && webpack serve", "build": "npm run icons && webpack --config somebuild.webpack.js"
Также рекомендую добавить папку с преобразованными иконками в .gitignore, так как при каждом запуске проекта у нас файлы будут генерироваться заново и нет особого смысла тянуть их в репозиторий.
Заключение

Данную систему можно расширять и модифицировать, например вы можете прикрутить какой-нибудь небольшой gulp-скрипт, который будет следить за папкой с исходными svg-иконками и автоматически запускать преобразование, обновляя при этом компоненты. Но даже такой версии будет достаточно для комфортного взаимодействия с иконками, позволяя избегать дубликатов и использовать более удобный импорт в виде компонентов.
