{
    "version": "https:\/\/jsonfeed.org\/version\/1",
    "title": "Блог Михаила Озорнина: заметки с тегом continuous integration",
    "_rss_description": "Главная · Блог · Работы ·",
    "_rss_language": "ru",
    "_itunes_email": "",
    "_itunes_categories_xml": "",
    "_itunes_image": "",
    "_itunes_explicit": "",
    "home_page_url": "https:\/\/mikeozornin.ru\/blog\/tags\/continuous-integration\/",
    "feed_url": "https:\/\/mikeozornin.ru\/blog\/tags\/continuous-integration\/json\/",
    "icon": "https:\/\/mikeozornin.ru\/blog\/user\/userpic@2x.jpg?1614204384",
    "author": {
        "name": "Михаил Озорнин",
        "url": "https:\/\/mikeozornin.ru\/blog\/",
        "avatar": "https:\/\/mikeozornin.ru\/blog\/user\/userpic@2x.jpg?1614204384"
    },
    "items": [
        {
            "id": "79",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/how-to-build-icon-font-from-sketch-2\/",
            "title": "Как собрать шрифт с иконками — 2",
            "content_html": "<p class=\"lead\">С момента <a href=\"http:\/\/mikeozornin.ru\/blog\/all\/how-to-build-icon-font-from-sketch\/\">первого поста<\/a> я доработал схему сборки, расскажу что и зачем там сделано. Сначала будет вступление-рассказ о чем все это, если вы хотите нового, прокрутите до заголовка <a href=\"http:\/\/mikeozornin.ru\/blog\/all\/how-to-build-icon-font-from-sketch-2#new\" class=\"nu\">«<u>Новое в этой версии<\/u>»<\/a>.<\/p>\n<h2>Что вообще происходит<\/h2>\n<p>У дизайнера есть несколько разных способов передать иконки разработчику:<\/p>\n<ul>\n<li>отдельными файлами или спрайтом в ПНГ,<\/li>\n<li>отдельными файлами или спрайтом в СВГ,<\/li>\n<li>иконочным шрифтом.<\/li>\n<\/ul>\n<p>Разработчики фронтенда все чаще привыкли использовать иконки в виде шрифта. Этим же способом распространяются популярные иконочные наборы (например, Font Awesome). У нас в компании разработчики тоже просят «дай шрифт». Мы некоторое время отлаживали схему сборки шрифта: как из файла Скетча автоматически получить файл, пригодный для фронтенда, не замучив дизайнера.<\/p>\n<p>Рассказ может быть полезен разработчикам фронтенда и дизайнерам интерфейсов. В меньшей степени он будет полезен бекендным разработчикам интерфейсов (классический ASP.NET MVC или что-то подобное): схема будет та же, но не будет готовых файлов конфигураций и скриптов. Если кто-то расскажет как прикрутить к этому NuGet, напишите, я добавлю.<\/p>\n<h2>Зачем это делать, есть же фонтелло<\/h2>\n<p>Есть много готовых сервисов, которые собирают шрифт по загруженным СВГ-файлам, например fontello. Мы не стали использовать ни один из них, потому что с ними могут быть сложности:<\/p>\n<p><b>Дизайнер может случайно сломать шрифт<\/b>. Если забыть и не экспортировать иконку, которую уже давал, то следующая версия шрифта будет без него и в неизвестном месте сломается интерфейс. Ситуацию усугубляет факт, что дизайнеров у каждого продукта несколько, а общий набор иконок пополняют 5-6 человек.<\/p>\n<p>Хорошее решение — простое, в нем минимум ручных действий.<\/p>\n<p><b>Нескольким дизайнерам работать непросто<\/b>. Если несколько дизайнеров поддерживают один шрифт, то возникает много вопросов синхронизации: где хранить исходники, файлы СВГ и файлы шрифта, кто собирает и кому передает, как не забыть иконку.<\/p>\n<p>Хорошее решение позволяет добавлять иконки скольким угодно дизайнерам так, что они не испортят чужую работу.<\/p>\n<p><b>Cложно интегрировать в общий процесс сборки продукта<\/b>. Отдельно стоящий сервис тяжело встроить в общий процесс разработки и сборки, а у кого-то есть еще и процесс CI. Придется вручную собирать сервисом файл, куда-то его загружать и как-то версионировать.<\/p>\n<p>Хорошее решение встраивается в процесс разработки.<\/p>\n<p><b>Не всех устраивает внешний сервис<\/b>. Многие компании не верят во внешние сервисы: они могут изменить набор функций, упасть во время подготовки релиза, стать платными или закрыться. В конце концов, их могут хакнуть. Мы — ИБ-компания, и каждый раз раздражать профессионально деформированных безопасников и разработчиков наличием внешнего сервиса не хочется.<\/p>\n<p>Хорошее решение работает внутри компании.<\/p>\n<p><b>Формируется не всё, что надо<\/b>. Некоторые сервисы выдают шрифт, а иконки кодируют номерами символов. К сожалению, на эти номера полагаться нельзя. Если убрать иконку или поменять порядок, то в следующий раз сервис может выдать совсем другие коды и все иконки непредсказуемо поменяются.<\/p>\n<p>Если не формировать вместе со шрифтом ЛЕСС-файл, то разработчикам придется в каждом использовании иконки указывать размер кегля, они могут забыть или ошибиться.<\/p>\n<p>Хорошее решение дает разработчикам все что нужно. Иконка кодируется понятным названием, коды символов и размер подставляются автоматически.<\/p>\n<h2>Новое в этой версии <span id=\"new\">&nbsp<\/span><\/h2>\n<p>Раньше я описывал схему сборки шрифта, которая позволяет автоматически собрать шрифтовой файл с иконками из исходника Скетча, сгенерировать для него демо-страницу и ЛЕСС-файл, а также опубликовать пакет в НПМ-репозиторий.<\/p>\n<p>В новой версии мы научились ещё два важных пункта: поставлять иконки в виде скетч-библиотеки и ТТФ-файла. Я пройдусь по каждому изменению, а в конце приложу итоговое решение.<\/p>\n<h3>Поставка иконок в виде библиотеки Скетча<\/h3>\n<p><aside class=\"aside-margin-right\"><span class=\"related-title\"><a href=\"https:\/\/medium.com\/ux-power-tools\/sketch-libraries-how-they-work-and-the-crazy-stuff-you-can-do-with-them-fc10f142ac80\">Описание работы библиотек<\/a><\/span><\/aside><\/p>\n<p>С момента написания того поста вышла новая версия Скетча — 47, в ней появились библиотеки символов. Иконки стало удобно вставлять в макеты именно с помощью библиотеки.<\/p>\n<p>Чтобы сделать один символ на одну иконку и не плодить их для каждого цвета, нужно сделать так:<\/p>\n<ol start=\"1\">\n<li>Сделайте по символу для каждого цвета, в которые у вас можно красить иконки.<\/li>\n<\/ol>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/icons-BG@2x.png\" width=\"557\" height=\"183\" alt=\"\" \/>\n<\/div>\n<ol start=\"2\">\n<li>Нарисуйте иконку и наложите её маской на символ цвета:<\/li>\n<\/ol>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/icon-in-library@2x.png\" width=\"368\" height=\"158\" alt=\"\" \/>\n<\/div>\n<p>После этого вы сможете менять цвет иконок через оверрайды:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/icon-in-library-2@2x.png\" width=\"376\" height=\"229\" alt=\"\" \/>\n<\/div>\n<p>Образец файла: <a href=\"https:\/\/github.com\/mikeozornin\/icon-font-public\/raw\/master\/iconset.sketch\">iconset.sketch<\/a><\/p>\n<p>К сожалению такой скетч-файл плохо собирался в шрифт. Это происходит из-за маски.<\/p>\n<p>Маска правильно экспортируется в СВГ-файл, но в шрифте нет понятия маски, в итоге иконки ломались. Долгое время я вел скетч-файл в двух вариантах: простые артборды для шрифта и такие же с маской для библиотеки. Но это плохой способ: нужно добавлять и изменять пары одинаковых иконкок. Из-за этого иногда были ошибки — я что-то где-то забывал.<\/p>\n<p>Неожиданно Акронис <a href=\"https:\/\/habrahabr.ru\/company\/acronis\/blog\/344454\/\">написал пост на Хабре<\/a> про свою дизайн-систему. С помощью их поста удалось сделать правильно. Сейчас наш сборщик регулярными выражениями вырезает лишнее из СВГ-файла и превращает файл с маской в обычный файл.<\/p>\n<p>Для вырезания лишнего я подключил grunt-text-replace, вот его конфиг:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">replace: {\r\n  remove_mask: {\r\n    src: [PATH_BUILD_ICONS + '\/*.svg'],\r\n     overwrite: true,  \/\/ overwrite matched source files\r\n     replacements: [\r\n      {from : \/ fill=&quot;(.*?)&quot;\/m,             to : ''},\r\n      {from : \/(\\s*)&lt;\\\/defs[\\s\\S]*&lt;\\\/g&gt;\/m,  to : ''},\r\n      {from : \/(\\s*)&lt;defs&gt;\/m,               to : ''},\r\n      {from : \/ id=&quot;(.*?)&quot;\/m,               to : ''},\r\n      {from : \/xmlns:xlink=&quot;(.*?)&quot;\/m,       to : ''},\r\n      {from : \/(\\s*)&lt;g[\\s\\S]*?&gt;\/m,          to : ''},\r\n      {from : \/(\\s*)&lt;\\\/g&gt;\/m,                to : ''},\r\n      {from : \/&lt;svg\/m,                      to : '&lt;svg fill=&quot;#000&quot;'},\r\n      {from : \/ transform=&quot;(.*?)&quot;\/m,        to : ''},\r\n      {from : \/ fill-rule=&quot;(.*?)&quot;\/m,        to : ''},]            \r\n    }\r\n  }<\/code><\/pre><h3>Поставка иконок в виде ТТФ-файла<\/h3>\n<p>У нас в компании есть команда технических писателей, которые пишут руководства по продуктам. В руководствах техписатели вставляют иконки, чтобы проиллюстрировать на что нужно нажать в интерфейсе.<\/p>\n<p>Раньше для вставки иконки они делали скриншот экрана, вырезали из него иконку и вставляли в руководство. Сказать, что это неудобный способ — ничего не сказать: растровые скриншоты плохо выглядят при печати; при изменении иконки нужно внимательно заменить все скриншоты с ней; сложно менять цвет иконок в растре, их приходится снимать в каждом цвете — это все увеличивает и без того большую работу.<\/p>\n<p>Редактор документации поддерживает вставку через СВГ, она решила бы почти часть этих проблем, но СВГ легко не перекрасить, и СВГ-картинки плохо выглядит при редактировании.<\/p>\n<p>Идеальным вариантом для них было бы использовать ТТФ-шрифт: он отлично рендерится на экране и при печати, хорошо автоматизируется и удобно перекрашивается.<\/p>\n<p>Однако недостаточно просто включить генерирование ТТФ-файла: по умолчанию коды символов формируются сборщиком автоматически. При следующем формировании шрифта код иконки мог замениться на произвольный. Если технический писатель вставлял иконку в документ, и обновлял шрифт, часть иконок могла непредсказуемо поменяться на другие. Так, конечно, никуда не годилось.<\/p>\n<p>В новой версии вместо автоматического выбора кодов символов я задаю их руками. Меинтейнер шрифтового репозитория (это я) выдает каждой новой иконке новый код и следит за тем, чтобы коды не менялись. Для этого используется секция codepoints в grunt-webfont. Каждой иконке нужно задать номер символа. У нас используется последовательная нумерация начиная с 0xF501.<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">codepoints : {\r\n   'upload-to-cloud_24' : 0xF501,\r\n   'upload-to-cloud_64' : 0xF502,\r\n},\r\nstartCodepoint: 0xF701,<\/code><\/pre><p>Иконкам, которым номер не выставлен вручную, код выберется автоматически. Вообще это неправильно и лучше следить, чтобы таких иконок не было. Чтобы найти такие иконки их пространство имен отличается, им выдается номер из пространства 0xF701+, поэтому они всегда будут в конце шрифта и их легко найти.<\/p>\n<p>Посмотреть коды символов можно с помощью <a href=\"http:\/\/opentype.js.org.\">http:\/\/opentype.js.org.<\/a> Выбираете Glyph Inspector, загружаете шрифт и смотрите:<\/p>\n<div class=\"e2-text-picture\">\n<img src=\"https:\/\/mikeozornin.ru\/blog\/pictures\/opentype.js@2x_1.png\" width=\"1886\" height=\"1398\" alt=\"\" \/>\n<\/div>\n<p>Наши писатели перешли на ТТФ-файл и довольны.<\/p>\n<div class=\"post-summary\"><div class=\"post-summary__header\"><p>Скачать и посмотреть<\/p>\n<\/div><div class=\"post-summary__text\"><p>Я обновил репозиторий решения, там есть пример файла и сборщик. Чтобы понять как и что — прочитайте README.md. Скачивайте и смотрите:<br \/>\n<a href=\"https:\/\/github.com\/mikeozornin\/icon-font-public\">https:\/\/github.com\/mikeozornin\/icon-font-public<\/a><\/p>\n<\/div><\/div><h2>Что дальше<\/h2>\n<p>Наша схема сейчас покрывает нужны дизайнеров, фронтендеров и технических писателей. Немного не хватает нормального предпросмотра шрифта (пока не хватает времени доделать). Напишу, если будет что показать.<\/p>\n<p>С вопросами, багрепортами или советами — в телеграм <a href=\"http:\/\/t.me\/mikeozornin\">@mikeozornin<\/a> или на почту <a href=\"mailto:mike.ozornin@gmail.com\">mike.ozornin@gmail.com<\/a>.<\/p>\n",
            "date_published": "2018-01-09T12:12:15+03:00",
            "date_modified": "2018-12-16T01:05:57+03:00",
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/icon-font-cover-2@2x.png",
            "_date_published_rfc2822": "Tue, 09 Jan 2018 12:12:15 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "79",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/icon-font-cover-2@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/icons-BG@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/icon-in-library@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/icon-in-library-2@2x.png",
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/opentype.js@2x_1.png"
                ]
            }
        },
        {
            "id": "54",
            "url": "https:\/\/mikeozornin.ru\/blog\/all\/how-to-build-icon-font-from-sketch\/",
            "title": "Как собрать шрифт с иконками",
            "content_html": "<p class=\"lead\">Разработчики иногда просят иконки не в пнг или свг, не пнг-спрайтом, а в шрифте. Им проще его так использовать. В посте я расскажу как из скетч-файла собрать шрифт, чтобы всем было удобно в будущем.<\/p>\n<p class=\"lead\">UPD. Появилась <a href=\"http:\/\/mikeozornin.ru\/blog\/all\/how-to-build-icon-font-from-sketch-2\/\">более новая версия сборки<\/a><\/p>\n<h2>Зачем это делать, есть же фонтелло<\/h2>\n<p>Есть много сервисов, которые собирают шрифт из загруженных свг-файлов. Зачем придумывать что-то своё?<\/p>\n<ul>\n<li><b>Чтобы случайно не сломать шрифт<\/b>. Если забыть иконку, которую уже выдавал и не загрузить в фонтеллу, то она не попадет в новый шрифт и где-то в интерфейсе пропадет иконка.<\/li>\n<li><b>Подойдет, если дизайнеров несколько<\/b>. Если дизайнеров в команде несколько, то нужна синхронизация между ними. Было бы круто, если бы каждый мог добавлять в шрифт иконки и не сломать чужой результат.<\/li>\n<li><b>Легко встраивается в ваш CI-процесс<\/b>.<\/li>\n<li><b>Не всех устраивает внешний сервис<\/b>. Внешний сервис может быть недоступен, он может внезапно обновиться, стать платным, и вообще не все готовы отдавать наружу свои иконки.<\/li>\n<li><b>Разработчику сразу формируется и less-файл<\/b>. Обмениваться кодами символов неудобно, они генерируются автоматически и могут измениться, использовать css-класс надежно, он не поменяется.<\/li>\n<\/ul>\n<h2>Вариант 1. Собираем и отдаём шрифт<\/h2>\n<p>Я выложил все необходимые файлы в репозиторий <a href=\"https:\/\/github.com\/mikeozornin\/icon-font-public\">icon-font-public<\/a>, скачайте его и распакуйте куда-нибудь.<br \/>\nСкачать: <a href=\"https:\/\/github.com\/mikeozornin\/icon-font-public\/archive\/master.zip\">https:\/\/github.com\/mikeozornin\/icon-font-public\/archive\/master.zip<\/a><\/p>\n<h3>Шаг 1. Настраиваем среду<\/h3>\n<p>Все эти заклинания надо произнести один раз, дальше не понадобятся<\/p>\n<p>1) Установить <a href=\"http:\/\/brew.sh\/index_ru.html\">brew<\/a>. Brew — это такой менеджер пакетов, который легко позволяет ставить программы и библиотеки. Выполнить в терминале команду:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">\/usr\/bin\/ruby -e &quot;$(curl -fsSL https:\/\/raw.githubusercontent.com\/Homebrew\/install\/master\/install)&quot;<\/code><\/pre><p>2) С помощью brew установить шрифтообработчики:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">brew install ttfautohint fontforge --with-python<\/code><\/pre><p>3) Установить node.js, скачать тут <a href=\"https:\/\/nodejs.org\/en\/\">https:\/\/nodejs.org\/en\/<\/a> current-версию.<\/p>\n<p>4) Установить SketchTool<br \/>\nПри установленном Sketch выполнить в терминале команду:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">\/Applications\/Sketch.app\/Contents\/Resources\/sketchtool\/install.sh<\/code><\/pre><p>5) Установить grunt<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">npm install -g grunt-cli<\/code><\/pre><h3>Шаг 2. Сборка файла шрифта<\/h3>\n<p>Для сборки шрифт нужно произнести в терминале заклинание:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">.\/build.sh<\/code><\/pre><p>Если в первый раз не сработает, сделайте скрипт выполняемым:<\/p>\n<pre class=\"e2-text-code\"><code class=\"\">chmod +x build.sh<\/code><\/pre><p>В итоге при добавлении иконки нужно будет сделать:<\/p>\n<ol start=\"1\">\n<li>Нарисовать иконку.<\/li>\n<li>Собрать шрифт: .\/build.sh<\/li>\n<li>Отдать файл шрифта и less-файл разработчику<\/li>\n<\/ol>\n<h3>Что все это было?<\/h3>\n<p>Всё, что описано выше работает так:<\/p>\n<ol start=\"1\">\n<li>С помощью SketchTool всё, что может быть экспортировано, экспортируется из скетча в СВГ-файлы.<\/li>\n<li>СВГ-файлы, полученные на шаге выше собираются в шрифт. Для этого запускается сборщик шрифта, который все СВГ-файлы собирает в шрифт, конвертирует его в нужный формат и формирует хтмл-страницу с превью.<\/li>\n<\/ol>\n<h2>Вариант 2. Собираем и отдаём шрифт npm-пакетом<\/h2>\n<h3>Это ещё что такое?<\/h3>\n<p>Фронтенд-разработчики подключают библиотеки через npm-пакеты. Это привычная и удобная для них среда, кроме этого, npm-пакет сделает передачу шрифта удобней.<\/p>\n<h3>Шаг 1. Настраиваем среду<\/h3>\n<p>Нужно настроить среду как в первом варианте, и дополнительно настроить локальный npm-репозиторий. Спросите вашего фронтендера как это сделать у вас в команде. Попросите его исправить файл package.json.<\/p>\n<h3>Шаг 2. Сборка файла шрифта<\/h3>\n<ol start=\"1\">\n<li>Нарисовать иконку.<\/li>\n<li>Собрать шрифт: .\/build.sh<\/li>\n<li>Изменить версию пакета в файле package.json<\/li>\n<li>Выполнить команду grunt publish<\/li>\n<li>Передать разработчику шифровку «Выпустил пакет версии xxx».<\/li>\n<\/ol>\n<h2>Вариант 3. Собираем и отдаём шрифт нугет-пакетом<\/h2>\n<p>К сожалению про нугет ничего не знаю, но если кто-то соберет рабочий вариант, добавлю.<\/p>\n<h2>На что обратить внимание при рисовании иконок<\/h2>\n<p>При экспорте иконок надо не забыть перевести все в кривые. Чего не должно быть:<\/p>\n<ul>\n<li>Радиусов скруглений<\/li>\n<li>Покрашенным рамок<\/li>\n<li>Текстовых надписей<\/li>\n<\/ul>\n<p>Если это будет, то иконка может выглядеть в шрифте плохо, даже если в СВГ-файле было всё ок.<\/p>\n<h2>Если что-то не работает<\/h2>\n<p>Я обкусывал наше решение, возможно что-то переобкусал. Пишите если что-то не работает, или попросите помочь вашего фронтендера, он разберется.<\/p>\n",
            "date_published": "2017-01-26T12:21:17+03:00",
            "date_modified": "2018-12-16T01:07:38+03:00",
            "image": "https:\/\/mikeozornin.ru\/blog\/pictures\/icon-font-cover@2x.png",
            "_date_published_rfc2822": "Thu, 26 Jan 2017 12:21:17 +0300",
            "_rss_guid_is_permalink": "false",
            "_rss_guid": "54",
            "_e2_data": {
                "is_favourite": false,
                "links_required": [
                    "system\/library\/highlight\/highlight.js",
                    "system\/library\/highlight\/highlight.css"
                ],
                "og_images": [
                    "https:\/\/mikeozornin.ru\/blog\/pictures\/icon-font-cover@2x.png"
                ]
            }
        }
    ],
    "_e2_version": 3798,
    "_e2_ua_string": "E2 (v3798; Aegea)"
}