Будни разработчика
14.6K subscribers
1.18K photos
337 videos
7 files
2.02K links
Блог Lead JS-разработчика из Хельсинки
Автор: @bekharsky

По рекламе: https://telega.in/channels/htmlshit/card?r=GLOiHluU или https://t.iss.one/it_adv

Чат: https://t.iss.one/htmlshitchat

№5001017849, https://www.gosuslugi.ru/snet/679b74f8dad2d930d2eaa978
Download Telegram
#фишка дня

Сегодня на ваших экранах новая серия сериала "Не боги горшки обжигают".

На сей раз отличился Kent C. Dodds, которого уж никак нельзя упрекнуть в незнании фронтенда 🙂

Но давайте разбираться. Что же случилось?

Если пройти по ссылке, то можно понять, что случилась типичная для интернет-каталогов ситуация: карточка товара со ссылкой куда-нибудь ещё.

И да, если раньше всем было вообще пофигу на валидацию — рендерит и ладно — то нынче в дело вступают SSR/SSG и они не позволяют гидрацию невалидного HTML 🥁

А попасть в ситуацию такую ну просто слишком легко: достаточно обозвать пару компонентов как-то иначе, чем просто a, и всё, потерялись. Нет, кнопки тоже нельзя. Нет, любой интерактивный контент нельзя.

Так что же делать-то? Псевдоэлементы к спасению!

Верстаем как обычно, вставляем просто две ссылки: одну на товар, вторую куда-нибудь ещё. И растягиваем псевдоэлемент первой на всю ширину. Как-то так: https://codepen.io/alinaki/pen/OJdJQyB

Все довольны, котята спасены!

#css #trick #card #validation
👍161
#фишка дня

Продолбался весь день с подготовкой релиза. С cherry-pick-ами нужных коммитов. Шутки про черрипики точёны оставьте себе.

В чём же проблема?

А в том, что наша команда работает по trunk-модели. Всё сливается в мастер, мастер автоматически релизится как Latest-версия продукта и отправляется в тестирование.

Продакшен-релиз, полученный из стабильного мастера (trunk), обзывается как минорный в рамках модели семантического версионирования.

Когда нужен релиз, а транк не считается стабильным — выбираем нужные коммиты и релизим патч-релиз из своей ветки.

Очень важный момент здесь: время, когда транк считается нестабильным, должно быть сведено к минимуму. В любой момент команда должна иметь возможность релизить текущее состояние проекта.

Для этого реализуются различные feature-флаги и прочие условные условности для разделения потоков пользователей продукта по фичам.

Естественно, такое состояние удерживать не всегда просто, потому череда патч-релизов может быть очень длинной. Это не то чтобы плохо само по себе...

Плохо когда вы забыли о гигиене и смешали коммиты от двух фичей — свободной к релизу и нестабильной. Или когда не засквошили PR-коммит (мой случай).

Тогда выборка черри-пиков может быть не самым приятным занятием. А грязные черри-пики штука очень неприятная.

Так вот, про что же фишка дня? А вот про то, что в процессе я выяснил: совсем не обязательно делать checkout коммита по его хэшу, можно по сообщению! Буквально:

git checkout ':/add multiselect to ui kit'

Причём, сообщение не надо вспоминать полностью!

В итоге, git выберет ближайший к вам такой коммит. Уютно!

В общем, соблюдайте гигиену репы, котаны. Не долбитесь весь день в черрипики.

#git #til #commit
🤩11👍6
This media is not supported in your browser
VIEW IN TELEGRAM
#статья дня

Итак, scroll-driven анимации уже давно реальность, пусть и поддерживаются пока только в Chrome, начиная с версии 115. Но они являются прекрасным примером прогрессивного улучшения, а значит, заработают без проблем сразу, как Safari и Firefox их начнут поддерживать.

Ну и не забываем, что браузеры на базе Chromium занимают львиную долю рынка. Так что для экспериментов полно место.

Итак, сегодня на обзоре статья деврела из Google Брамуса Ван-Дамма. Он пионер CSS-анимаций по скроллу и посвятил этому уже не один год.

