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

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

Чат: https://t.me/htmlshitchat

№5001017849, https://www.gosuslugi.ru/snet/679b74f8dad2d930d2eaa978
Download Telegram
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.me/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.me/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
А вот в комментариях к предыдущему посту ещё полезное :)
Более того, что делать если вам нужно создать тип, параметры которого служат для передачи в функцию, которая является библиотекой и вам нужно передать все required параметры, не делайте это ручками, используйте Parameters

const createPerson = ({
firstName,
lastName
}: {
firstName: string,
lastName: string
}) => ({
firstName,
lastName
})

type CreatePersonParams = Parameters<typeof createPerson>[0];

const params: CreatePersonParams = {
firstName: 'John',
lastName: 'Doe'
};
👍14
#инструмент дня

Каждый разработчик за свою жизнь должен сделать следующее: написать музыкальный плеер, тетрис, игру Жизнь. Если ты веб-разработчик, то ещё свою CMS, PHP-фреймворк, стейт-менеджер и... и уведомления.

Если тебе 14 лет, то ещё и криптобиржу.

Короче, уведомления вообще штука раздражающая. Всегда чего-то не хватает в существующих решениях. Но в любом случае, сегодня вашему вниманию React Hot Toast: https://react-hot-toast.com/

Отличаются маленьким весом, возможностью отмены скрытия пока наведена мышь, поддержкой промисов и JSX-содержимого, стилизуются, прости господи, через Tailwind. Не думал, что внесу это в плюсы, но после UI-китов на Emotion это уже очень хорошо.

Ещё бы туда диалоги добавить, было бы уапще.

Всем тостов, котаны! За мой счет :)

#react #toast #бородач
👍10🤩1