Привет, Хабр! Меня зовут Артём Поморцев. Я фронтенд-разработчик компании «Криптонит» и хочу поделиться своим опытом создания набора иконок (icon pack).
Скажу сразу, что иконочные шрифты не всегда являются наиболее эффективным и надёжным вариантом, но они по-прежнему относительно просты и легки в реализации.
Проблема
Наша проблема заключалась в том, что мы переходили на новый дизайн. Тогда мы работали с фреймворком blueprint.js, и он не всегда отвечал требованиям UX-дизайнеров. Также было желание сделать собственный пакет иконок, который можно было бы легко дополнять и изменять по мере необходимости.
Решение
Первоначально мы попробовали использовать другие пакеты иконок, такие как FontAwesome, Vue-Unicons и HeroIcons. Однако дизайнерам они тоже не подошли, поэтому мы решили подготовить собственный пакет иконок. Поначалу хотелось найти готовое программное решение, в которое можно добавить файлы SVG и билдить со спокойной душой. Этого не нашлось, поэтому мы решили собрать его из двух библиотек: svgtofont и SVGO.
1) svgtofont

svgtofont — это библиотека для генерации иконочных шрифтов из файлов SVG. Документация объёмная, поэтому расскажу лишь о самых интересных возможностях:
outSVGReact — передача из SVG в React-компонент;
outSVGReactNative — передача из SVG в компонент React Native;
outSVGPath — возможность конвертации SVG в CSS-полигон;
startUnicode — код символа, с которого стартует шрифт;
useCSSVars — возможность использования CSS-переменных.
Также svgtofont поддерживает свойства svgicons2svgfont.
Быстрая настройка для проекта (package.json)

С svgtofont возникли проблемы. Главная из них состояла в том, что иконки заполнялись, когда не следует, или вообще не отображались (об этом расскажу ниже).
2) SVGO
SVGO — это оптимизатор SVG, избавляющий файл от метаданных — обычно ненужной информации, которая заложена в различных дизайн-тулзах. Поэтому первым делом я решил использовать его, чтобы решить проблемы с пустыми иконками, а заодно уменьшить размер файлов SVG. В SVGO можно указывать, что вам конкретно нужно убрать, начиная от удаления декларации XML, до атрибутов. В нём есть работа со стилями и классами, поэтому SVGO подойдёт для всех уровней оптимизации. Подробнее ознакомиться с его возможностями вы можете в документации.
Быстрая настройка для проекта (package.json)

SVGO запускает под капотом оптимизацию файлов.
--folder ./svg — указывается входная папка.
-o или --output — выходной файл или папка (по умолчанию такая же, как и входная).
./svg_generated — папка с оптимизированными SVG-файлами.
С SVGO тоже возникла проблема. При билде или запуске проекта каждый раз генерировался новый иконочный ��рифт. Он менял свой идентификатор, поэтому при переходе на новую версию ломались иконки. Эта проблема решилась быстро. Мы просто поменяли конечную папку, в которую записали оптимизированные файлы SVG для того, чтобы не было перезаписи исходных.
В результате применения SVGO размер пакета уменьшился на 19%

Так в чём же была проблема с отображением иконок?
Причина этой проблемы — алгоритм, используемый для определения внутренней части фигуры. Алгоритм задаётся атрибутом fill-rule тега <path> внутри SVG. Значение по умолчанию: «nonzero». Есть ещё одно значение «evenodd», которое поддерживается редко.
Если вы просто удалите атрибут, направление пути d будет таким же. Поэтому нужно изменить направление путей самостоятельно. Вот как решить эту проблему:
1. Скачайте Fill Rule Editor:

2. Перетащите или вставьте значок SVG, шрифт которого выглядит странно, и откройте плагин:

3. Нажимаем на SVG:

4. А теперь, чтобы это исправить, нажмите на внутренний или внешний контур:

Проблема решена!
Полный билд сборки:

Результат:

Итоги:

Размер упакованного пакета: 485 Кб
Размер проекта после распаковки: 1.75 Мб
Количество файлов SVG: 400