Ещё раз ссылка: https://www.bram.us/2023/10/23/css-scroll-detection/

Рассказывается о механиках определения направления скролла и применении разных эффектов в зависимости от, включая задержку начала анимаций.

Поскольку есть немаленькая вероятность, что вы пришли в канал по сегодняшней рекламе, вот собственно её исходник: https://codepen.io/alinaki/pen/rNPVjKG

Всё волшебство кроется в грамотном применении CSS-переменных. Кто-то может помнит, что я рассказывал о нативных миксинах в CSS, об анимациях по ключевам кадрам.

Ключевые кадры штука очень мощная и их не обязательно применять для, собственно, анимаций. Вот, например, можно отложить заполнение некой CSS-переменной: https://codepen.io/bramus/pen/YzdbdyL

В итоге, дальше дело техники: отложенная позиция скролла вычитается из текущей и получаем направление скролла!

А уж куда это знание применить — дело ваше. Рекомендую к прочтению!

#css #animation #scroll
👍12
#фишка дня

Чтобы задать анимацию появления какого-либо элемента на экране при загрузке страницы, добавлении элемента или обновлении DOM совсем не нужно городить сложных конструкций.

Достаточно проделать следующий трюк:

@keyframes appear {
from {
…whatever
}
}

Это анимирует объект в момент его появления из положения, заданного в анимации, в то, что указано в стилях.

Пример на CodePen: https://codepen.io/alinaki/pen/XWXORzM

Попробуйте обновить страницу и поиграться со значениями.

Спасибо Twitter-банде https://twitter.com/keyframers за эту находку.

#css #keyframes #animation #бородач
👍19
#заметка дня

Чуть выше я описывал процесс подготовки релиза из транка и мучения с черрипиками: https://t.iss.one/htmlshit/2318

Но что делать, если git cherry-pick прошёл успешно, а тесты падают? В рабочем пылу можно успеть выбрать не один десяток коммитов (не надо так, к слову) и какой-нибудь окажется зависим от другого. Например, импортов нужных ещё нет.

Очень просто! Используем git revert и указываем нужный коммит. В случае конфликтов команды те же, что и у черрипиков.

Но вообще лучше аккуратно смотреть, что выбираете.

#git #release #trunk #cherrypick
👍1
📣 Масштабное исследование по использованию Kubernetes — накануне дня рождения оркестратора

Kubernetes, одному из самых популярных Open Source-проектов, совсем скоро исполнится 10 лет. Накануне этой даты мы в VK Cloud хотим выяснить, как оркестратор помогает решать задачи маленьких и крупных компаний и поделиться результатами исследования со всем сообществом.

Если вам не безразличен Kubernetes, вы можете внести вклад в развитие общего дела: пройдите небольшой опрос — он займёт примерно 10 минут.

Ваши ответы помогут сформировать большой аналитический отчет. Все участники опроса первыми получат результаты исследования — мы пришлем их на почту.

Приглашаем поучаствовать техлидов и тимлидов, разработчиков, тестировщиков, девопсов, админов, CTO, CIO, CDTO и всех, кто работает с K8s.

Заполнить анкету можно тут: https://bit.ly/3MeMQwZ
👍1
This media is not supported in your browser
VIEW IN TELEGRAM
#библиотека дня

Близятся рождественские и новогодние праздники, а значит, скоро каждый третий сайт получит снег.

Поскольку это неизбежно, давайте сразу скину нормальную библиотеку, которая не заставит ноутбуки ваших посетителей выть: https://github.com/tsparticles/tsparticles

Я помню первое появление этой либы, они начинали с connected particles и были тупо везде. В итоге это настолько надоело, что я вообще выкинул их из головы.

А парни развивались! Демок какое-то дикое количество теперь: https://particles.js.org/samples/index.html

Ну и адаптеры есть буквально под все фреймворки.

Да, снег там тоже имеется.

#particles #effect
👍16🤩2
#такое дня

Эта картинка, с презентации NextJS 14 обошла весь твиттер и все ресурсы для разработчиков. Естественно, со скандалом.

