Система иконок на React
- четверг, 7 марта 2024 г. в 00:00:20
Очень часто при разработке React-приложения нам приходится работать с большим количеством иконок в проекте. Наверное, каждый разработчик стремится максимально упростить и автоматизировать подобные рутинные задачи. Есть несколько способов работы с иконками в веб-приложениях, но я хочу поделиться с вами именно тем, который кажется мне наиболее удобным. Данная статья поможет frontend-разработчику сделать работу с иконками комфортнее, используя их в качестве React-компонентов.
Наши иконки будут встраиваться напрямую в HTML-разметку в виде svg-элементов, что позволит в свою очередь взаимодействовать с их атрибутами и стилями. Также все иконки будут импортироваться из одного компонента, тем самым сохранив наши импорты в чистоте и порядке.
Для того, чтобы развернуть подобную систему иконок, нам потребуется использовать пакет SVGR, который как раз и отвечает за основное преобразование svg-иконки в react-компонент.
Первым шагом в проекте необходимо создать папку, где у нас будут храниться исходные svg-иконки, например src/assets/icons
.
Устанавливаем SVGR согласно официальной документации, либо копируем эту строчку в командную строку:
npm install --save-dev @svgr/webpack @svgr/cli @svgr/core
После того, как мы установили необходимые пакеты, нам нужно в корне проекта создать файл с названием 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,
};
Всё, что осталось сделать — это обновить список 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-иконками и автоматически запускать преобразование, обновляя при этом компоненты. Но даже такой версии будет достаточно для комфортного взаимодействия с иконками, позволяя избегать дубликатов и использовать более удобный импорт в виде компонентов.