То, чего мне не хватает в CSS / Хабр | Веб-студия Nat.od.ua
То, чего мне не хватает в CSS / Хабр
Мне нравится, когда люди делятся тем, что они хотят видеть в CSS. За последние несколько недель я прочитал два потрясающих списка желаний Дэйва Руперта и Эрика Мейера. В 2022 году мы получили много новых CSS функций , мои любимые из них – контейнерные запросы (Container Query), :has и subgrid.
Я подумал, почему бы мне не поделиться с вами тем, что я хотел бы однажды увидеть в CSS.
Знать о том, перенесён ли элемент (flex-wrap detection)
Когда я использую flex-wrap: wrap, иногда мне хочется, чтобы был способ узнать, в какой именно происходит перенос на новую строку.
Например, предположим, что у меня есть раздел, который содержит заголовок и ссылку. Мы можем сделать этот маленький компонент отзывчивым с помощью flex-wrap: wrap. Вишенкой на торте будет знать, когда элементы переносятся в новую строку.
.section-header {
display: flex;
flex-wrap: wrap;
}
В настоящее время мы не можем определить, когда элементы переносятся. Единственный способ – использовать медиа-запросы для внесения желаемых изменений. Я хотел бы, чтобы у нас могло быть что-то подобное этому:
.section-header {
container-type: style flex-wrap;
display: flex;
flex-wrap: wrap;
}
@container style(wrap) {
/* срабатывает только при переносе элементов */
}
Добавлю от себя, что я бы больше хотел видеть что-то типа :isWrap
Приведенный выше синтаксис CSS не самый удобный и понятный глазу, но вы поняли идею.
Поддержка gap
В настоящее время нет способа проверить, поддерживается ли gap при использовании с flexbox.
Не буду вдаваться в подробности, но иногда это действительно необходимо. Как я это вижу:
@supports (gap: 10px) {
.element {
display: flex;
gap: 10px;
}
}
Сейчас этот код не работает.
Новый (логический) линейный градиент (linear-gradient)
Логические свойства CSS отлично подходят для создания многоязычных веб-сайтов. Поскольку арабский – мой родной язык, я использую множество вариантов отображения right-to-left , и каждый раз, когда я использую логические свойства, мне хотелось бы, чтобы они поддерживались и в градиентах.
.hero {
background-image: linear-gradient(to inline-end, #000, transparent);
}Знать, является ли элемент sticky-позиционированынм
Я могу придумать простой пример, в котором я хочу знать, когда position: sticky активен. Другими словами, когда элемент прилипает.
.site-header {
position: sticky;
top: 0;
}
.site-header:sticky {
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.1);
}Упрощенные градиенты
Давайте посмотрим правде в глаза, CSS-градиенты сами по себе не выглядят гладкими. Каждый раз, когда я использую градиенты, мне приходится модифицировать их, чтобы немного облегчить работу.
Я использую этот отличный инструмент для создания сглаженных градиентов.
.hero {
linear-gradient(to bottom, #304365, ease-in-out, transparent);
};
Упрощенный синтаксис в настоящее время является предложением CSSWG, но ни один браузер еще не принял его.
Анимировать text-decoration
Я хотел бы, чтобы у нас был способ анимировать подчеркивания ссылок без использования CSS-фона или псевдоэлементов. Почему бы не использовать что-то вроде text-decoration-size?
a {
text-decoration-size: 0%;
transition: text-decoration-size 0.3s;
}
a:hover {
text-decoration-size: 100%;
}Leading trim
Одной из проблем при работе с некоторыми шрифтами является различное начальное значение (отступ от букв шрифта), что может привести к несоответствию интервалов до и после шрифта.
Подробнее об этой проблеме и как её исправить тут и тут.
Контролировать overscroll
В настоящее время мы можем предотвратить цепочку прокрутки, используя overscroll-behavoir: contain. Представьте, что у вас есть модальный элемент, и при его прокрутке элемент body тоже будет прокручиваться.
Сейчас это поддерживается, но одна вещь, которая мне в этом не нравится, – это то, что она не будет работать, если элемент имеет короткое содержимое.
Заключение
На этом всё, делитесь своим мнением и предложениями относительно новых CSS функций в комментариях, а любые ошибки в статье смело относите мне в лс, заранее спасибо!
Стартап в соло. Часть 1: текущие показатели / Хабр | Веб-студия Nat.od.ua
Стартап в соло. Часть 1: текущие показатели / Хабр
Содержание всех статей
Стартап в соло. Часть 1: текущие показатели
Стартап в соло. Часть 2: идея и первая версия
Стартап в соло. Часть 3: упрощаем продукт
Стартап в соло. Часть 4: техническая реализация
Стартап в соло. Часть 5: что должен понимать разработчик, когда запускает стартап?
Стартап в соло. Часть 6: работа над SEO
Стартап в соло. Часть 7: источники привлечения клиентов
Содержание
О чем пойдет речь?
Примерно 11 месяцев назад я начал разрабатывать пет-проект – Telegram чат для сайта. С тех пор и до сегодняшнего дня занимаюсь его разработкой и продвижением самостоятельно. Правда занимаюсь им в свободное от основной работы время, которого мало.
Недавно проект перешагнул за 100 платящих пользователей в месяц и 100 000 рублей суммарной выручки (именно выручки, всё возвращается в проект, в карман ничего пока не положил). Вложения пока не отбились, но плавно к этому иду.
Хочу рассказать тем, кто тоже работает над своими проектами, как за год я пришел к текущим показателям (что было нелегко). Попробовал структурировать свои мысли, вышло довольного много текста. Текст разбил на статьи, содержание будет в каждой статье.
Кто я?
Senior Full-Stack разработчик (NodeJS + React).
5+ лет коммерческого опыта (работал над приложениями для автоматизации бизнес-процессов, над CRM системами и над e-сommerce решениями).
8+ лет в разработке (начинал с Java, пробовал Android, потом ушел в веб; сейчас стек NodeJS, React и много других популярных названий).
Свободное на проект время: ~10-15 часов в неделю, часто меньше.
Про 8 лет в разработке и 4PDA
Оказалось, что первый мой “опубликованный” проект как раз был выложен 8 лет назад на сайте 4PDA. Это было консольное Android приложение, написанное на Pascal (причем написанное на телефоне в мобильной IDE(!)).
Занималось приложение настройкой эмулятора Windows, чтобы запускать разные древние системы по типу Windows 95 на телефоне. Вот ссылка – https://4pda.to/forum/index.php?showtopic=666450
Почти ностальгическую слезу пустил.
Уточнение. Я сторонник мнения, что Full-Stack разработчик не особо может считаться Senior’ом из-за слишком большого количества технологий.
В моем понимании, Senior Full-Stack – это Middle во всём и сразу (от БД с Docker’ом до оптимизации сайта под Google Page Speed и настройки CSS’a). С серьезным опытом, знанием своих технологий и, в случае недостатка знаний, пониманием, где искать дальше для качественного выполнения задачи.
Что за проект?
Telegram Feedback – это чат для сайта. Посетитель пишет в чат на сайте, его сообщения приходят в бот, группу или Telegram канал (смотря куда удобнее). Владелец сайта отвечает в самом Telegram, ответ возвращается пользователю в чат на сайте.
Собственно, чат похож на Jivo-чат (тот чат, который всё время справа внизу экрана выпрыгивает, вы его точно видели, хе-хе). Но немного иначе. Jivo умеет группировать сообщения и с сайта, и из WhatsApp, и из Telegram, и из других каналов связи. У меня же просто чат. Специально не усложняю, а решаю только одну задачу для пользователя.
P.S. Я стараюсь яростно агитировать пользователей не включать “выпрыгивание чата”. Всегда раздражало, поэтому по умолчанию у моего чата это выключено.
Текущие финансовые показатели
На момент написания статьи у меня 105 платящих пользователей (81 ежемесячная подписка, остальные оплачивают помесячно вручную). Количество пользователей с тестовым периодом составляет ~20% относительно платящих пользователей.
Статистика в панели администратора
Итого, выручка:
(290 рублей – 5% (комиссия платежной системы) – 6% (налог ИП)) * 105 (клиентов) = 258 * 105 = 27 090 будет в следующем месяце.
Платежи появились только в сентябре. До этого виджет был бесплатный, так как стояла задача понять, какой именно продукт будет удобен пользователям, а не начать зарабатывать.
…хотя платежи добавил, а зарабатывать не начал…
Пользователи бесплатно пользовались, я платно их изучал и дорабатывал продукт. Платно, потому что пользователи находились через рекламу, а реклама не бесплатная.
Вот показатели платежей через CloudPayments с сентября:
Занимательный факт №1: на момент подключения оплаты в сентябре у меня было ~100 активных пользователей. После появления оплаты осталось 30 пользователей.
Вывод №1: активные пользователи и активные платящие пользователи – это две разные группы пользователей с разными конверсиями (что логично).
Занимательный факт №2: пока что вся выручка уходит обратно в проект на покупку рекламы и на развитие SEO. Ни копейки в карман я не положил, а наоборот, на каждую копейку выручки я докладывал не одну из своего кармана в течение года.
Вывод №2: прежде, чем проект станет выгодным или хотя бы не будет требовать активных вложений, должно пройти немало времени. И пока продукт станет удобным, и пока база клиентов накопится. Это и близко не один год. Не рассчитывайте на быстрый доход при создании пет-проекта, ставьте перед собой другие цели.
Системы платежей и чеки
Тут всё просто.
Для приема платежей из РФ использую Cloud Payments (API).
Для приема международных использую Enot Pay (API).
Для отправки чеков (кто не знает, их по закону обязательно отправлять для каждого платежа) использую Cloud Kassir (от Cloud Payments, API).
Откуда приходят пользователи?
Для этого у меня есть наглядная картинка:
Диаграмма пользователей по источникам привлечения
В следующих статьях дам пояснение, как собирается эта статистика.
Архитектура и стек технологий
Чат для сайта, по факту, система из нескольких компонентов, которая включает:
Сайт и личный кабинет пользователя (с требованием к хорошему SEO)
Технологии: TypeScript, NextJS (серверный рендеринг), React, кластерный режим для NextJS, Bootstrap 4
Виджет для сайта (js скрипт, который устанавливают на сайты пользователей)
Технологии: TypeScript, PreactJS (весит ~3Kb, обычный React слишком жирный для виджета), SocketIO
Админка с аналитикой и менеджментом пользователей (исторически сложилось, что это отдельный фронт)
Технологии: TypeScript, React, Bootstrap 4
Серверная часть с API и сокетами
Технологии: TypeScript, NodeJS + NestJS, SocketIO, PM2 (менеджмент процессов), Jest (unit тесты) + Supertest (E2E тесты)База данных
PostgreSQL 14
Брокер сообщений и key-value хранилище:
Redis
Прокси-сервер (чтобы собрать все компоненты системы выше в единое целое)
Nginx (классика)
Дополнительно:
Сервер
От FirstVDS (не реклама). Мощные и дешевые сервера.Ubuntu 20.04 + XFCE (совсем неудобно делать запросы через консоль без UI, с PgAdmin удобнее, поэтому поставил графическую оболочку спустя полгода развития проекта).
В лимит вертикального масштабирования по производительности я упрусь нескоро. Скорее всего, ресурс памяти под БД исчерпается быстрее, чем пропускная способность канала или производительность сервера (лимит для текущего VDS – Xeon Gold 5115 x 128 CPU и RAM DDR4 512 Гб).
Для момента, когда я все-таки упрусь в лимит и будет нужно горизонтально масштабироваться, посматриваю на сервера (или даже выделенные места) от Selectel. Давно хотел у них что-нибудь запустить, но всё ничего не подворачивалось.
DDOS-защита
DDOS-Guard. Недорого, удобно. В дополнение к глобальной защите, есть “локальная” защита на уровне Nginx и на уровне API. Срабатывает чуть быстрее в некритичных случаях.Чтобы никто не пытался забить память автоматическими сообщениями, картинками, XSS и т.д, внутри самого приложения тоже много разных защит. Почему-то желающие были, об этом расскажу в деталях позже.
Каптча
Яндекс Каптча. Под мои задачи сейчас бесплатно, потом станет недорого.Резервные копии
Делаются несколько раз в день стандартными средствами от FirstVDS + pg_dump + zip.
Я провожу проверку восстановления проекта из резервной копии минимум раз в месяц. В случае какой-либо критичной проблемы проект пропадёт минимум на час, максимум на день (в случае, если нужно устранять уязвимость).
Администраторы делятся на две категории: те, кто еще не делает бекапы и те, кто уже делает.
(c) Народная мудрость
Любой сервер падает. Главное поднять его, пока никто не заметил.
(с) Народная мудрость
Причем тут БДСМ студия?
Еще один занимательный факт.
Когда я запустил первую версию виджета и дал рекламу через Яндекс.Директ, первым пользователем была БДСМ студия в Иркутске 🙂. Ради интереса нашел их сайт в базе – до сих пор пользуются. Вначале даже попросили сделать открытие виджета по JavaScript событию.
Топ-3 странных сайта составлю в следующей статье. Интересные были, БДСМ студия не самое нестандартное. Я давно отключил уведомления для каждого подключенного сайта, так что рейтинг будет только за первые несколько месяцев работы виджета.
Предыдущий опыт
До Telegram Feedback у меня были попытки запускать свои пет-IT проекты с намеком на платящих пользователей. Правда, проект безуспешные и я давно их закрыл.
Woodle Auto – CRM система и система онлайн записи для автосервисов. Разрабатывал года полтора (долго, так как времени свободного за рамками основной работы было не так много).
Вложил довольно много за этот период, а заработал… 1 450 рублей. Зато сколько опыта на тему исследования рынка, пользователей и маркетинга.
Woodle Search – разрабатывал полтора месяца. Вложил ~60 000 рублей, заработал ~5 000 рублей. Потом случилось 24 февраля, Google Maps ушли из РФ и на проект я забил. Да и откровенно не до него было тогда. Тогда-то мысли в кучу собрать, а не о пет-проектах думать.
Заключение
Это был очень краткий обзор того, что есть сейчас. Дальше расскажу, как появилась идея и как выглядела первая версия проекта.
Об отечественном велосипедостроении – система контроля доступа для low-code платформы | Веб-студия Nat.od.ua
Об отечественном велосипедостроении – система контроля доступа для low-code платформы
Здравствуй, Хабр!
В прошлой статье мы рассматривали «лоскутный» подход к внедрению low-code платформы. Напомню, одна из проблем, которые мы собирались решать, звучит следующим образом: «Информационные системы зачастую… имеют изолированные друг от друга системы доступа и авторизации – вследствие чего сотрудникам приходится помнить и пользоваться несколько учетными записями».
При поиске решения этой проблемы, мы отталкивались от выбранного подхода к внедрению, согласно которому каждый лоскуток является не только покрытием участков рабочих процессов, но и агентом в смежных информационных системах. Это позволит получить в едином окне доступ не только к тем процессам, которые покрыты лоскутками платформы, но и к смежным с ними, реализованным в других системах. Доступ может быть реализован следующими способами:
1. Вызов методов апи смежных систем;
2. Прямое чтение/запись из/в БД смежных систем;
3. Доступ к функциональности смежных систем путем вынесения ссылок на их пользовательские интерфейсы на единый рабочий стол с сохранением внешних пользовательских сессий.
Также как вариант доступа возможна замена устаревающих участков процессов смежных систем лоскутками.
Итак, первое, что нам предстоит спроектировать – оптимальную структуру хранения информации о правах доступа, позволяющую привести к ней аналогичные по предназначению данные из других систем. При этом структура должна позволять относительно быстро производить по ней поиск.
Мы посмотрели несколько достаточно разных реализаций (варианты ACL, доступ на основе шэринга), и в итоге пришли к следующей, достаточно абстрактной структуре:
1. Иерархический справочник субъектов. Субъект может быть группой, либо отдельным пользователем.
2. Иерархический справочник объектов. Объект может быть разделом, формой, компонентом формы, методом апи, записью, полем.
3. Справочник возможных действий над объектами. Определяется для каждого типа объектов.
4. Таблица правил доступа субъектов к действиям над объектами. Содержит также приоритет правила.
Изначально вся система закрыта, есть только разрешающие правила.
Иерархии субъектов и объектов необходимы для того, чтобы облегчить процесс назначения прав и избежать дублирования данных. Если дочерние узлы не нуждаются в отличных от родителей правах, данные хранятся только для верхних уровней.
Также мы предусмотрели возможность разрыва наследования прав для объектов путем указания соответствующего признака – для изоляции правила от его родителей в рамках приоритета.
Приоритет правил необходим для некоторых случаев, например, если мы хотим дать разрешение админу на самый корень, и не хотим, чтобы дочерние узлы могли игнорировать эти правила.
При попытке актора выполнить действие, производится поиск и вычисление прав на разных уровнях приоритета. На каждом приоритете находятся все правила по иерархии, от рассматриваемого объекта, вверх, до разрыва наследования. Из собранных по иерархии объектов правил выбираются подходящие по субъектности и типу действия. Далее происходит суммирование всех разрешений, которые актор может получить для рассматриваемого типа действия.
У конечных пользователей и проектировщиков платформы должна быть возможность делегировать права на объекты в ручном или автоматическом режиме, создавая новые правила. Для правил, созданных вручную, должен храниться автор – с целью возможности отмены делегирования прав в случае, например, ошибки.
Для упрощения процесса внедрения этой системы в работу, необходимо разработать:
1. механизм импорта данных о субъектах из ActiveDirectory и подобных ей систем аутентификации.
2. интерфейс для быстрого наполнения справочника объектов как из самой платформы, так и из доступных смежных систем.
Итого, для получения всех необходимых пользователю функций в одном окне, необходимо дополнить все перечисленное механизмом получения и применения данных пользовательских сессий смежных систем. Данные будет применяться для автоматической авторизации при переходе по ссылке с рабочего стола во внешние интерфейсы или вызове апи.
О способах обеспечения информационной безопасности этой структуры мы расскажем в одной из следующих статей.
12 важнейших сайтов для освоения CSS в 2023 году / Хабр | Веб-студия Nat.od.ua
12 важнейших сайтов для освоения CSS в 2023 году / Хабр
Хотите войти в веб-разработку, но не знаете, с чего начать? Освоение CSS станет отличным стартом и, к счастью для вас, в сети существует огромное количество учебных ресурсов.
Мы провели исследование и собрали 12 наиболее актуальных сайтов, которые помогут вам продвинуться от уровня новичка до профессионала по CSS за кратчайшие сроки.
Будь вы начинающий программист или опытный, на этих сайтах есть информация для всех уровней: от полноценных учебных пособий до памяток и фрагментов кода. Эти ресурсы предоставят вам инструменты и знания, необходимые для создания красивых, функциональных веб-страниц. К тому же большинство из них абсолютно бесплатны.
Так что пристегните ремни и приступайте к написанию кода!
▍ Flexbox Froggy — освоение Flexbox
Если вы любите играть, то это идеальный сайт для освоения Flexbox. Flexbox Froggy – это восхитительная интерактивная игра, которая научит вас основам синтаксиса Flexbox.
По мере продвижения через уровни каждый «прыжок через пруд» будет становиться всё сложнее. К тому моменту, когда вы поймаете всех лягушек, у вас сформируется твёрдое понимание принципов работы Flexbox, и вы будете готовы использовать этот инструмент в своей работе.
Но не стоит верить нам на слово. Попробуйте Flexbox Froggy, и вы увидите, что ваши знания CSS начнут стремительно расти.
▍ CSS Grid Garden — освоение CSS Grid
Готовы перенести своё понимание CSS на новый уровень? Если да, то игра
CSS Grid Garden
– для вас!
Эта интерактивная игра научит вас основам Grid Layout — мощной системы построения макетов, которая становится всё более популярной. Задача в этой игре проста – вам нужно поливать сад, и каждый раз, когда вы будете делать это правильно – в него будет добавляться новая строка или столбец.
Для полива требуется написать код CSS и применить его к саду. По мере продвижения, когда вы начнёте успешно проходить всё более сложные уровни, ваше знание CSS Grid возрастёт десятикратно!
CSS Grid Garden также содержит дополнительные уровни для тех, кто желает отточить свои навыки. С помощью этих уровней вы научитесь использовать дроби при проектировании сетки, узнаете, как работает выравнивание при вытягивании элементов по сетке, и даже освоите создание удивительных паттернов с помощью этих элементов.
Плюс всё это можно делать в захватывающем стиле со множеством забавных анимаций и визуальных эффектов.
▍ Flex Box Adventure
Готовы к серьёзному испытанию?
Flex Box Adventure
гарантирует его вам.
Обучающая игровая среда Flex Box Adventure требует от вас отвечать на вопросы, создавать макеты на флексбоксах и сражаться со свирепыми монстрами для освоения искусства CSS Flexbox. Ваша цель? Стать «Мастером Flexbox» или «Жрецом CSS».
Это может прозвучать сложно, но представленная в данной игре дружелюбная для пользователя среда не только вдохновит вас, но и обеспечит поддержку для достижения успеха. Не пугайтесь – Flex Box Adventure подходит для людей с любым уровнем навыков. Каждое упражнение сопровождается пошаговыми инструкциями и примерами кода, которые можно использовать в качестве справки.
▍ CSS Diner — проверьте свои знания селекторов
Интересует весёлая задачка для тестирования ваших новых навыков CSS? Остановите своё внимание на CSS Diner. Этот ресурс представляет различные уровни, которые начинаются с простых селекторов и завершаются более продвинутыми темами вроде псевдоклассов и комбинаторов.
На каждом уровне вам даются столовые тарелки, и нужно выбирать селекторы, с которыми они связаны в коде CSS. Узнав верный селектор, его нужно ввести в текстовое окно и нажать «Ввод» для продолжения.
Каждая задача сопровождается объяснением, которое позволяет понять, почему определённый селектор подходит лучше другого. При этом на случай затруднений игра также предоставляет подсказки.
Готовы к испытанию? Вперёд на CSS Diner!
▍ Flexbox Defense
Готовы повысить свои навыки CSS и освоить искусство Flexbox Defense? Тогда этот сайт для вас. Игра Flexbox Defense ставит перед собой задачу помочь вам понять и отработать создание макетов Flexbox с использованием забавных графических элементов.
Flexbox Defense представляет захватывающий способ попрактиковать свои навыки CSS и попутно немного поразвлечься. Если для вас это звучит интересно, то смело пробуйте.
▍ Codecademy — курсы и обучающие материалы по CSS
Codecademy
– это отличный выбор для всех, кто ищет более углублённых инструкций по использованию CSS. Этот ресурс предлагает интерактивные уроки, опросники и упражнения по написанию кода, которые помогут вам освоить CSS. Помимо этого, представленная на сайте информационная панель позволяет отслеживать прогресс, чтобы сохранять мотивацию.
Codecademy также предлагает курсы, посвящённые более специфичным темам вроде HTML & CSS, Responsive Design и Flexbox. Ещё очень здорово, что после завершения каждого курса или урока вам выдают сертификат, подтверждающий получение навыков.
Если вы хотите ускорить темпы обучения, то ознакомьтесь с подпиской Pro, которая даёт доступ к полезным учебным материалам вроде проектов, аналитики, а также позволяет пошагово отслеживать свой прогресс.
▍ CSSReference.io
Готовы стать мастером CSS? Тогда добавьте в закладки
CSSReference.io
, бесплатное видеоруководство по CSS. Предлагая множество примеров для каждого свойства и объясняя причины использования каждого примера, этот сайт является одним из лучших информационных ресурсов по теме свойств CSS.
Здесь же вы найдёте диаграммы и иллюстрации – идеальные помощники для тех, кто предпочитает осваивать материал визуально.
Кроме того, этот сайт регулярно пополняется новым контентом, включая поддержку Flexbox, Grid и кастомных свойств.
Обратите внимание на колонку «popular views», где представлена информация о новшествах каждого раздела.
Так что, если для вас такой ресурс кажется интересным и полезным, не откладывайте его посещение в долгий ящик.
▍ Knights of the Flexbox Table
Готовы стать мастером Flexbox? Попробуйте бесплатную онлайн-игру для начинающих
Knights of Flexbox Table
.
Этот сайт даёт вам простое введение и обучает основам, таким как создание макетов, выравнивание контента, разработка отзывчивого дизайна и быстрое изменение значений CSS.
Освойте и запомните Flexbox с Tailwind CSS, чтобы начать обходиться без шпаргалок.
▍ Flexbox Zombies
Если вы ищете крутой и весёлый способ изучения основ CSS Flexbox, тогда Flexbox Zombies может оказаться тем, что надо.
С помощью этой интерактивной игры вы будете осваивать особенности Flexbox, сражаясь с зомби и оттачивая навыки написания кода.
Что делает Flexbox Zombies крутым обучающим инструментом:
- Она даёт вам практический подход к освоению CSS Flexbox.
- Требует умелого решения задач для победы над зомби и прохождения уровней Flexbox.
- Упрощает запоминание фрагментов кода за счёт мнемоник.
- Предлагает реальные задачи, такие как создание строк и столбцов с помощью Flexbox с применением обретённых навыков.
Помимо этого, освоение Flexbox также поможет вам повысить навыки решения задач, поскольку использование этого функционала предоставляет инструменты для оптимизации дизайна любой веб-страницы.
▍ Mozilla Developer Network — ресурсы по CSS и HTML
Mozilla Developer Network
– это отличный источник для освоения CSS и HTML. На нём есть всё, начиная с короткого знакомства с HTML, а также пошаговые руководства для изучения основ CSS Grid и Flexbox.
На MDN есть документы, в которых приводится полноценная информация о технологиях, веб-разработке и опенсорсных проектах, включая HTML, CSS, JavaScript, графику, мобильные/десктопные приложения и не только.
Плюс здесь есть форум, где можно задавать вопросы опытным разработчикам и получать ответы в течение считаных часов. MDN также даёт доступ к таблицам совместимости с браузерами, по которым можно выяснить, будут ли используемые вами HTML-элементы или свойства CSS работать с тем или иным браузером.
И если что-то в вашем коде работает не так, MDN поможет эту проблему отладить.
▍ CSSTricks — уроки, советы и трюки для становления экспертом CSS
Имеете средний уровень навыков в CSS и ищете возможность подтянуть основы и изучить продвинутые принципы? Тогда идеальным ресурсом для вас будет
CSSTricks
. Этот сайт основал
Крис Куайе
, и на нём вы найдёте обучающие материалы, советы и трюки, которые помогут вам на пути становления экспертом по CSS.
На CSSTricks найдётся материал для любого уровня, начиная с уроков для новичков и заканчивая продвинутыми рекомендациями для профессионалов, которые хотят поспевать за последними тенденциями.
Здесь также приводятся фрагменты кода, которые вы можете интегрировать в собственные проекты, и регулярно публикуются посты по теме последних трендов индустрии.
Если вы стремитесь улучшить ваши навыки написания кода, CSSTricks определённо будет вам полезен.
▍ CSS Zen Garden
CSS Zen Garden – это один из первых сайтов, который помогал людям осваивать CSS. Позиционируется он как ресурс, «стремящийся показать, какие визуальные решения можно получить с помощью CSS-дизайна».
CSS Zen Garden играл значительную роль в развитии веб-стандартов в течение более 15 лет и продолжает предлагать обучающие материалы по всем темам CSS, начиная с визуального отделения содержания от презентации и заканчивая невероятными идеями вроде трансформирования всего макета с помощью медиазапросов.
Он также предоставляет методы для отделения HTML-содержимого от презентации, чтобы все визуальные эффекты применялись исключительно с помощью CSS.
Ищете вдохновения?
Тогда CSS Zen Garden должен находиться в начале списка полезных ресурсов. Он содержит впечатляющую коллекцию стильных дизайнов и обучающих материалов, которые помогут отточить навыки по созданию красивых сайтов с помощью CSS.
▍ Заключение
При всём разнообразии ресурсов и сайтов CSS не обязательно должен быть чересчур объёмным и трудным в освоении. Независимо от того, являетесь вы новичком или опытным разработчиком, существует множество опций для продвижения на вашем пути.
Освоение ключевых методик вроде Flexbox и Grid позволит вам повысить выразительность и эффективность любого сайта. Приведённый выше список поможет упростить изучение CSS.
Ну а вложенное в это время обязательно себя окупит, поскольку CSS является очень ценным инструментом для любого веб-разработчика и верстальщика.
🏆 Голосуй за нас на премии «ЦОДы РФ»!
Как кастомизировать стандартные страницы ошибок / Хабр | Веб-студия Nat.od.ua
Как кастомизировать стандартные страницы ошибок / Хабр
В процессе настройки нового веб‑сервера, вы можете захотеть чтобы страницы ошибок отображались в красивом виде, вместо стандартного. Также иногда страницы ошибок должны быть в том же оформлении, что и основной сайт и/или предоставлять пользователям какую‑то дополнительную информацию, такую как, например, контакты, альтернативные способы решения возникшей проблемы или что‑то иное.
Стандартный вид Ошибки 404 в Nginx
Для упрощения процесса, я создал небольшую утилиту (прямая ссылка на проект в GitHub), по сути Node.js скрипт, которая позволяет создавать статические страницы ошибок в собственном дизайне и со своими текстовыми сообщениями. По умолчанию, утилита содержит только один шаблон в минималистичном дизайне (с поддержкой доступности и адаптивности, на сколько это возможно в такой простой странице). Но если вас не устраивает такой дизайн, то вы можете с легкостью изменить его, путем создания собственного: со своими стилями, шрифтами, изображениями и текстами.
Пример страницы для Ошибки 404
Для возможности создания страниц на других языка, утилита позволяет использовать собственные языковые пакеты, включающие свои кастомные текстовые сообщения.
Для упрощения интеграции, утилита автоматически создает сниппет с конфигурацией веб сервера, который легко может быть добавлен в конфигурацию вашего веб сервера. На текущий момент сниппет создается только для Nginx. Другие виды серверов будут добавлены позже (в качестве альтернативы, вы можете создать Pull Request с таким улучшениями, либо оформить Feature Request).
Использование
В базовом сценарии использования, всё что требуется, это лишь склонировать себе на компьютер репозиторий проекта, установить зависимости Node.js, запустить команду сборки, скопировать полученный результат к себе на сервер и обновить конфигурацию сервера.
$ git clone [email protected]:sapachev/error-pages.git
…
$ npm install –production
…
$ npm run build
…
INFO: Start building process
INFO: Flush build directory ‘/home/error-pages/dist’
INFO: Compile pages from source data:
• /home/error-pages/dist/400.html
• /home/error-pages/dist/401.html
• /home/error-pages/dist/403.html
• /home/error-pages/dist/404.html
• /home/error-pages/dist/410.html
• /home/error-pages/dist/500.html
• /home/error-pages/dist/502.html
• /home/error-pages/dist/503.html
• /home/error-pages/dist/504.html
INFO: Compile web servers config snippets from source data:
• /home/error-pages/dist/nginx-error-pages.conf
INFO: Build Tailwind CSS styles
INFO: Run ‘INPUT=”/home/error-pages/themes/minimalistic/@assets/css/main.twnd.css” OUTPUT=”/home/error-pages/dist/@assets/css/main.css” npm run build:tailwind’ command
INFO: Tailwind CSS styles were built
INFO: Copying assets to ‘/home/error-pages/dist/@assets’ directory
INFO: Building process was completed in 1.727sПродвинутое использование
В дополнение к шагам базового сценария, вы можете улучшить скомпилированные страницы меняя части, из которых они собираются: шаблоны, стили, тексты, а также сниппеты конфигурации.
Основная конфигурация утилиты хранится в файле config.json в корневой папке, которую можно менять в соответствии со своими требованиями:
{
“tailwind”: true,
“theme”: “minimalistic”,
“locale”: “en”
}Шаблоны
Все шаблоны хранятся в папке themes, где стандартной темой является minimalistic, которую можно изменить или добавить новую. Каких‑то особых требований к шаблонам страниц нет: каждый шаблон является обыкновенным HTML документом, с внедренными переменными, на месте которых будут текстовки из файлов локализации. Для обработки внедренных переменных используется библиотека mustache.js. Таким образом, если нужно реализовать какую‑то особенную логику в своих шаблонах, то вы можете ознакомиться с документацией этой библиотеки для определения имеющихся возможностей шаблонизации.
После добавления своего шаблона, просто укажите его в файле конфигурации, чтобы скомпилировать страницы с его использованием.
Стили
Стилизация шаблонов базируется на фреймворке Tailwind CSS. С помощью этого фреймворка, можно быстро описывать стили страниц без необходимости писать отдельный CSS код. Точкой входа для стилей Tailwind должен быть файл themes/
Однако, если по каким-то причинам использование Tailwind не требуется (например, стили уже описаны ранее в CSS), компиляцию стилей Tailwind можно отключить в основной конфигурации утилиты (файл config.json). В этом случае шаг сборки стилей будет просто пропущен без какого-либо влияния на финальный результат.
Текстовые сообщения и Локализация
Все текстовые сообщения хранятся в JSON файлах, разделенных по признаку языка, и расположены в папке src. Каждая страница создается из соответствующего ей файла локализации вида <Код HTTP>.json (<Код HTTP> – это число, соответствующее коду ошибки HTTP). Таким образом, если нужно создать страницу для кода, который еще не описан, то просто создайте соответствующий JSON файл, содержащий описание этого статуса в соответствующих свойствах.
Любой файл локализации может быть расширен любым количеством дополнительных свойств, которые вам нужно отобразить на странице. Для определения общих свойств, вы можете использовать файл common.json – свойства из этого файла будут применены к каждой странице.
Для локализации страниц, просто создайте новую папку в директории src, содержащую JSON файлы с текстами страниц. Создавая JSON файлы, вы можете описать любой набор HTTP кодов (например, только для 400-ых ошибок) – просто следуйте конвенции именования, и не забывайте выделять общие тексты в файл common.json.
Конфигурации сервера
В процессе работы, Утилита автоматически создаст сниппет для вашего сервера, который будет содержать лишь те страницы, которые были созданы. Данный сниппет будет содержать настройки обрабатываемых ошибок, и указывать на страницы, которые будут их представлять. Как было сказано ранее, на данный момент только Nginx поддерживается.
Для использования полученных страниц, остается только скопировать на сервер все файлы из папки dist и включить использование сниппета в уже существующей конфигурации сервера. В соответствии с шаблоном сниппета, все страницы должны быть расположены в папке /usr/share/nginx/html/error-pages. В случае если настройки в снипетта не подходят, то вы можете отредактировать шаблон сниппета в папке snippets. Так же как и для тем оформления, шаблоны конфигураций поддерживают mustache.js, тем позволяя реализовать в шаблоне любую логику (списки, условия и т. д.).
Сам по себе конфиг, я рекомендую располагать в папке /etc/nginx/snippets/, а для его подключения использовать строчку конфигурации: include /etc/nginx/snippets/nginx-error-pages.conf;. Разумеется, это не более чем рекомендация, т.к. в реальности всё может быть иначе или сложнее.
Ниже приведен простой пример конфигурации веб‑сервера с включенным в нее сниппетом кастомных ошибок:
server {
server_name example.com;
access_log /var/log/nginx/example.access.log;
include /etc/nginx/snippets/nginx-error-pages.conf;
location / {
root /data/www;
}
}Демо
Посмотреть как выглядят страницы ошибок можно на моем сайте по следующим ссылкам:
Сообщение об ошибках и запрос новых функций
Код утилиты нельзя назвать каким‑то сложным, однако, несмотря на этот факт, все значимые части покрыты юнит‑тестами. Впрочем, это не является гарантией отсутствия каких‑либо ошибок, поэтому если вы столкнетесь с какими‑то проблемами, то, пожалуйста, сообщите мне о них, через создание Issue в репозитории проекта: https://github.com/sapachev/error‑pages/issues
Также приветствуется создание запросов новых функций, которые вы хотели бы увидеть в данной утилите.
Участие в разработке
Проект открыт для всех желающих, и если у вас есть идеи, а главное желание и возможности их реализовать, то с радостью рассмотрю их в виде Pull Request. Со своей стороны готов предоставить вам поддержку в реализации вашей задумки. Не стесняйтесь спрашивать меня о коде, и возможных решениях вашей идеи.
рассказываем, как прошел митап #DevTalks о фронтенде / Хабр | Веб-студия Nat.od.ua
рассказываем, как прошел митап #DevTalks о фронтенде / Хабр
Всем привет! На связи Spectr.
В феврале мы провели митап #DevTalks, посвященный фронтенду, и сейчас хотим подробно о нем рассказать: поделимся докладами спикеров, материалами выступлений, отзывами участников и немного расскажем о внутренней кухне организации таких ивентов.
О формате и организации митапа
Формат наших митапов — это не скучные лекции, построенные исключительно на теории. Наоборот, это живые и актуальные кейсы, основанные на практическом опыте спикеров. А еще это возможность вживую завязать новые знакомства, обсудить с коллегами, как решить ту или иную рабочую задачу, заявить о себе и рассказать о своих идеях dev-комьюнити.
Немного истории
Первый митап из серии #DevTalks мы провели в конце 2021 года. И с этого момента организовали и провели уже 4 таких события. За это время успели поговорить о геймдеве, безопасной разработке, устройстве современных БД, архитектуре веб-приложений. Записи всех предыдущих #DevTalks можно найти тут.
Как мы организовываем события
Почти всю организационную часть митапов мы обычно берем на себя: продумываем основную тему и программу, выбираем спикеров, помогаем в формулировке тезисов и тем докладов, решаем вопросы, связанные с трансфером, организовываем пространство для проведения событий. А еще координируем и модерируем процесс во время митапа и участвуем во всем, что происходит на площадке. К тому же мы не против поделиться своими знаниями и опытом, поэтому часто наши разработчики и сами выступают с докладами.
При этом нам важно, чтобы контент был доступен широкой аудитории, поэтому делаем качественные онлайн-трансляции митапа. В таких вопросах сложно обойтись без помощи, поэтому тут мы задействуем силы профессионалов.
Для того чтобы участники оперативно узнавали о любых изменениях, связанных с митапом, мы создали чат в Telegram. А еще тут ведем «прямой эфир» во время ивента, собираем обратную связь и рассказываем о ближайших событиях. При этом сам чат в какой-то момент стал отдельной мини-площадкой для обсуждений, где можно попросить совета или похоливарить на животрепещущие темы.
Доклады
Делимся записями всех четырех докладов митапа, кратким содержанием каждого и ссылками на презентации.
Андрей Смирнов: «Фронтендеры — они повсюду»
Вы ведь наверняка знаете о подкасте Frontend Weekend? Андрей — его бессменный ведущий. А еще Андрей работает в X5 Tech, руководя всем ресурсным пулом фронтендеров и мобильных разработчиков. Мы всегда собираем фидбэк от участников, и они уже уже неоднократно просили нас пригласить кого-то, кто сможет обстоятельно рассказать о roadmap развития разработчика. Мы пригласили Андрея, ведь, кажется, он один из лучших спикеров на данную тему!
В своем докладе Андрей разобрал всевозможные варианты карт компетенций: сложные и запутанные, найденные на просторах интернета, более простые и более удобные с разделением по грейдам. Рассказал, как ими пользоваться и по каким принципам стоит развивать свои компетенции. А еще Андрей затронул тему того, какие софты нужно развивать джуну, а какие — тимлиду. И все это с простыми и понятными примерами, мемами и историями из жизни. В конце доклада Андрей рассказал о возможных способах оценки и проработки своих навыков и компетенций и разобрал плюсы и минусы каждого способа.
Ссылка на запись доклада.
Ссылка на презентацию.
Константин Остров: «Неочевидные возможности SVG в современном фронтенде»
Следующий спикер, Константин Остров, в своей работе более пяти лет использует SVG-изображения для создания функционала сайтов для застройщиков: от выбора квартиры на плане этажа до анимаций. Сейчас он руководит отделом фронтенд-разработки в студии «Феникс».
В своем докладе Константин рассказал о том, что представляют собой SVG-изображения и в чем их преимущества, а после выступления ответил на вопрос, в чем же заключаются их недостатки. Привел примеры задач, с которыми команда сталкивалась при работе с SVG: позиционирование внутри SVG, внедрение динамических элементов внутрь SVG, расчет координат вне BOX модели. А также рассказал, что такое производительность и что на нее влияет и показал на примере проекта с многоквартирными домами, как может выглядеть применение SVG-графики.
Ссылка на запись доклада.
Ссылка на презентацию.
Семен Левенсон: «Насколько мой фронтенд плох»
Семен известен многим по выступлениям на Dump, CodeFest, HolyJS. В копилке Семена 20+ докладов на этих конференциях. А еще он участвует в программном комитете HolyJS, записывает подкаст «Тяжелое утро» и работает в Яндекс.Маркете.
Семен рассказал, что же такое рефакторинг, и разобрал, какие признаки могут быть у плохого кода и почему плохой код — это нормально. Объяснил, как сообщить менеджеру о том, что рефакторить все-таки надо — на менеджерском, т. е. на языке схем и графиков. А еще о том, что такое плохометры, как их строить и чем они могут быть полезны для разработчиков. Также в докладе можно найти несколько неочевидных способов, как «уговорить» менеджера на рефакторинг и несколько полезных инструментов для работы с «плохим кодом».
Ссылка на запись доклада.
Ссылка на материалы на Гитхаб.
Зар Захаров: «История о том, как мы с CRA на ViteJS съезжали»
Зар в разработке с 2006 года (примерно с того момента, когда из инструментов разработки были только PHP, CSS, HTML и иногда использовали JS). За это время он успел поработать и в стартапах, и в аутсорсе, и в крупных продуктовых компаниях. Сейчас Зар — старший разработчик в VK. Как и Андрей Смирнов, Зар — участник программного комитета Frontend Conf, к тому же сам часто выступает на многих конференциях. Многие знают Зара как создателя первого марафона по программированию.
В качестве предыстории к докладу Зар рассказал о ситуации, когда он с командой работал над простеньким сайтом образовательного проекта. Но со временем проект рос и развивался, поэтому нужно было искать решения, необходимые для его реализации (или альтернативу CRA). В своем докладе Зар рассмотрел ряд возможных для этого инструментов, таких как Next.js, Webpack, Vite. И остановился на последнем.
В докладе Зар рассказывает, в чем основные преимущества Vite перед CRA, о своих первых впечатлением при использовании VIte и о процессе перехода с CRA на Vite.
Ссылка на запись доклада.
Ссылка на презентацию.
Как прошел митап
Кажется, получилось очень круто, полезно и интересно. И во многом это заслуга спикеров. Мало у кого получается быть настолько на одной волне с участниками. При этом аудитория митапа была живой и открытой к обсуждениям, ведь каждое выступление спикера заканчивалось множеством дополнительных вопросов. И они бы продолжались и продолжались, если бы не тайминги 🙂
Любопытство со стороны участников мы поощряли и дарили тем, кто задавал наиболее интересные вопросы (по мнению спикеров), фирменный мерч.
Если говорить о количестве участников, то в этот раз в офлайн-формате митап посетило 120+ человек. При этом процент «доходимости» (конверсии зарегистрировавшихся в офлайн-участников) также высокий — около 80%.
Для #DevTalks это довольно большие цифры. Но мы уверены: дальше больше. Благо выбранная для митапов площадка — технопарк Morion Digital — позволяет разместить еще больше гостей 🙂
Кроме докладов
На площадке мы разместили брендированную фотозону, чтобы участники могли забрать с собой приятные эмоции о прошедшем ивенте в виде профессиональных фотокарточек. И зону кофе-брейка, где гости ивента могли выпить вкусный кофе и «побаловаться» печеньками.
Полный фотоотчет с события лежит тут.
В перерывах между докладами участники знакомились и общались друг с другом, обсуждали темы, которые не успели обсудить в рамках докладов со спикерами.
Во время события мы провели интервью. Узнали у участников, в чем заключается польза подобных мероприятий для них, попросили спикеров сказать пару слов об аудитории митапа, а также задали один общий вопрос, который родился из названия одного из докладов: важно ли разработчикам и бизнесу говорить на одном языке? (Скоро выпустим отдельный материал на эту тему!)
Митап завершился афтепати в одном из лучших баров Перми, где мы продолжили говорить о фронтенде, но это уже совсем другая история 😊
Отзывы участников
После митапа нам удалось собрать несколько приятных отзывов от участников:
«Мне понравились спикеры: их доклады, опытность, харизматичность и умение работать на аудиторию. Таких хочется слушать. Не менее важным для меня стало то, из каких компаний они были. Спасибо, что привлекаете таких крутых докладчиков ))».
«Понравились спикеры и темы, которые они освещали, также организация на высоте».
«Ламповая атмосфера, крутые докладчики».
«Спасибо Spectr, за то что повышаете пермскую ИТ-культуру, видно, что очень стараетесь. Понравились: сильные выступающие из разных городов, разные тематики, стол со вкусностями, afterparty. Вы большие молодцы ребята! <3».
«Понравилась атмосфера, спикеры с интересными (актуальными) докладами и организация мероприятия».
И еще немного из Telegram-чата.
Что дальше?
Подобные ивенты мы проводим регулярно — несколько раз в год. И уже второй год мы делаем масштабную конференцию о разработке и управлении бизнесом — Ural Digital Weekend. Мы уже активно готовимся к событию и открыли продажу билетов. Для читателей Хабра приготовили специальный промокод, который даст приятную скидочку: HABRAHABR.
Приезжайте 4–5 августа в Пермь. Будем рады вас видеть! 🙂
P2P, Push и Pull / Хабр | Веб-студия Nat.od.ua
P2P, Push и Pull / Хабр
CDN (Content Delivery Network) — распределенная сетевая архитектура, созданная для ускорения доставки контента пользователям. CDN влияет на скорость загрузки любого контента сайтов и приложений, который видит пользователь: аудио, видео, стриминг, изображения, тексты, графика.
Сеть доставки контента делится на три типа: P2P, Push и Pull. В материале разбираемся в отличиях и особенностях разных CDN.
P2P
Peer‑to‑peer CDN — это децентрализованная сеть, в которой пользователи распространяют контент между собой, а не полагаются на централизованный сервер. Данный метод позволяет снизить нагрузку на исходный сервер и повысить скорость доставки контента.
P2P CDN распределяет контент между пользователями. Данная модель не использует HTTP‑серверы, в отличие от традиционных CDN, когда в сетях размещают множество HTTP‑серверов по всему миру, на которых кэшируется и хранится контент.
Сеть доставки контента P2P не является CDN общего назначения, то есть не обслуживает все виды веб‑контента — peer‑to‑peer сосредоточен исключительно на масштабируемом и эффективном распространении видео. P2P CDN работает путем координации пользователей таким образом, чтобы они отправляли видеосегменты контента друг другу вместо того, чтобы каждый постоянно получал сегменты с пограничного сервера.
Push
Push CDN — метод, при котором контент активно передается с сервера происхождения на пограничные серверы CDN. Это может быть полезно для контента, который часто обновляется или имеет высокий спрос.
Вместо того, чтобы извлекать контент с сервера, когда он нужен CDN, контент загружается в сеть заранее. Таким образом, CDN могут кэшировать статический контент и предоставлять его пользователю.
Push CDN дают преимущество гибкости в работе с контентом. Владелец веб‑сайта и создатель его содержимого может напрямую указать, какой контент будет передан на сервер CDN, когда истечет срок его действия и когда он должен быть обновлен. Это эффективное и более простое использование трафика — контент загружается на сервер CDN только при наличии изменений, что позволяет снизить трафик.
Проблема этого подхода заключается в том, что если вы часто обновляете контент и если ваш сервер уже обслуживает другой тяжелый трафик, то такая синхронизация может увеличить нагрузку на сеть.
Pull
Pull CDN — метод, при котором контент запрашивается пограничными серверами CDN с исходного сервера. В отличие от метода Push, сама CDN отвечает за извлечение нужного контента для доставки посетителям. Это наиболее распространенный тип CDN, который может быть полезен для контента, который не часто обновляется или имеет низкий спрос.
Происходит это так: владелец сайта оставляет контент на исходном сервере и переписывает URL‑адреса так, чтобы он указывал на CDN. Когда выполняется определенный запрос на веб‑страницу, CDN извлекает элементы и файлы веб‑страницы с исходного сервера и передает их посетителю. Затем сервер CDN будет кэшировать эту версию страницы до истечения срока ее действия.
Основное преимущество Pull заключается в том, что его довольно легко настроить, поскольку CDN в основном делает всю работу за вас. Кроме того, Pull извлекает элементы и файлы веб‑страниц только после первоначального запроса, за счет чего уменьшается потребление хранилища.
Но данный метод может привести к некоторым проблемам, ведь он менее гибок, чем Push CDN. Часто возникает избыточный трафик, поскольку элементы и файлы веб‑страниц запрашиваются повторно еще до того, как они были изменены.
Кроме того, Pull может быть медленнее Push, поскольку посетители, которые впервые заходят на страницу, или те, кто пытается открыть веб‑страницу после истечения срока хранения элементов и файлов в CDN, могут испытывать меньшую скорость загрузки страницы.
Почему Banditypes — самая маленькая TS-библиотека для валидации схем / Хабр | Веб-студия Nat.od.ua
Почему Banditypes — самая маленькая TS-библиотека для валидации схем / Хабр
Я выпустил библиотеку banditypes — самый маленький валидатор схем для TS / JS. Удивительно, но базовый функционал валидации с приятным API можно упихнуть в 400 байт, если сконцентрироваться на размере и добавить пару грязных хаков. В этой статье расскажу, как добился такого результата.
Но для начала, если вы еще не знакомы с проблемой и популярными решениями (zod, superstruct, yup старина joi) — пара слов про валидацию данных вообще. Мы собираемся работать с данными какой-то формы — скажем, данные о товаре, то есть объект со строкой в поле title и числом в поле price. Но получаем мы эти данные из ненадёжного источника — localStorage (как раз эту задачу я и решал), внешнего АПИ или вообще от пользователя. Если мы просто берем эти данные и используем как наш объект, а там вдруг что-то не то (например, массив сток), появляются смешные баги с « прибудет через undefined минут». Гораздо лучше проверить «форму» данных один раз, при чтении, и показать явную ошибку.
На голом TypeScript (и на JavaScript тоже) описывать эту логику больно:
if (typeof res === ‘object’ && res
&& ‘title’ in res && typeof res.title === ‘string’
&& ‘price’ in res && typeof res.price === ‘number’
) {
retrun res
}
Гораздо приятнее писать декларативные валидации на специальном DSL. Все библиотеки сошлись примерно к одному варианту:
const userSchema = object({
title: string(),
price: number(),
});
const user = userSchema(res);
Современные валидаторы умеют генерировать TS-тип прямо из схемы через Infer
Так вот, banditypes решает эту задачу с 400 байт вместо 11КБ zod и yup или 1.8Кб superstruct. Я не какой-то маньяк, 1.8КБ — уже очень хорошо, но я любопытный и люблю челлендж, и я смог. Как мне это удалось? Сейчас расскажу!
Как правильно измерять размер библиотек
Когда кто-то говорит, что «библиотека X весит 40 килобайт», обычно имеют в виду, что 40 килобайт — это полный umd-бандл библиотеки со всеми функциями, которые в ней есть. Это было логично в 2008, когда мы вставляли на сайт jQuery с сомнительного CDN, это было куда ни шло в 2015, когда мы реквайрили монолитный шматок кода и радовались, но в 2023, когда статические импорты бороздят просторы ес-модулей, это уже не говорит ни о чём вообще.
Во-первых есть три-шейкинг. Если в библиотеке 100 функций, а я использую одну, то по-хорошему и в бандл ко мне должна залезть только эта функция. Замер полного размера «наказывает» библиотеки, в которых много функций (ты не сильный, а ТОЛСТЫЙ) и не говорит ничего о том, как хорошо библиотека три-шейкается. Понятно, что это верхняя граница на размер, но способ измерить сборку с разными подмножествами функциональности нужен.
Чем меньше библиотека, тем менее реалистичный размер даёт классический метод. В umd-бандле (или любой standalone-сборке) библиотеки без клиентского кода есть как минимум три вещи, которых не будет в финальном бандле приложения:
Имена экспортируемых функций (не смейтесь, это около 25% banditypes). Любой нормальный бандлер как минимум смэнглит имена экспортов в какой-нибудь qi=()=>…, а то и вообще заинлайнит их в место использования.
Повторы стандартного JS-синтаксиса (const, function, Object, catch), который и так присутствует в клиентском коде, и, слава gzip, в библиотеке их можно использовать почти бесплатно.
22 байта End of Central Directory record, который есть в любом gzip-файле, и второй раз от вашей библиотеки не появится.
Поэтому я измеряю размер оригинальным, но логичным способом — беру небольшое «тестовое приложение» (совсем крошечное, только чтобы гзип прогреть), и собираю его 2 раза — один с подключенной валидацией, один — без. Разницу размеров этих сборок я и называю как размер библиотеки. Тестовых приложений можно сделать несколько — я измеряю варианты со всеми валидаторами (385 байт); с самыми частыми (примитивы + объект + массив, 206 байт) и ядро без встроенных валидаторов (96 байт).
Чтобы вы не подумали, что я упростил себе задачу (ишь, EOCD считать не хочет!) — при таком способе в размер входит еще и код для интеграции библиотеки в клиентский код, то есть описание схемы. Думаю, это честно — мы же оптимизируем размер всего приложения, а не только библиотеки? Иначе я мог бы вообще не писать ничего и назвать это «невероятной 0-байтной библиотекой для валидации: все валидации вы пишете сами».
Дизайн для маленькости
Если отчаянно шлёпать по клавиатуре, а потом попытаться волшебным образом ужать получившийся бандл, ничего хорошего не выйдет.
Режем скоуп. Хорошие библиотеки валидации возвращают ошибки с приятным сообщением вида { message: ‘Expected string, got number’, path: }, и не по одной, а все сразу. Такую библиотеку можно использовать для взаимодействия с пользователем — например, при проверке форм. От этой чудесной фичи я сразу же отказался.
Меньше методов — лучше три-шейкинг. Почему superstruct три-шейкается, а zod — нет? Потому что в superstruct всё сделано функциями: min(number(), 9000), а в zod — методами: z.number().gt(5). Минификатор может посмотреть на код и сказать «ха, функция min не используется, удалю-ка её». А вот найти все места, где используются объекты Number, увидеть, что их метод gt не используется, и удалить его, почти невозможно. К тому же у min гораздо проще ужать название в какой-нибудь w. Поэтому предпочитаем функциональные АПИ.
Больше расширяемости. Если мы убрали функции из библиотеки, но при этом не хотим загонять пользователей (и себя) в тупик недостатком фичей, нужно дать им возможность дописывать нужную функциональность самим. На каждый валидатор добавили два метода:
type1.map(res => …) — дополнительно провалидировать данные string().map(str => str.length ? str : fail()) или преобразовать их: string().map(str => )
type1.or(val => …) — если левая валидация не прошла, попробовать правую. Кроме очевидных юнион-типов (в том числе — опциональных, string().or(optional())), можно реализовать дефолтные значения: string().or(() => ‘default’)
В итоге получилось красивое (и совместимое с популярными библиотеками в базовых сценариях) API:
const userSchema = object({
title: string(),
// дополнительная валидация
price: number().map(num => num > 0 ? num : fail()),
tags: set(enums())
});
// строка или массив строк
const strings = string().or(array(string()));
// преобразование данных
const arraySum = array()
.map(arr => arr.reduce((acc, e) => acc + e, 0));Грязные хаки
Заложив маленькость как основное ограничение на этапе дизайна, можно уже добиться неплохого результата — в моём случае, около 550 байт. Теперь настаёт время хаков — пытаемся сделать всё то же самое, но ещё компактнее, при этом не сильно испортить DX. Пять оптимизаций помогли мне ужать размер до невероятных 385 байт:
Используй современный JS (не уверен, что это можно назвать грязным трюком). На удивление, замена function array(raw) {} на const array = (raw) => {} и использование спредов уменьшило сразу на 23 байта (да, на моих масштабах это праздник). gzip достаточно хорошо жмёт все function (несжатый бандл уменьшился на 430 байт), но выгода всё таки есть.
Уменьшай API. Зачем нужен тип literal(42), если enums() делает то же самое? 16 байт.
Повторяй. Если начал писать функции стрелками, то пиши стрелками все функции, так лучше жмётся. Если в коде используется слово Object, то следующие Object мы получем почти бесплатно, спасибо gzip. На удивление, правильное переиспользование функций при gzip занимает больше места, чем копипаст с небольшим изменением. И да, если все-все функции принимают 1 аргумент, они жмутся лучше, потому что повторяющийся кусок длиннее.
Трюк, которым я горжусь: вместо серии raw => typeof raw === ‘string’ ? raw : fail() я придумал тип like = tag => raw => typeof raw === typeof tag ? raw : fail(). То есть мы передаём значение-пример, как string = like(”), и сравниваем typeof примера с переданным значением. 20 байт!
Зачем делать throw new TypeError(‘Invalid Banditype’), если можно просто вызвать строку, ‘bad banditype'(), и ошибка всё равно вылетит? Да, туда нельзя передать кастомне сообщение и прочитать его сверху, но вот такие у нас ограничения. 20 байт.
Я попробовал много идей, которые не сработали или сделали хуже. Замена throw на return null или вариации return true / false немного уменьшает размер, но усложняет валидацию настоящих null и усложняет координацию проверок в коллекциях (теперь нужно руками проверять валидацию на каждом элементе, она не вылетит вверх по волшебству). Перекладывание for..in в Object.keys увеличивает размер, какие бы вариации я не пробовал.
Наконец, от одной хорошей оптимизации я сознательно отказался: это замена методов-комбинаторов map / or на чистые функции. Вариант с функциями лучше три-шейкается и позволяет минифицировать названия функций (e вместо .map), но, на мой вкус, ухудшает API: or(map(string(), s => ), array(string)) читается хуже, чем string().map(s => ).or(array(string())), потому что все слова в естественном порядке. К тому же методы проще типизировать.
Сегодня мы познакомились с banditypes — самой маленькой JS-библиотекой для валидации. Упихнуть ее в 400 байт я смог, используя три дизайн-принципа
Откажись от лишних фич (подробных сообщений об ошибках валидации)
Используй функции, а не методы, потому что они лучше минифицируются.
Поддержи кастомизацию, чтобы пользователь мог сам добавить нужный, недостающий функционал.
И пять оптимизаций:
Современный JS — меньше кода
Удаление дублирующихся API
Повторяющийся код — хороший код для gzip
typeof raw === typeof sample
Вместо throw вызываем строку: ‘bad banditype'()
Заодно придумал оригинальный способ измерения размера библиотеки на основе тестового приложения — это гораздо честнее, чем классический размер UMD-бандла.
Используйте на здоровье, не забывайте поставить звёздочку на гитахбе — это поднимает мне настроение. Если было интересно — подписывайтесь на мой телеграм-канал, там маленький и увлекательный контент.
Плохие практики разработки, которые до сих пор встречаю в стартапах / Хабр | Веб-студия Nat.od.ua
Плохие практики разработки, которые до сих пор встречаю в стартапах / Хабр
Привет, я Виктор. Двенадцать лет назад я пришел в веб-студию в Самаре. Так начался мой путь в разработке. У нас не было гита, CI/CD, тестовых стендов и много чего еще. Я видел, как это мешало развитию команды и бизнеса. Приходилось на ощупь собирать грабли, открывать для себя хорошие практики и внедрять их. С тех пор успел поработать старшим разработчиком в российском финансовом холдинге и немецком b2b-стартапе. Был тимлидом в фудтех-проекте, СTO в образовательных стартапах для российского и латиноамериканского рынка — и почти везде поначалу натыкался на похожие проблемы. Недавно переехал в Израиль, стал консультировать стартап. И что бы вы думали…
Ниже собрал примеры из практики, как мы стреляем себе и бизнесу в ногу, хотя казалось бы, цель в стартапе — “бежать быстро”. И выложил схему, как можно это починить, которой сам обычно пользуюсь. Она и побудила меня написать этот пост. Найти схему можно в конце поста.
Нет Git, разработка ведется на продакшн-сервере
Классическая история, когда проект стартует с одного разработчика. Он что-то делает, заливает по FTP, тестирует и правит прямо на проде. Может быть, где-то и есть репозитории, но они пустуют или не обновляются.
Затем бизнес масштабируется, нанимаются разработчики. И тут случается интересное. Например, как-то раз такой товарищ, работавший один и без гита, затер пару дней моей работы. Благо, я привык пользоваться системой контроля версий в любых проектах и ситуациях. Вопрос, что было бы с его кодом, затри я его… Чтобы продать команде стартапа идею “гит нужен, он даст бэкапы и поможет масштабироваться”, я сделал презентацию и выступил на пятничной встрече за пиццей. И помогло. Когда прод упал, а второй разработчик был не на связи, я хотя бы смог понять, что он менял. И относительно быстро исправить ошибку.
Зачем нужен git?Нет код-ревью
Я пришел в проект, где из прошлой команды уже никого не осталось. Встала задача сменить один вид пагинации на другой. Казалось бы, делов, – зайди в функцию и поменяй за 2 минуты. Но замену сделать нельзя, потому что предшественник использовал хитрую схему: копипасту кода, в которую каждый раз вносил какие-то изменения. Итого, у нас 200 вхождений и геморрой с их правкой вручную на 3 дня. Думаю, ревью от любого коллеги эта хитрая копипаста не прошла бы.
Но хорошо, тогда у меня было хотя бы время посидеть, подумать и сделать лучше. Вот пример, когда отсутствие ревью оказалось критичным. Новый проект. CRM, основа всего бизнеса, тормозит. Нужно чинить, менеджмент давит. Разработчик решает проигнорировать стандартные процессы: код-ревью, тестирование, запуск автотестов. Просто сразу пушит в гит и релизит. CRM падает совсем. Оказалось, в условиях стресса, когда “надо прям вот сейчас”, человек допустил ошибку в коде. Гораздо безопаснее, если бы коммит посмотрел кто-то еще. Имхо, в критических условиях можно проигнорировать автотесты, если они крутятся долго. Но не стоит игнорировать код-ревью.
Нет CI/CD
На одном проекте, куда я пришел, ребята релизили вручную через git pull. Сайт при этом регулярно падал. Например, как-то раз попросту не сделали установку пакетов. У поддержки, бизнеса и пользователей копились вопросики к команде. После настройки CI/CD ситуация магически исправилась.
В другой раз наличие git и CI/CD сильно помогло нам то самое “релизить быстро”. Понадобилась немецкая версия сайта, причем срочно и чисто как лендинг для показа потенциальным инвесторам. Имея автоматизированный процесс развертывания и создания новых тестовых серверов на базе CI/CD, мы быстро обрезали все ненужное, подняли отдельные базы, залили переводы – и вуаля – превратили тестовый стенд в сайт для показа инвесторам.
Плюсы от CI / CDНет прозрачного процесса постановки задач
Моя “любимая” история — постановка задач методом развести тред на 150 сообщений в чате. Или в личке
.
Как-то у нас был общий чат с колл-центром. И был QA, в задачи которого входило фильтровать информацию в чате, уточнять детали и если действительно всплывал баг — заводить задачу в трекере. Но сотрудники колл‑центра быстро сообразили, что если писать в чат, то им будут по всей форме задавать всякие уточняющие вопросы, просить скриншотов, урлов и других «сложных» вещей. А вот если писать напрямую «тестировщику Жене», он в половине случаев поправит что‑то быстро через админский доступ.
QA был полностью уверен, что делает доброе дело, а на деле из‑за неизвестных другим багов и масштабов ручной работы мы теряли деньги. Все вскрылось после ухода человека из компании. На нас обрушился шквал новой информации и мелких, но противных багов, которые пришлось срочно исправлять.
А как‑то раз удалось такое пресечь. Появилась «важная» задача, интеграция с большим клиентом. Менеджер в обход всех процессов пошел к разработчику ставить задачу голосом: «Не надо даже думать, просто сделай, как я говорю». Благо, команда уже научилась работать по процессам. Обсудили на дейлике, внесли в трекер. Пошли исследовать и задавать вопросы. Оказалось, методом «не думая» мы могли слить всю коммерческую базу.
Нет правила “1 задача=1 ветка в коде”
Мы делали новый большой кусок системы, который уже ждали платящие клиенты. Запуск должен был принести нам много денег. Каждый день задержки, наоборот, эти деньги съедал. Вместе с командой декомпозировал все на отдельные максимально независимые куски, чтобы мы могли зарелизить функционал как можно быстрее, а различные хотелки и доделки пилить уже в процессе.
Создал в трекере 10 задач, но ребята решили делать их в одной ветке. В итоге дедлайн был вчера, но зарелизить мы не можем: в одной из некритичных задач критичный баг, который быстро не исправишь. При этом, если бы не общая ветка, мы без проблем могли бы зарелизить остальные 9 задач – и запустить систему. После разбора команда приняла подход. Но что интересно, когда я переходил в другую команду, нам пришлось проходить подобный “восхитительный” опыт заново.
По мере роста не заводятся автотесты
Некоторые стартапы живут долго. И копят легаси. Сам я пришел к автотестам как раз потому, что мне было сложно тестировать проекты с историей, к которым я присоединялся. Хотелось автопроверок, чтобы быть уверенным, что моя правка ничего не сломает.
Но был в одном проекте разработчик, который вместо покрытия легаси автотестами хотел все «переписать с нуля». Очень хотел. Я дал ему попробовать переписать кусок с нуля. Он зарелизил свои правки и положил некритический функционал сайта. Все переписанное пошло на помойку, потому что вернуть старый код было дешевле, быстрее и проще. И на «контролируемых потерях» узнал что такое, постмортем. А в качестве своего рода урока человек писал автотесты.
Нет мониторинга ошибок
Часто в стартапах есть чаты с ранними или активными пользователями. И вот приходит к тебе поддержка или продакт, говорит, «у пользователя не работает» (а дальше варианты: «то, не знаю что», «вот это, но деталей не знаю» и так далее). Если у тебя работает, пойти и выяснить, что именно и как не работает — адище. Ты получаешь обрезанный скриншот. Или просто повтор в духе «все еще не работает, почините СРОЧНО» — например, от того же пользователя.
Пока мы не подключили систему мониторинга, о том, что лежит сайт, мы узнавали с задержкой минут в 10 в лучшем случае. От пользователей. С мониторингом мы наконец-то стали устранять баги до того, как нам напишут. А бонусом не раз вскрывали по логам критические баги — например, то, что заказ на сайте как бы создается, но в базу не сохраняется.
Пример мониторинга ошибок с помощью Sentry
Вместо выводов
Вы спросите — так зачем же ты ешь кактус продолжаешь работать в основном стартапах?! Мне нравится выстраивать процессы из хаоса. За это время я заметил, что у таких проектов две беды. Не ведется работа с людьми. И нет нужной автоматизации. Поэтому остается два пути. Образовывать людей. И внедрять проверенные временем инструменты и практики везде, где только можно: если все совсем плохо, то начать с организации релизов через CICD. В рамках этого придется и о git договориться, и код-ревью внедрить. А все вместе послужит хорошей базой для дальнейших улучшений: организации процессов, наладки мониторинга и так далее.
Пройдя оба пути, вы получите совершенно другой уровень скорости и качества разработки. Сам я обычно иду по такой схеме. Если захочется обсудить или дополнить ее в комментариях — буду рад и благодарен. Ну и конечно же делитесь своими историями!
Работа с i18n — автоматизация Google Translate и другие полезные советы / Хабр | Веб-студия Nat.od.ua
Работа с i18n — автоматизация Google Translate и другие полезные советы / Хабр
NPM-пакет для интернационализации i18n используется на фронтэнде для создания мультиязычных вебсайтов очень часто. Перевод текста в нем содержится обычно в json или в js файлах, и требует дальнейшей обработки, чтобы с ним с комфортом могли работать контент-редакторы. В статье описывается как максимально упростить и сделать удобным хранение и внесение изменений в перевод.
Работа с переводом
Есть (наверно) специальные программы для этого, но наиболее удобным мне показалось хранение перевода в Google spreadsheet
В первой колонке идет i18n ключ. Во второй – текст на основном языке. В ячейке С4 находится следующее:
=GOOGLETRANSLATE(B4, “en”, “es”)
Автоматический перевод с английского на испанский соответствующего текста. Формульное значение данной ячейки копируется на весь столбец. Аналогично поступаем с другими колонками/языками.
При редактировании какой либо ячейки вручную, измененный текст уже не будет перезаписываться Google Translate-ом.
Преобразование для i18n
Для начала загрузим наш Google spreadsheet локально: File -> Download -> Tab Separated Values (.tsv)
В i18n у меня разные переводы хранятся в разных json файлах – en.json, es.json etc. Основной (en.json) билдится с фронтэндом, остальные подгружаются с бэка по запросу, поэтому должны быть отправлены туда
en.json
“account”: {
“2fa”: “Two Factor Authorisation (2FA)”,
“2fa_optional”: “Two Factor Authorisation (2FA)”,
“2fa_placeholder”: “Insert here your Two Factor Authorisation”,
“2fa_add”: “Add 2FA”,
“2fa_add_details”: “Copy this code {code} and add to a compatible Google Authenticator app or scan the QRCode bellow with Google Authenticator.”,
“2fa_enabled”: “2FA is successfully enabled”,
“2fa_is_enabled”: “2FA is currently enabled on your account”,
…
Следующий node.js код распарсивает экспортированные из Google spreadsheet данные по джейсонам и раскладывает их куда надо:
parseTsv.js
const fs = require(“fs”);
const rawdata = fs.readFileSync(“./src/resources/lang/translation.tsv”);
let content = rawdata.toString();
let lines = content.split(“rn”);
let columns = lines.split(“t”);
lines = lines.splice(3);
for (let i = 1; i < columns.length; i++) {
const lang = columns;
const data = {}; lines.forEach(line => {
const trs = line.split(“t”);
const val = trs.split(“.”);
if (val.length > 1) {
if (!data]) {
data] = {};
}
data]] = trs;
} else {
data] = trs;
}
});
fs.writeFileSync(
“../backend/public/assets/lang/” + lang + “.json”,
JSON.stringify(data, null, 2)
);
}
fs.copyFile(
“../backend/public/assets/lang/en.json”,
“./src/resources/lang/en.json”,
err => {
if (err) throw err;
}
);
Всё.
Google API
У Google есть API, которое позволяет программно скачать Google spreadsheet (включая авторизацию). Если есть желание и время его интегрировать, то можно еще более автоматизировать данный процесс и даже сделать его частью CI/CD. Но и в описанном выше варианте внедрение сделанных редактором изменений в перевод занимает 20 секунд.