Что тут происходит?

По нажатию на кнопку мы выполняем некий код на сервере, исполняющий SQL через шаблонный литерал в какой-то базе данных.

Почему произошёл скандал? Ну, по мнению уважаемых и разных людей это всё возвращение к PHP4 и его спагетти-шаблонам.

Ну это когда вы сначала к базе данных подключились, а потом <!DOCTYPE HTML> и поехали.

Я не совсем с этим согласен и у меня такое чувство, что все эти уважаемые люди под камнем жили последние 20 лет и пропустили Ruby On Rails, Hotwire, Turbolinks, October CMS, Drupal AHAH, интеграцию Laravel и Vue.js и далее везде.

Камон, мы целую карточную игру на October CMS писали без единой строчки JS, только на директивах и атрибутах, переданных в PHP-шаблон. Да, максимально простую, но зато минут за пять, кроме шуток. Эти вещи не вчера появились, их хотели всегда.

Конечно, код с картинки выглядит убого. Да, директивы "use server" и "use client" — явный костыль. Я сейчас не буду поддаваться истерии и писать о том, что там sql без валидации — откуда вы, блин, знаете? Там же буквально теговый шаблон, sql это функция, которая может делать что угодно. Ну да не суть.

Короче, если бы я до сих пор разрабатывал промо-сайты, я бы сейчас прыгал до потолка, даже несмотря на то, что NextJS я очень не очень люблю. А сейчас у меня просто иные задачи на ином стеке.

Грязь можно развести при любом подходе, если человек не понимает базовых принципов деления на компоненты, не говоря уж о SOLID вообще.

Но будем реалистами — история развивается по спирали и серверные компоненты уже с нами. Да, я прекрасно знаю, где лично я бы их применял, будь у меня такая возможность.

Вы можете воротить нос, а можете творить :)

#nextjs #react
👍25👎1🤩1🤡1
У меня сегодня день рождения. 36 лет.

По этому поводу уже вполне осознанно и намеренно рекомендую вам доклад Вадима Макишвили: 36.

https://youtu.be/nIFClfBXuIQ

Он о том, как не выгорать и найти смысл жизни и работы. И отделить одно от другого, что бывает сложно.

Рекомендую я его на самом деле каждый год, но сегодня, получается, официально.

Не выгорайте, котаны.
61👍20🤩6
#инструмент дня

Я много обещал рассказать о сетапе для разработки веба, но руки не доходили. Так что приходится кусочками 🙂

Если кто общался со мной в чате, знает: первая рекомендация для работы — это Node Version Manager, nvm.

Зачем управлять версиями ноды? Oh, sweet summer child...

Ну, как минимум, проекты не всегда переводят на поддержку самых последних версий, даже всеми любимые фронтенд-утилиты. Да и legacy strikes back.

Но nvm не самое быстрое и удобное решение, она ставит ноду глобально, приходится между проектами переключаться ручками. Инициализация нового терминала может занять до нескольких секунд. Ну, мягко говоря, неудобно для работы со множеством людей и проектов.

И тут на сцену выходит Volta: https://volta.sh/

Написана на Rust, быстро инициализируется, позволяет задать нужную ноду прямо в package.json! В итоге переключился на новый проект — и у тебя уже другая версия Node.js

Настоятельно рекомендую попробовать, даже если ты индиго на острие технологий.

#js #node #nvm #volta #бородач
15
#библиотека дня

Стандартный метод fetch, даром, что встроенный, представляет собой крайне удручающее зрелище, требующее огромное количество бойлерплейта — настроек — вокруг себя.

Поэтому многие до сих пор предпочитают axios, просто чтоб не связываться.

Мой друг и, какое совпадение, подписчик решил эти вопросы реализовав библиотеку extended-fetch, о которой я даже писал, с этим же введением: https://t.iss.one/htmlshit/1290

Слово автору:
если очень обобщенно - это попытка вынести в абстракцию над fetch наиболее востребованный функционал axios
цели просты - максимально возможное следование спецификации, "сквозная" типизация, ноль зависимостей, изоморфный код (да, в nodejs сейчас undici как имплементация fetch)


