Привет, Хабр! Меня зовут Анатолий Долгов и я frontend-разработчик международной команды Учи.ру. Сегодня я расскажу, как мы успешно синхронизировали параметры дизайна и кода. Это упростило многие рабочие моменты, уменьшило количество неприятных ошибок и сделало нас ближе к внедрению полноценной дизайн-системы.
Проблема
Нам предстояло синхронизировать дизайн-макеты в Figma с кодовой базой и значениями стилей. Так как ранее не было единой точки, из которой можно было бы брать эти параметры, возникали проблемы из-за дублей и несостыковок. Например, не всегда были актуальны дизайн-макеты. Эти проблемы кажутся незначительными, но когда их много, они сильно замедляют разработку и отнимают время как у дизайнеров, так и у разработчиков. Вручную менять свойства сотен элементов — это большая боль и трата времени.
В какой-то момент наш продуктовый дизайнер Леонид Лукин предложил внедрить токены, или компоненты. Это сущность из Figma — переменные с определенными значениями, которые используются во всех макетах и хранятся в единой точке у дизайнеров. То есть все фирменные цвета, размеры, отступы, сетки и так далее. Таким образом, мы поняли, что можем сделать процесс универсальным, хотя бы на уровне мелких постоянных.
Конкретные действия
Нам нужно было импортировать токены в код. Причем сделать это в двух версиях: для стилей и для скриптов в JavaScript. Мы решили не изобретать велосипед и нашли готовое решение. Это плагин Figma Tokens, который умеет выгружать из базы токенов нужные значения в произвольном и гибко настраиваемом формате. С его помощью можно сформировать большой JSON-файл, а затем настроить структуру и поместить токены не в один файл, а в несколько. Например, сделать файлы отдельно для цветов, размеров и breakpoints. Также есть возможность создать собственные кастомные файлы, гибко загружать их в рабочий репозиторий и далее генерировать конечные файлы JS и CSS.
Чтобы все было полностью автоматизировано, помимо этого плагина нужно было добавить какой-то action, который при любом изменении токенов мог бы автоматически пересоздавать JSON-файлы и отправлять изменения в репозиторий. Мы со своей стороны просто автоматически бы их принимали, чтобы затем подменялись значения существующих переменных. Таким образом можно было бы изменять эти значения в коде без участия разработки. Мы внедрили такую автоматизацию не до конца, сделав только часть дизайна и отдельный пакет с этими токенами, которые хранятся у нас сейчас.
Немного расскажу об устройстве архитектуры. Наше приложение сейчас представляет собой монорепозиторий. В нем находятся несколько общих пакетов, которые используются везде, а также наше основное приложение. Например, общим пакетом у нас является UI Kit, библиотека визуальных компонентов. Мы вынесли некоторые общие части в пакеты в процессе перехода на микрофронтенды, решив, что в рамках этого удобно создать такой же отдельный пакет для токенов. Он представляет собой тот самый скрипт, о котором я говорил ранее.
Чтобы внедрить эту систему, нужно сначала решить проблему с совместимостью. У нас имелся набор кастомных значений, который мы сами переносили из макета на протяжении всего процесса разработки. И был файл с переменными, которые назывались случайным образом, без какой-либо системы. Предстояло мягко подменить все значения по всей кодовой базе. А их было очень-очень много.
Мы придумали промежуточное решение, проксировав существующие значения теми, которые импортировались из этих токенов. Вместо своих названий переменных мы назначали им имена токенов, которые выгружались из Figma. То есть, в коде они остались такими же, но значения уже стали подгружаться из этого дизайнерского файла.
Взгляд с другой стороны
По словам нашего продакт-дизайнера Леонида Лукина, для дизайнера все выглядит следующим образом. В меню Figma появляется пункт «Экспортировать как JSON». После нажатия токены сохраняются в файл, который дизайнер отправляет разработчикам. Файл помещается в пакет с токенами, где работает скрипт сборки. Он обрабатывает его и возвращает на выходе файлы JS и CSS. Оба они содержат одинаковые значения, которые можно использовать при решении других задач.
Таким образом, мы избавляем от огромного количества лишней работы дизайнера, frontend-разработчика и тестировщика. Если мы внесли куда-либо одно изменение, далее оно будет отображаться автоматически. Нам достаточно сделать тест только один раз, в том месте, куда мы вносили изменение.
Визуально наш продукт выглядит достаточно консистентно. Пользователи видят, что у нас нет множества разных элементов, которые не сочетаются друг с другом, все они подчинены единому стилю. При создании нового макета используются визуально гармонирующие между собой элементы.
По нашим общим ощущениям, теперь работа стала более прозрачной. Например, исчезли ситуации, когда в макете есть отступ, которого нет в коде. У нас есть понимание, что является фирменным элементом дизайна, а что — нет. Мы используем токен и универсально настраиваем все элементы через одну точку.
Планы
Мы хотели сделать этот процесс еще проще для дизайнера с помощью скрипта, который мог бы самостоятельно забирать JSON-файлы из Figma и заливать их в репозиторий. Затем происходил бы автоматический pull request, после чего разработка одобряла его. Дизайнеру в этом случае не надо даже нажимать на пункт меню «Экспортировать как JSON». Возможно, мы это реализуем в будущем.
Но определенные улучшения у нас уже есть. Мы добавили кастомные токены, они никак не привязаны к нашим макетам в Figma, но нам как разработчиками удобно их использовать. Это, например, специфичные значения высоты шапки, которые очень часто используются в коде, но не являются общей сущностью с точки зрения макета.
Мы планируем в будущем создать так называемую Витрину. Для этого мы используем плагин Storybook. Из всех подобных решений он наиболее удобен для нас. «Витрина» — это база токен-компонентов, которая будет доступна всем, кто занимается разработкой. Мы планируем, таким образом, создать полноценную работающую дизайн-систему — свод правил для дизайнеров, разработчиков и тестировщиков.
Это библиотека, которая позволяет отрисовать любой компонент без кода. При этом, она содержит информацию, как динамически меняются разные значения параметров компонента и как они визуально трансформируются. Когда мы внедрим это решение, у нас появится законченная связь дизайна с кодом.
Как вам наш вариант? Как у вас на работе решают проблему связи дизайна и кода?