А теперь у него нашлось немного времени, так что он обновил библиотеку чтобы можно было в дженерике передавать свой тип возвращаемых запросом данных

https://github.com/glebcha/extended-fetch/tree/master#custom-response-type

то есть чтобы можно было делать так

const api = createHttpClient();

interface Book {
id: string,
description?: string,
}

api.get<Book>('/api/books/12’)

Если не передавать ничего в дженерике и выполнять api.get('/api/books/12'), то вернется объединение типов

Promise<string | Record<string, unknown> | RequestInit | Blob | ArrayBuffer | FormData>

Песочница: https://codesandbox.io/s/extended-fetch-react-typescript-ryxrdj?file=/src/App/App.tsx


По-моему, хорошая альтернатива axios-у, если неохота тянуть лишнего.

Камон, котаны, как ещё опенсорсу пиариться?

#fetch #axios #pr
👍24🤡7
#такое дня

Тут пришли сведения, что сообщение выше не поддерживается более старыми версиями Telegram, чем та, в которой оно было создано.

Я приношу свои извинения. Это не первый раз, когда команда телеги совершает подобное, и явно не в последний :(
#инструмент дня

Итак, перед вами стоит задача сделать встраиваемый виджет. Любого рода, от плагина дашборда с показателями продаж до интерактивного баннера. Писать нужно быстро, эффективно, поддерживаемо. И чтоб размер поменьше.

Ванильный JS — мелкий размер, но поддерживаемо — вряд ли. React — один только DOM-слой займёт 40kB, Preact — 4kB, уже очень хорошо, Svelte свернётся в 1.6kB, но учить птичий язык шаблонов — это надо иметь причину...

И тут выходит VanJS со своими 0.9kB: https://vanjs.org/

Сразу пример кода:

const Hello = () => div(
p("Hello"),
ul(
li("World"),
li(a({href: "https://vanjs.org/"}, "VanJS")),
),
)

van.add(document.body, Hello())


Максимально нативно и понятно, не правда ли? И логика построения UI сохраняется. Есть управление стейтом, поддержка TS. Не нужно никакой сборки, садись пиши. Прекрасная документация, включая примеры от сообщества!

А его шаблонный движок вообще может быть использован отдельно. Назвали Mini-Van :)

#van #framework #js #бородач
👍14🤡5
#инструмент дня

Полку API-клиентов прибыло! Я уже рассказывал про GUI для HTTPie, который делали Злые Марсиане, а теперь пришло время рассказать ещё об одном. Почему пришло? Ну потому что Postman борзеет просто по часам и работает отвратительно.

Итак, Bruno: https://www.usebruno.com/

Хранит все запросы и коллекции в простых текстовых файлах (разрабы придумали язык разметки Bru специально для этого). Правда, я знаю как минимум одного человека-пользователя PhpStorm, который на этом месте презрительно хмыкнул.

Как следствие, все ваши коллекции запросов хранятся просто на диске. Нужно облако — используйте Git. Вот так просто. Планов на своё облако у команды нет.

Да, есть платная версия, 12 долларов в год (двенадцать в год). В ней из интересного есть поддержка вебсокетов и массового прогона данных по коллекциям для нагрузочного тестирования.

Кажется мне, для многих профессиональных пользователей Postman основной причиной всё ещё будут скрипты, но они и в Bruno есть. Посмотрим, куда вывезет.

#api #client
👍16
#такое дня

Сегодня на работе обновили проект до последней стабильной Node.js и была сказана немного неаккуратная фраза:
— Next on our list is Next.js 14.

И понеслась...

— I have remixed feelings about this
— You are being so reactive
— Not a good move from my vue
— Tired of this, I'll rest on my nest
— Bun intended
— I hate you all I want to underscore this. You’ve ruined everything I believe is good with humanity.
— I'll go
— This conversation is full of solid puns

Продолжим в комментариях? Или ну такое?
👍14
#заметка дня

В чём разница между селекторами :disabled и [disabled]?

Вот вы не знали (наверное), а она есть!

Псевдокласс :disabled выберет любой элемент, находящийся в отключённом состоянии.

Селектор атрибута [disabled] выберет любой элемент, имеющий атрибут disabled.

Например, <input type="text" disabled/> подпадёт под оба селектора, вне зависимости от того, случилось это на этапе прямого рендера или через установку свойства disabled узлу.

Да не томи уже!

Короче, суть дела в том, что атрибут disabled может быть установлен на fieldset, в таком случае поля будут недоступны, но в селектор input[disabled] не попадёт ничего.

Сложно? Вот пример: https://codepen.io/alinaki/pen/VwgKOPE

Короче, аккуратнее.

#css #disabled
👍11
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

Одна из самых недооценённых возможностей CSS-анимаций, это функция steps(n).

Зачем оно надо? Ну, исходя из названия, чтобы сделать использование временной шкалы дискретным, за равные промежутки. Кадры, короче говоря.

Почему недооценена? Потому что SVG, Lottie и Rive-анимации предоставляют чуть больше возможностей, но ценой подключения скриптов или целого рантайма. А всего-то надо подготовить лист спрайтов-кадров.

Поэтому сегодня я дам вам два примера. Первый — анимашка шагающего пиксель-артного Локи: https://codepen.io/alinaki/pen/GRPrYdv

Здесь есть небольшой хак чтобы картинка стала отзывчивой: вместо размера указано соотношение сторон, а фон сдвигается в процентах. Ну и, чтобы пиксель-арт оставался собой, а не размывался, стоит накинуть соответствующее правило image-rendering.

И наглядно от мэтра Джея: https://codepen.io/jh3y/pen/KKbpeBQ

Если концепция спрайтов вам совсем не знакома, в этом примере можно включить раскадровку.

Никаких рантаймов, красота.

#css #sprite #animation #бородач
👍17
This media is not supported in your browser
VIEW IN TELEGRAM
#фишка дня

Стопудово вы делали эффекты как на видео через три div-а или span-а. Ну просто потому что трансформации на SVG это абсолютная боль.

Типа такого: https://codepen.io/alinaki/pen/abXpvyQ

Да, пример очень простой, но даже это на SVG бывает проблемно санимировать.

Хотя, казалось бы, для этого и предназначено.

А вся проблема в том, что для SVG определение координат для преобразований происходит немного иначе, нежели чем для элементов. Выходов из ситуации есть несколько.

Первый, от Аны Тюдор: исправить viewBox, поставив вместо 0, 0 (левый верхний угол) — -width/2,-height/2, соответственно, исправив остальные координаты.

Второй, интереснее, от Джея: указать следующие правила в CSS:

transform-box: fill-box;
transform-origin: 50% 50%;


Правило transform-box исправит положение координатной сетки, от которой мы уже сменим дефолтную точку отсчёта для преобразований — transform-origin.

По-умолчанию, кстати, transform-box установлен как view-box. То есть, в нашем примере, заполняет лишь 24 пикселя по каждой стороне 🤡

А вот и, собственно, пример:
https://codepen.io/alinaki/pen/YzBNyEz

Не бойтесь анимировать SVG, котаны. Просто не полагайтесь на дефолт.

#css #transition #svg
Please open Telegram to view this post
VIEW IN TELEGRAM
👍25
#заметка дня

Что делать, если нужная вам библиотека не предоставила типы для всех публичных методов?

Ну вот такое вот архитектурное решение: метод экспортирован из модуля, а тип или интерфейс — нет?

Делать unknown или any? Копировать и переопределять с помощью as?

Ни в коем случае! Вам нужен простой советский... ReturnType: https://www.typescriptlang.org/docs/handbook/utility-types.html#returntypetype

Пример использования — на иллюстрации. Ну или ещё можно так:

const createPerson = () => ({
firstName: 'John',
lastName: 'Doe'
})

type Person = ReturnType<typeof createPerson>

Не делайте ерунды, котаны. Читайте документацию.

#typescript #ts #types #бородач
👍191
А вот в комментариях к предыдущему посту ещё полезное :)