Журнал «Веб-платформа» @web_platform Channel on Telegram

Журнал «Веб-платформа»

@web_platform


📍 Журнал о том, как всё устроено в веб-платформе и что происходит в индустрии фронтенда

⭐️ Новости, полезные фичи, находки и напоминания

👨‍💻 Главред @zyuzin_vitaly

Виталий и Веб-платформа (Russian)

📍 В нашем Telegram-канале "Виталий и Веб-платформа" вы найдете увлекательные статьи о том, как устроена веб-платформа и что происходит в индустрии фронтенда. Мы делимся последними новостями, полезными фичами, интересными находками и напоминаниями для разработчиков. Наш автор - @zyuzin_vitaly, который делится своими знаниями и опытом в области веб-разработки. Присоединяйтесь к нам, чтобы быть в курсе всех важных событий и трендов в мире веб-технологий!

Журнал «Веб-платформа»

01 Jan, 14:45


Журнал «Веб-платформа»

Итак, первая новость года: 1 января вышла новая мажорная версия этого блога! Теперь это не только блог о моих взаимоотношениях с веб-платформой, а полноценное медиа, в котором будет показан взгляд разработческого сообщества на разные части веб-платформы.

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

Минорные обновления:
- еженедельные дайджесты о происходящем в веб-платформе и индустрии фронтенда моего авторства (aka Фронтвестник) теперь называются #Пульс_веб_платформы
- периодические литературные вбросы объединены под названием #Фикшн_веб_платформы

Новые фичи:
- наработки, эксперименты, полезные фичи, находки и напоминания моего и не только авторства теперь объединены в рубрике #Лаборатория_веб_платформы
- новая рубрика #Книжый_клуб_веб_платформы с короткими выжимками книг вокруг веб-разработки

Также выражаю благодарность всем, кто поддерживал канал в прошлом году! Донат или любой поддерживающий/критикующий коммент мотивируют продолжать писать и думать о дальнейшем развитии, то есть по сути дают жизнь этому каналу.

2025 — поехали! 🏁

@web_platform | Поддержать канал 🤝

Журнал «Веб-платформа»

01 Jan, 14:45


Channel name was changed to «Журнал «Веб-платформа»»

Журнал «Веб-платформа»

30 Dec, 11:09


#Фикшн_веб_платформы

(предыдущая часть)

transition

«Всё понятно», — пробурчал себе под нос Фил, глядя на буквы, которые сложились в ссылку на домене netlify. «Очередной скам», — подумал он и решил удалить с машины бот-аудитор, но что-то его остановило. Название поддомена в ссылке было какое-то странное. Сначала Фил принял его за хэш, но тут явно вырисовывались какие-то слова на незнакомом языке.

Любопытство взяло верх, и Фил решил перейти по ссылке desinesperarequihicintras.netlify.app. Если что браузер работает в stealth-режиме под VPN, так что украсть куки или отследить трафик с его машины не удастся.

«Наверное реклама очередного майнд-трекера… Таргетологи хреновы!», — подумал Фил. Подобные штуки его уже давно не интересовали, и своей электроэнцефалограммой ни с какой корпорацией он делиться не собирался.

Перейдя на сайт, Фил удивлённо увидел текст на пустой странице:

А и Б сидели на трубе,
А упала, Б пропала,
Кто остался на трубе?


«Ээээ…», — промычал Фил. В этот самый момент часы на руке у него завибрировали и на них показалось пуш-уведомление, призывающее через две минуты подключиться к синку. «Чёрт!», — выругался Фил. Он совсем забыл о сегодняшнем позднем синке с рабочей группой. Фил полез в ящик стола, пошарил рукой и достал корпоративный VR-сет.

Надевая VR-сет, Фил старался освежить в памяти, чем сегодня был занят. Он понял, что многого про сегодняшний день рассказать на синке не сможет. Целый день он провозился с рефакторингом, но пока мог похвастаться только частично загруженным в голову контекстом проекта и парочкой переписанных небольших модулей системы.

К слову, сейчас уже такая прямая работа с кодом встречалась в ежедневной рутине Фила нечасто. Обычно для разработки новых фич приходили сырые описания от менеджеров. Задачей Фила было внятно оформить новое описание в базе знаний о системе, снабдить инфой о краевых случаях и исключениях, добавить контракты и тестовые кейсы. После этого обновление базы знаний уходило корпоративной AI-системе Levia-3, которая сама генерила новый код фичи по обновлённым описаниям, контрактам и тест-кейсам.

Да, название профессии «оператор ЭВМ» из прошлого века в таком подходе играло новыми красками. Оператор корпоративной AI-шайтан-машины. Которая знает ответ всегда. Ну или почти всегда.

В случае, когда Levia-3 всё таки не справлялась, но делала вид, что справляется, её нужно было дообучить для решения конкретно этого типа задачи или кейса. Вот тут уже приходилось включать в работу «кожаного» разработчика и писать, составлять и размечать датасеты, создавать новые тесткейсы.

Всяческие рефакторинги и доработки легаси-части системы, ранее не описанные в базе знаний, тоже нужно было выполнять вручную. Собственно говоря, именно этой задачей Фил сейчас и занимался — нужно было загнать ранее не описанную часть фронтенд-системы в ведение Levia-3 и решить все сопутствующие проблемы.

Не то чтобы супер-увлекательное дело, но за дообучение Levia-3 полагались дополнительные токены, а токены лишними не бывают.

Синк прошёл без неожиданностей, и после его окончания Фил устало снял VR-сет, положил на стол, замер и недвигающимися глазами посмотрел куда-то сквозь монитор. Он так сидел некоторое время, а затем взгляд его сфокусировался на открытой в браузере странице с детским стишком.

«Так, таааак…», — задумчиво протянул Фил и открыл инспектор кода браузера. Помимо текста в HTML-коде он увидел скрытое поле <input type="hidden" value="bGltYm8=" />. «Скрытое и зашифрованное поле, хммммм…», — пробормотал Фил и как-то машинально стал думать над разгадкой. «А и Б, А и Б…». Что-то это напоминало…

И тут Фила озарило — atob! Шифровку можно разгадать прямо в консоли. Фил написал в консоли вызов функции atob, передал туда значение из скрытого инпута и запустил код. Консоль выдала разгадку — limbo.

«Эээмммм», — в задумчивости протянул Фил, размышляя, что с этим делать дальше. «Может быть это роут?», — подумал он, вписал в адресную строку desinesperarequihicintras.netlify.app/limbo и нажал Enter.

(продолжение следует)

@web_platform | Поддержать канал 🤝

Журнал «Веб-платформа»

27 Dec, 06:00


#Пульс_веб_платформы 27.12.2024

Новости
- у React Aria/Spectrum появился конкурент Base UI в виде движка, извлечённого из недр Material UI, без определённой системы стилей (движок предоставляет класснеймы и CSS-переменные), с поддержкой data- и aria-атрибутов: пока представлена альфа-версия, в планах запилить ещё компоненты, Tailwind-плагин, багфиксы и документация
- опубликован отчёт по опросу JetBrains State of Developer Ecosystem Report 2024: JS всё ещё в топе языков, TS медленно растёт, HTML/CSS так же медленно падает, что в целом показывает инертность платформы несмотря на хайповость некоторых инфоповодов; Go и Rust — языки, которые респонденты собираются заадоптить; TS, Rust и Python — самые многообещающие языки (вот будет революция, если в JS таки случится разделение на базовую/надстроечную часть); на JS/TS больше всего реализуют UI; AI используют для более быстрого поиска информации, кодинга и выполнения рутинных задач, а также для изучения новых технологий; зарплата в US и Индии различается в 8 раз; топовых зарплат больше у Scala-специалистов, меньше всего — у PHP-, HTML/CSS- и JS-разработчиков; сложные части работы разработчика — коммуникации и понимание требований
- в новой версии Bun сделали лок-файлы bun.lock в JSONC-человекочитаемом-формате (так удобнее мерджить в git → DX — существенное конкурентное преимущество)
- в версии Zod v3.24.0 впервые имплементирована спека Standard Schema — попытка объединить усилия авторов валидационных либ для создания общего интерфейса, который позволит проще интегрировать разные части экосистемы между собой

Проекты
- whatunit — единиц измерения в CSS становится всё больше и все их в памяти уже не удержать, поэтому появилась такая диаграмма решения, какую единицу выбрать в той или иной ситуации (текст/отступы/позиционирование, респонсив/фикс, флекс/грид); из тех, что я уже забыл — текстовые ch для ширины символа , ex для высоты строчной буквы , cap для высоты заглавной буквы

Статьи и демки

JS
- WeakMap и WeakSet — это «самоочищающиеся» аналоги Map и Set, которые помогают бороться с утечками памяти в задачах, где необходимо хранить набор ссылок на DOM-ноды или же создать кэш вида «ключ-значение»
- в DOM есть встроенная «шина сообщений» BroadcastChannel, которая предназначена для обмена сообщениями посредством postMessage (не путать с window.postMessage) и подписки на событие "message" в рамках одного ориджина, годится для обмена сообщениями между вкладок браузера, окнами, айфреймами, например, чтобы прокинуть по всем вкладкам сессию залогиненного пользователя или заполненную форму

CSS
- семейство «подрезающих текст» свойств text-box (text-box-trimtext-box-edge) должно облегчить взаимодействие с дизайнерами в тонких материях, там где отступы реально нужны для решения задач дизайна, а из-за дополнительного отступа тестовых боксов в браузере эти отступы или убираются костылями (привет тем, кто выравнивал текст в кнопке по центру), или на них забивают
- тот самый «указывающий» треугольник у тултипа можно реализовать с помощью одностороннего бордера, выглядывающей из под тултипа половины перевёрнутого квадрата, вырезания clip-path-ом нужной фигуры из прямоугольника или же border-image + conic-gradient
- текст с цветом анимированного градиента достигается с помощью модерновой комбинации свойств @property + linear-gradient() + background-clip
- «нативный» импорт стилей из других стилей, например, @import url("https://somesite.net/xxxxxxx.css") всё ещё плохо работает в браузерах, а точнее блокирует рендер до полного скачивания и парсинга CSS-файлов, по возможности избегайте этого подхода

Платформа
- если взять бесконечную ленту, на которой можно печатать, печатающий элемент, индикатор состояния машины и программу, а также 5 команд: печать символа, сдвиг печатающего элемента вправо и влево, переход на определённое состояние машины и её остановка, то можно вычислить в принципе любое вычисление, с которым сталкивается современный компьютер (computer собсна «вычислитель»); пожалуй, без этой идеи Алана Тьюринга мир бы сейчас был совсем другой

@web_platform | Поддержать канал 🤝

Журнал «Веб-платформа»

20 Dec, 06:01


#Пульс_веб_платформы 20.12.2024

Новости
- вышла Node.js v23.4.0: из-под флага вынесен модуль node:sqlite, то есть теперь по дефолту доступно создание SQLite-бд, выполнение SQL-запросов напрямую в Node
- прошёл 105-й митинг TC39: Intl.DurationFormat продвинулся на Stage 4, Error.isError на Stage 3, а также на Stage 1 появился Import Sync — нативный способ синхронных импортов в JS import.sync('react')
- появились результаты опроса State of JS 2024, 14к разработчиков преимущественно мужчины из США и EC среднего возраста и 5-10 лет работы в индустрии поделились статой: уже довольно популярны Object.groupBy(), Promise.allSettled(), array.toSorted(), string.replaceAll/matchAll(), но мешает браузерная поддержка, а также болит отсутствие статической типизации из коробки; webpack, Parcel, а также отдельно esbuild и Rollup продолжили уступать позиции Vite; React/Next.js в целом в топе, но с годами популярность падает и люди страдают от их разнообразных проблем и сложности, Vue.js примерно на том же месте по популярности, что и в 2021; pnpm заметно популярнее npm/yarn workspaces; Astro многим нравится, популярность Lit чуть подросла; Vitest стремительно набирает популярность, но Jest всё ещё также в топе, хоть и вызывает страдания (Deno и Node с их встроенными возможностями тестирования пока на дне); в топе используемых либ Lodash, date-fns, Zod, Moment, Day.js; Express всё ещё намного популярнее Nest и Fastify; большинство опрошенных используют TS на фронте, больше половины — на бэке; больные точки: архитектура, стейт-менеджмент, управление состоянием, билд-тулы
- Ecma выпустили спецификацию Source map format: цели — поддержать двунаправленный маппинг сорсов и деобфускация стэк-трейсов на сервере
- 17 декабря исполнилось 28 лет CSS: забавно, что со временем всё больше людей начинают работать с технологиями, которые старше их самих, и от этого воспринимают их «древними»

Проекты
- prompts-js — асинхронные версии вызова диалогов alert, confirm и prompt на промисах и нативном элементе <dialog> (просто JS-файл, красота, если бы ещё добавить JSDoc с описанием типов, то вообще было бы идеально)

Статьи и демки

JS
- некоторое время назад SQLite решили полностью переписать на Rust (оригинальный модуль libsql написан на C, что делает его уязвимым со стороны памяти по своей природе) и так появился проект limbo, который в случае успешного завершения заменит libsql; интересно, как будет выглядеть в этом случае поддержка со стороны Node
- забавное замечание: чтобы выполнить полный test suite Node.js может занять несколько дней, поэтому это делает не на каждый чих, и поэтому сравнивая 20 и 22 версии ноды, некоторые API показали улучшение по перфомансу, а некоторые наоборот просадку
- общепринято, что в JSON нельзя добавлять комментарии, но это правило можно нарушить, если вы уверены, что JSON-парсер, который будет читать ваш файл, не сломается в процессе
- если вы задались задачей рендерить веб-компоненты на сервере, то нужно решить проблему отсутствия DOM-а и глобальных объектов (window, document…): для этого можно использовать фреймворк (Lit, WebC, Enhance) или же взять либу Happy DOM — «безголовую» эмуляцию DOM, взять оттуда необходимые объекты и сгенерить HTML и JS
- в React 19 появилась более полная поддержка веб-компонентов: теперь можно в «пропах» веб-компонента прокидывать объекты или функцию-колбек (даже с кастомным событием)
- в управлении состоянием в React-приложениях стоит выносить работу с ним из рендер-функций, в идеале не используя useState/useEffect там, где можно их использовать (то есть почти везде)
- в случае прокидывания сеттера в дочерний компонент вместо использования «общей» функции-колбека начинает «течь» абстракция, этого лучше всего по умолчанию избегать

CSS
- ключевой момент из внедрения Container Queries в Netflix — меньше использования CSS- и JS-кода для управлением лейаутом → меньше багов, но при этом если использовать полифилл, то могут быть проблемы с перфом, надо проверять

@web_platform | Поддержать канал 🤝

Журнал «Веб-платформа»

13 Dec, 06:01


#Пульс_веб_платформы 13.12.2024

Новости
- вышла новая версия Safari 18.2: поддержано свойство text-box (text-box-trim + text-box-edge) для «подрезки» вертикальных отступов у тестовых строк; @view-transition заработал не только в пределах одного документа, но и между разных страниц; background-clip: border-area маскирует рамку нижележащим слоем; теперь работает деление на единицы измерения в calc(100vw / 1px); поддержаны scrollbar-width и scrollbar-gutter для стилизации скроллбаров; добавлена функция Scroll to Text Fragments; поддержан <input type=week>; у PointerEvent появился метод getPredictedEvents() для предсказания будущих позиций курсора; поддержан Promise.try
- в Mozilla представили новый брендинг с консольным динозавром-флажком, а также наняли три новых топа: в Firefox выходят вице-президент FF и вице-президент по продукту FF, а также вице-президент по инфраструктуре
- CSSWG подытоживают год и выкатывают новые FPWD: Display 4, Overflow 5, Multicol 2 и Color HDR 1, из интересных нововведений: reading-flow для управления порядком чтения контента скринридером в flex- и grid-контейнере; интерполяция и анимация свойства display; псевдоэлемент ::column в многоколоночном контейнере; свойство scroll-marker-group и группа псевдоэлементов ::scroll-marker-* для стилизации скролл-контейнера; управление яркостью HDR-контента
- вышел отчёт Cloudflare Radar 2024: HTTP/2 вдвое опережает HTTP/3; React, Next.js — самые популярные фреймворки; PHP вдвое популярнее Node.js; для создания API Go используется чаще Node.js; Yandex — второй по популярности поисковик — подсдал к концу года; среди браузеров Chrome держится на 65%, потом идёт Safari, Edge, а у Firefox 4% пользователей; в северных странах преобладает десктопный трафик, в Афркие, Индии, Южной Америке — мобильный

Проекты
- skia-canvas — «безбраузерная» реализация API canvas для node или десктопа на GPU
- html-react-parser — парсер HTML в React-компонент

Статьи и демки

JS
- общение компонентов на основе событий помогает избежать проп-дриллинга или связывает разнесённые части одной системы; есть простой вариант хука useEvent (создаёт эвент и отдаёт диспатчер) или более сложный в виде шины событий
- порой бывает нужно сделать небольшой проект, куда тянуть бандлер вместе с процессом билда не обязательно: для локального сервера и HMR сгодится browser-sync, сторонние пакеты можно загрузить с  unpkg.com/npm и прописать алиасы в <script type="importmap">; TS заменяется на JS + JSDoc, tsc проверяет код на соответствие типов
- в ref элемента в React можно передать функцию, в параметре которой будет DOM-нода и в React 19 ref-функция теперь может возвращать cleanup-функцию, как в useEffect
- вслед за React 19 вышел Next 15.1 со свежим React на борту (для Pages Router ещё можно React 18), улучшен дебаг ошибок

CSS
- в бете Tailwind 4 был представлен механизм стилизации дочерних элементов из заданного варианта родителю <div class="**:data-avatar:rounded-full"> (все дочерние элементы с атрибутом data-avatar будут скруглёнными), что дизраптит саму идею атомарных классов, помещая в classname «мета-CSS» и давая возможность использовать фреймворк ещё более противоестественным способом
- с тех пор, как иконочные шрифты стали считаться анти-паттерном, технологии пошли вперёд: появились вариативные и цветные COLR шрифты, хорошо сжимающий формат woff2 и font-display стали повсеместно поддерживаемыми, в content появился alt-текст для скринридеров; тем не менее шрифт может не загрузиться или может быть проигнорирован системой, поэтому SVG — всё ещё лучший вариант для веб-иконок
- color: lch(from var(--bg) calc((49.44 - l) * infinity) 0 0) автоматически меняет цвет текста с чёрного на белый в зависимости от цвета фона

Платформа
- в девтулзах Chrome 131 теперь помечаются те анимации, для которых не задействовался процесс «композитинга» (анимация height или кастомного свойства)
- если знаешь особенности платформы, базового языка (JS, CSS, HTML) и браузеров, становится легче кастомизировать вещи в рамках фреймворков, находить и фиксить баги, решать проблемы проще

@web_platform | Поддержать канал 🤝

Журнал «Веб-платформа»

06 Dec, 07:38


#Пульс_веб_платформы 06.12.2024

Новости
- вышел релиз библиотеки компонентов React Aria/Spectrum: добавлены компоненты Disclosure and Accordion; что примечательно, под капотом не используется summary/details, видимо ещё не до конца распространилось стабилизировавшееся API; также в React Aria появился компонент ToggleButtonGroup, управляемый с клавиатуры; также либа теперь полностью Typescript Strict-совместима
- выпущен Astro 5.0: всё то же, что было в бете (Content Layer — запрос контента из внешнего ресурса, Server Islands — отложенный рендеринг с сервера, astro:env — типобезопасный env-ы) + экспериментальные фичи для отображения респонсив-картинок, кропа, а также импорта SVG-компонентов
- вышла стабильная версия React 19: помимо новых API теперь одинаковые подключенные стили не будут дублироваться и будут подключаться в указанном порядке, также можно указывать <meta> без дополнительных либ и ещё полностью поддерживаются кастомные элементы (веб-компоненты)

Проекты
- представьте, что вы разработчик нового React-фреймворка и хотите, чтобы приложение, написанное на вашем фреймворке, могло одной кнопкой деплоиться на Vercel, Netlify и ещё многие другие хостинги… Разработка и поддержка всего этого добра сразу навевает тоску. Но выход есть! vinxi. Одной строчкой в Vite-конфиге подключаем поддержку нужного провайдера, как и сделал Tanner Linsley в своём фреймворке TanStack Start
- onlook — oss визуальный редактор React-приложения: ещё одна попытка избавиться от «макетов», чтобы собирать их сразу в коде
- react-verification-input — маск-инпут для ввода пин-кодов, React
- dontfuckwithscroll — не воруйте скролл, наглядное пособие

Статьи и демки

JS
- если вы знаете куда с одной страницы пользователь пойдёт дальше, можно предзагрузить или даже пререндерить этот урл; для этого с помощью Speculation Rules API в скрипте <script type="speculationrules"> нужно указать секцию prerender и prefetch с возможной настройкой условий запуска (если адрес включает строку, селектор соответствует выражению…); Chromium-only
- при создании модалки нужно по-хорошему предусмотреть много вещей: триггерный элемент, кастомный контент и класснеймы, обработчики событий, рендер в Portal-е, управление фокусом; в общем, проще всего взять готовую headless-либу, например, Radix или React Aria и прикрутить свою логику и стили
- если стоит задача заняться перфомансом, то можно начать с PerformanceObserver, с помощью которого можно программно получить не только разовое значение метрик (FID, CLS, LCP), но и обсёрвить, то есть повторно снимать метрики во время пользования приложением
- а что если не рендерить SPA-целиком в <div id="root">, а подгружать React только в определённый интерактивный островок вашего сайта? Да не, бред какой-то… или нет?
- с View Transitions API можно методом startViewTransition запустить нативную плавную смену двух DOM-нод; но что если как раз императивно запускать не хочется, а хочется, чтобы DOM-нода добавилась и транзишн автоматом выполнился? Берём MutationObserver и вуаля: нода появилась, обсёрвер триггернулся, колбек запустился, а в нём уже и startViewTransition

CSS
- рецепт, чтобы создать у элемента эффект замёрзшего стекла: взять backdrop-filter: blur(10px) и насыпать кучу теней для создания глубины; для создания «стеклянной прозрачности» у блока определённой формы можно добавить ещё и mask-image
- единицы измерения lh — величина вычисленного значения line-height, её удобно использовать для задания динамических отступов между тестовыми блоками (rlh — аналог для рутового элемента)
- впервые встретился такой UI-элемент — кнопка в трёх состояниях (да, нет, не знаю): её можно реализовать на чекбоксах, :has(:checked) и pointer-events

HTML
- в HTML у ссылок <a> есть атрибут ping — легальный способ отслеживать нажатие по ссылке, отсылая запрос по указанному в значении адресу, которое к тому же сложнее заблочить
- напоминание в следующий раз, когда будете собирать форм-визард, использовать <fieldset> для каждого «шага» с набором полей (правда, если не столкнётесь с проблемой стилизации, хехе)

@web_platform Поддержать канал 🤝

Виталий и Веб-платформа

29 Nov, 09:09


#Пульс_веб_платформы 29.11.2024

Новости
- вышел Angular 19: в современном фронтенде, если фреймворк не поддерживает SSR и гидрацию, а также сигналы, конкуренцию среди модной-молодёжной аудитории уже не выдержать; и Angular в этом плане снова с строю: для каждого роута можно задать отдельно режим рендера Server/Client|Prepender; для отрендеренного, но незагидрированного HTML будет записываться события пользователя, чтобы когда доедут скрипты, «проиграть» их заново и запустить
- вышел Firefox 133: поддержана опция keepalive у fetch, так что теперь во всех браузерах можно пользоваться fetch c keepalive вместо Navigator.sendBeacon(), если важно, чтобы определённый запрос завершился, а не прерывался, в случае unload-а страницы
- вышел TypeScript 5.7: улучшена проверка для никогда не инициализируемых переменных; поддержан таргет до es2024; поиск tsconfig.json по родителям теперь не будет останавливаться на первом найденном; поддержано API Node.js 22 module.enableCompileCache() для более быстрого выполнения повторных операций
- вышел Tailwind CSS v4.0 Beta: интересна траектория развития в сторону CSS-first конфигурации (т.е. использование кастомных переменных, слоёв и директив) вместо конфигурации в JS; изначальный спорный подход с вынесением всего в classname уже стреляет по ногам, требуя от разработчиков soul-crushing backward compatibility work — это рано или поздно или приведёт TW в тупик, или заставит переродиться в тулкит с «естественным» набор миксинов, пресетов и ручек для управлениях внутрянкой
- вышедший Deno 2.1 стал первым LTS-релизом и среди прочего включает новую команду deno outdated для проверки устаревших версий пакетов, эмбеддинг «статических» файлов в бинарник при запуске deno compile, а также возможность указать зависимые команды при запуске других команд
- вышел мажор Vite 6.0: для небольших проектов ломающие изменения не выглядят болезненными, скорее добавились новые фичи и апдейтнуты зависимости
- в Node 22 в ближайшее время появится поведение --experimental-require-module без флага

Проекты
- pkg-graph — визуальное исследование зависимостей npm-пакета, строит граф на лету в браузере
- spoiled — компонент спойлера для React, под капотом Paint API (для Safari предусмотрен фолбек)
- dual-range-input — двойной range-инпут, собранный из двух обычных range-инпутов

Статьи и демки

JS
- инфа по базовым типам TS для React собрана в одно месте: чтобы выцепить тип возвращаемого значения функции — <ReturnType> и <Awaited<ReturnType>> — для асинхронной функции; тип ReactNode лучше ReactElement тем, что шире; props: React.ComponentProps<"button"> для типизации базовых пропсов HTML-элемента или компонента; использование as const для типизации tuples, чтобы TS не считал их массивами
- история, как в Reddit в разросшуюся монорепу внедряли Vite, пара интересных фактов: чтобы подружиться с Lit пришлось добавлять ?inline ко всем путям стилей, чтоб не вставлять их в страницу, а инлайнить строками в бандл; чтобы заюзать на полную ESM пришлось во всех модулях добавить export maps, которыми раньше пренебрегали
- favicon — единственно гарантировано видная часть сайта во вкладке браузера, поэтому её можно использовать для индикации неактивности пользователя или нотификации о событии в свёрнутой вкладке

CSS
- когда-то в Safari затащили эффектное свойство background-clip: text для создания «текстурного» текста путём «вырезания» фона, и оно долго работало только с префиксом -webkit, и вот теперь только в Safari появился ещё один вариант — background-clip: border-area — только теперь, чтобы текстура фоновой картинки осталась на месте рамки, а не букв
- oklch удобен тем, что позволяет легко подстроить один из параметров цвета, например, lightness, чтобы сделать один и тот же цвет на тёмном фоне более ярким, а на светлом — более тусклым oklch(calc(0.75 - var(--colorAdjuster)) 0.2 328)

HTML
- с помощью <link rel="preload" as="image"> с атрибутами imagesrcset, imagesizes и type можно прелоадить картинки только в браузере, поддерживающий формат, заданный в type, например, type="image/avif"

@web_platform | [Поддержать канал 🤝

Виталий и Веб-платформа

26 Nov, 06:02


#Фикшн_веб_платформы

day0

Фил устало открыл крышку своего ноутбука. Рабочий день только начинался, но на часах уже был полдень. Может быть сказывалась глубокая осень, или же давно не случавшийся с ним отпуск, но Фил чувствовал себя выжатым досуха. Он работал разработчиком в большой, поросшей бюрократическими мхами компании. Проект, над которым сейчас велась работа, шёл сложно. Вроде и хорошо, что наконец взялись за переписывание фронтенда большого легаси-проекта, но от него было ощущение засасывающего ненасытного болота, которое пока что не удавалось даже целиком охватить умом, зато ум болото осваивало успешно.

Чтобы как-то взбодриться, Фил принёс с кухни за рабочий стол в комнату полулитровый стакан кофе, недавно принесённый курьером вместе с бургером, который Фил заточил на завтрак. Потягивая кофе, он надел наушники и врубил музыку со стриминга. Какой-то незнакомый рок-н-рольный голос бодро пел под акустику: «Может быть это алкоголизм? Может быть недостаток любви и добра? В этом мире так мало тепла…»

Фил зачекинился в командном мессенджере и погрузился в дебри зависимостей старого проекта. Пока что попытки разобрать гигантский монолитный модуль не приводили к успеху. Изменение какой-нибудь штуки в одном месте вызывало ошибки в других несвязанных местах. Сложности также добавляло то, что в последнее время участились взломы пакетов в экосистеме npm, пребывающей в упадке. Многие некогда крупные и успешные пакеты, сейчас в 2030 году, были в лучшем случае заброшены мейнтенерами, а в худшем — распространяли рекламу или скам. С тех пор, как широко распространились AI-модели, генерирующие код, в реестр npm хлынули пакеты сомнительного качества. Поэтому ставить что-то из реестра можно было только на свой страх и риск, сканируя бандл AI-ботом-аудитором. Фил как раз недавно поставил себе такой — новый быстрый бот Phosphor. В большинстве случаев откровенное вредоносное ПО бот отлавливал, но мелочи часто приходилось править и дорабатывать самому, форкая проект.

Фила бесило, что часть незаменимых пакетов собиралась только под какой-то древней версией Node.js, и ещё они при этом не дружили друг с другом. Тут ещё как назло две домашние кошки Фила устроили между собой разборки и опрокинули стакан с недопитым кофе на стол, едва не залив на ноут.

Фил выругался и пошёл на кухню за салфетками, чтобы устранить последствия потопа. Вернувшись и вытерев лужи со стола, Фил глянул на экран в открытую консоль браузера и заметил, что там по одной выплёвываются рандомные английские буквы раз в какой-то интервал. «Это что ещё за хрень», — проворчал Фил. «Странно, ведь в новых пакетах бот не нашёл ничего криминального», — подумал он и начал искать в исходниках, что могло выкидывать странные логи в консоль. Как будто отдельные буквы выводились в консоль из разных мест по независимым друг от друга таймерам, потому что какого-то единого лога Фил найти не смог.

Промучившись с поиском источника странных логов и ничего не найдя, Фил в раздражении плюнул и решил проветриться. Уже стемнело, он брёл вдоль дороги в холодном свете светодиодных фонарей и думал. Всё это нашествие AI-кодописателей, кодоревьюеров и кодотестировщиков вгоняло в уныние. Программы и тулинг вокруг них стали более непредсказуемыми и ненадёжными, ведь в случае большинства AI-продуктов даже их создатели толком не знали, от чего и как именно AI выдаёт тот или иной результат.

И тут в голове у Фила щёлкнуло: «А что если эти странные логи в проекте появились не от новых пакетов, которые он установил, а от нового бота-аудитора, который эти пакеты проверял? Что если бот заинжектил что-то в код пакетов? Эта блестящая чёрная коробка вполне могла, чёрт знает что внутри неё творится!»

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

d e s i n e s p e r a r e q u i h i c i n t r a s n e t l i f y a p p

(продолжение следует)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

22 Nov, 15:15


#Пульс_веб_платформы 22.11.2024

Новости
- вышли результаты опроса State of HTML: новые API типа Popover и <dialog> появляются (это хорошо), но есть баги, например, на iOS не работает сокрытие при клике на backdrop (это плохо); некоторые новые API типа Anchor positioning и View transitions API ещё не везде поддерживаются; традиционная боль, которая мало утихает с годами, — стилизация и кастомизация элементов форм; в топе нехватающих элементов data table, tabs, switch/toggle, skeleton-ui, context-menu, carousel, inifinite scroll
- вышел Chrome 131: псевдоэлементы ::selection и ::highlight теперь более логично наследуют значения CSS-свойств; к <details> и <summary> теперь можно применять display: flex и grid; в @property теперь поддерживается тип <string>; в элемент <select> теперь валидно включать другие теги помимо <option><optgroup> и <hr>; currentcolor поддержан для relative color syntax; Summarization и Translator API для суммаризации и перевода с помощью AI, встроенного в браузер; в дев-тулзы также завезли AI, теперь и браузер будет советовать, как писать код лучше
- департамент юстиции США может заставить Google продать Chrome предположительно родительской компании Alphabet, чтобы более явно отслеживать, как через Chrome Google манипулирует рекламным рынком, и уменьшить возможности собора данных для AI через Chrome
- есть в языке и стандартной платформе такие узкоспециализированные фичи, которые нужны достаточно редко, поэтому забываются и вовремя не вспоминаются; например, Symbol может пригодиться, чтобы спрятать поле или метку в объекте без боязни, что оно где-то вылезет, так символьные поля объекта недоступны в Object.keys() и JSON.stringify()

Проекты
- react-scan — либа для проверки перфоманса в React-приложениях: хороший способ отследить наличие ненужных рендеров, а также обнаружить зависимость между несвязанными друг с другом компонентов

Статьи и демки

JS
- раньше уже писал про команду deno compile, а тут как раз вышел обзор с интересной мыслью: можно собирать ваше приложение с вереницей npm-пакетов в зависимостях в один файл и уже его транспортировать на CI вместо того, чтобы на самом CI скачивать и устанавливать все зависимости приложения — это сэкономит время и мощности CI
- в догонку к прошлому пункту: в вашем package.json файле devDependencies отличаются от dependencies тем, что не будут установлены на CI, ведь они нужны только локально при разработке; запускать production-вариант сборки можно ключом npm install --production, переменной NODE_ENV=production, а также ключом --omit=dev
- самое верное средство, чтобы завести проект нескольколетней давности, попереключать версии node и python и найти заветную рабочую комбинацию!
- как вариант не использовать билд-систему совсем: можно установить либу из npm во временную папку, оттуда скопировать сбилженные JS-файлы и подключить их руками на сайте: с обычным js-файлом проблем нет совсем, с ESM-файлом нужно озаботиться import map-ами, если внутри модуль включает зависимости, а вот с CJS-файлами придётся использовать esm.sh для преобразования их в в ESM
- если вы паблишили npm-пакеты, то наверняка знаете про команды npm version major/minor/patch, и для пререлизов (альфа/бета) тоже есть подобные команды: npm version premajor --preid=alpha сменит 23.1.6 на 24.0.0-alpha.0, а npm version prerelease бампнет альфа-версию
- мы используем инструменты, потому что они делают свою работу, и привыкаем терпеть их несовершенство, так как или им нет альтернатив, или альтернативы чересчур нишевые и экзотические; но если посмотреть со стороны, то картина сразу становится очевидной — React и TS достаточно вербозны и не лишены недостатков

CSS
- в пошаговой анимации steps(5) указывается количество шагов, на сколько разделить анимацию, но также есть дополнительная настройка, указывающая как именно выставляются эти шаги:  0%, 20%, 40%, 60% и 80%, или же 20%, 40%, 60%, 80% и 100%, или же 0%, 25%, 50%, 75% и 100%; настройка steps(3, jump-none) разделит шаги на равные интервалы, что более логичное, но не дефолтное значение

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

15 Nov, 19:49


#Пульс_веб_платформы 15.11.2024

Новости
- свойства для «подрезки» текста от верхнего и нижнего отступа точно по высоте строки text-box-trim и text-box-edge, доступные сейчас в бете Safari 18.2 вероятно скоро доедут и до Chrome
- обновился черновик CSS Values and Units Module Level 5, внесли синтаксис if(), чтобы можно было писать в CSS инлайновые условия в духе: display: if(style(--feature-flag: true): block; else: none)
- вышел новый npm-совместимый менеджер пакетов от создателя npm и других достойных мужей — vlt, позволяющий, к примеру, отображать зависимости проекта в виде диаграммы или вообще в gui; также вниманию предлагается npm-совместимый реестр vsr, который можно самостоятельно развернуть у себя бесплатно
- либа Framer Motion стала независимой и переименована её автором Matt Perry в просто в Motion
- способы, как уменьшить количество зависимостей проекта, на примере Storybook 8.4: с помощью активистов проекта e18e удалось снизить размер проекта на 50+%, а размер лок-файла на 75+% (удалены fs-extra, handlebars, file-system-cache; заменены lodash ⇒ es-toolkit, express ⇒ polka, chalk ⇒ picocolors, qs ⇒ picoquery; использован production-mode react)
- у CSS появился «официальный» логотип, а заодно продумывают категоризацию на уровни CSS4 и CSS5
- в Node v18.20.5 LTS import attributes и JSON module помечены как stable и в догонку статья с объяснениями зачем эта фича нужна — чтобы гарантировать, что если в JSON файле придёт исполняемый JS-код, то он не будет выполнен

Проекты
- pinia-colada — data-fetching слой для совместной работы со стейт-менеджером Pinia (Vue.js), похоже на Tanstack query, но напрямую подключается к Pinia
- nano-staged — легковесная альтернатива lint-staged для запуска команд при добавлении в стейдж, коммите файлов в git
- lexical — оказывается у facebook есть свой опенсорсный фреймворк текcтовых редакторов

Статьи и демки

JS
- метод dangerouslySetInnerHTML своим названием как бы напоминает, что если источник HTML вне контроля, то стоит обязательно предварительно санитайзить контент, ведь внутри может оказать вредоносный скрипт (и не только в теге <script>, но и просто в src или обработчике onclick, onerror…); помимо спецлиб для санитайзинга типа sanitize-html, можно воспользоваться браузерной технологией CSP, которая ограничивает возможность запуска инлайновых скриптов
- рецепт для работы с формами в React: на action (сервер) или submit (клиент) вешается колбек, возвращающий FormData, которая парсится zod или zod-form-data, и при успехе возвращаются деструктурированые значения
- свойства screenX и screenY при использовании внешних мониторов могут рассчитываться по-разному в разных браузерах, иногда принимая отрицательные значения
- напоминание, когда выйдете на работу: проверить tsconfig.json в вашем проекте на наличие в них ключей incremental и noErrorTruncation

CSS
- среди новинок CSS много тех, которые пока что работают только в Chrome, но также много и кроссбраузерных фич, которые не на слуху, но их можно смело использовать: inset и логические значения свойств block-size, inline-start, inset-block и другие, группирующие селекторы :is, :where, функции сравнения min, max, clamp, единица измерения динамической высоты вьюпорта dvh, media queries range syntax (width <= 1140px)
- при работе с container queries для container-type можно задать inline-size и size; значение inline-size указывает браузеру, что инлайновый размер (то есть ширина, width) контейнера больше не связан с его содержимым, то есть в директиве @container можно указывать min-width/max-width не боясь «зацикленности»; значение container-type: size наоборот разрывает связь высоты контейнера с его содержимым, то есть можно безопасно «квейрить» свойства «высоты» @container (min-height/max-height)
- overflow: clip отличается от overflow: hidden тем, что не создаёт скроллов и может обрезать только по одной стороне вместо сразу двух; кроме того, есть свойство overflow-clip-margin, которое может задать дополнительное пространство внутри обрезаемой области (жаль, что не поддерживается в Safari)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

08 Nov, 16:46


#Пульс_веб_платформы 08.11.2024

Новости
- Nicholas C. Zakas прорабатывает поддержку в ESLint плагинов для других (неES) языков: началась работа над плагином для линтинга CSS (направление Stylelint → ESLint)
- часть OSS-разработчиков Flutter создали форк Flock из-за недовольства, что баги в оригинальной команде долго фиксятся, планируют активно работать с сообществом и не отходить от оригинального Flutter (пока что)
- в Mozilla Foundation (НКО) сократили 30% персонала (отделы advocacy и global)

Проекты
- codingfont — шрифтовый батл, чтобы остался только один: удобный, моноширинный, твой (мой победитель Source Code Pro)
- prerender — Node-сервер, который в безголовом Chrome отрендерит SPA и отдаст готовый HTML (например, для поисковиков)

Статьи и демки

JS
- если отбросить хэллоуинскую тематику, то в одном месте сравниваются подходы к организации UI-китов: headless —компоненты и минимальные стили, разработчик сам организует CSS для них (Radix Primitives); boneless — атомарные классы, из которых разработчик уже составляет компоненты (Bootstrap, Tailwind); skinless — компоненты совсем без стилей (React Aria); lifeless — набор «голых» абстрактных хуков, в которые нужно передать «физическое воплощение», чтобы система «ожила» (TanStack, React Aria Hooks)
- идея: не использовать try/catch напрямую, а оборачивать код в функцию, возвращающую промис, а уже внутри этой функции прописать catch у промиса
- пока в Vercel проводят конференции и выпускают новые версии с поддержкой серверного React, в мире работает такой Tanner Linsley, пытающийся вернуть React на клиент, сделав сервер ещё одним способом работы с асинхронными данными, но при этом оставив прежнюю клиентскую природу React в TanStack Start
- оператор ??= нужен, чтобы проверить значение на null/undefined и присвоить дефолтное значение: вместо user.name = user.name ?? 'Anonymous' будет user.name ??= 'Anonymous'


CSS
- свойство text-wrap: balance ожидаемо из названия подравнивает длинные многострочные заголовки и короткие тексты, но уже неожиданно может быть использовано для подравнивания любых inline-элементов, переносящихся на несколько строк, например, <li> с display: inline-block и иконками внутри
- этот год был богат на урожай CSS-фич: в этом списке среди прочего есть упоминание о псевдоклассах :user-valid и :user-invalid, которыми с связке с :has() можно связать стилизацию <label> с последующим пользовательским неверным заполнением <input>: input { label:has(+ &:user-invalid) { text-decoration: underline wavy red }}
- значение width: stretch, оно же -moz-available и -webkit-fill-available несмотря на до сих пор требуемые префиксы, доступная во всех браузерах альтернатива высчитыванию width: calc(100% - 48px), если нужно «компенсировать» отступы у 100% ширины
- есть такие моменты во фронтендерских буднях, на которые можно забить, а можно мимикрокодилом улучшить интерфейс по-мелочи: много времени не займёт, конечному пользователю будет приятнее; например, outline — его обычно выключают, чтобы убрать «проблему», но можно его оставить и сделать симпатичным: показывать по :focus-visible, выставить цвет currentcolor, сделать элемент «блочным», немного скруглить углы, задать outline-offset и возможно немного его анимировать

HTML
- ещё одна статья к подтверждению предыдущей мысли: расставить HTML-атрибуты или обернуть чекбоксы в лейблы, а кнопки в формы несложно, но пользовательский опыт улучшится и на мобильных, и на десктопных платформах
- недавно ставший с выходом FF повсеместно доступный атрибут fetchpriority помогает браузеру понять, какие ресурсы грузить первым приоритетом (LCP-картинку), а какие можно отложить (второстепенные скрипты и стили); интересный приём — прелоадим стили с низким приоритетом без блокирования рендера <link rel="preload" as="style" href="theme.css" fetchpriority="low" onload="this.rel='stylesheet'">

Платформа
- вы наверняка знаете webstatus.dev, где есть инфа в скольких процентах браузеров поддерживаются те или иные фичи; так вот к этим данным есть API api.webstatus.dev (описание схемы openapi) на поиграться

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

01 Nov, 16:20


#Пульс_веб_платформы 01.11.2024

Новости
- c выходом Node 22.11.0 все дальнейшие 22.x-релизы будут считаться LTS
- состоялся первый митинг рабочей группы JSR: JSR не всегда может опубликовать существующий проект на .js + .d.ts; хостинг проекта стоит ~$400 в месяц; хотят сделать тул для генерации JSR-конфига из package.json
- вышел Firefox 132: улучшена поддержка аппаратного ускорения для SVG-фильтров; HTTP-фавиконки будут блокироваться, если их невозможно получить через https; поддержан атрибут fetchpriority

Проекты
- nvm-desktop — собранный на Tauri кроссcистемный десктопный клиент Node Version Manager
- node-html-to-image — Node-надстройка над puppeteer, чтобы отрендерить страницу и снять скриншот (опционально поддерживается Handlerbars для разметки)
- html- — попытка воссоздать стандартные HTML-элементы с помощью веб-компонентов (которая обречена на провал, но смотреть интересно); вот, например, кнопка

Статьи и демки

JS
- нативная поддержка TS в Node уже сама по себе хороша, но также позволяет импортировать TS-файлы просто так const module = await import('./module.ts'); включить можно экспериментальным флагом при запуске Node, в том числе в сразу внутри .bashrc: export NODE_OPTIONS="--experimental-transform-types --disable-warning=ExperimentalWarning"
- ручной вызов метода submit() у формы совершит отправку не учитывая валидации и не запуская события submit; а чтобы перед отправкой формы триггерить событие и проводить валидации, есть давно доступный в браузерах метод requestSubmit()
- «нативное» управление светлой-тёмной темой через <meta name="color-scheme" content="light dark"> прикольно тем, что можно буквально найти meta-элемент через document.querySelector и менять его значение
- «нативная» валидация форм (атрибут метод setCustomValidity у инпутов) позволяет на коленке сделать проверку введённого значения в инпуты и отобразить это в виде системного уведомления (пример для React)
- File — это расширение Blob, с добавленными методами name, size, type, lastModified, webkitRelativePath

CSS
- селектор .container:has(.element:last-child:nth-child(-n + 3)) применится, если в контейнере содержится 3 или меньше количество элементов, удобно для перестроения грида
- гайд по Scroll-Driven Animations (Хромиум-браузеры-only): киллер-фича — разгружается основной поток браузерного движка и поэтому анимации получаются гарантировано более плавными (бонусом пример связки анимации кастомного свойства посредством скролл-анимации)
- с частым появлением новых фич в CSS можно регулярно обновлять CSS Reset; в предлагаемом варианте используются @layer, чтобы подключать стили не обязательно в самом начале , и нативная вложенность селекторов :not([class]) { h1& {…}}

Платформа
- сборник рекомендаций по улучшению Core Web Vitals, из интересного: в девтулзах Chrome есть вкладка Coverage, чтобы увидеть неиспользующийся код; картинки лучше всего подключать в <img src|srcset>, так они начинают грузиться раньше, а не ждут загрузки стилей/скриптов; не стоит пользовать событие unload и заголовок Cache-Control: no-store, так как они мешают браузеру доставать страницу из кеша при переходе «назад»
- обычно поиском по истории коммитов пользуешься, чтобы посмотреть, кто что изменил в конкретном файле или строке файла; а вот git log с ключом -S — «поисковик» по диффам коммитов определённой строки, не привязываясь к конкретному файлу
- недавно писал дев-фик, где предполагал появление web-components-фреймворка от Google и «глобального UI-kit-а», помните? Как вы возможно догадались, «прототипы» не были взяты из воздуха. Фреймворк самом деле существует — это Lit (остаётся довезти туда нативные сигналы, упростить SSR, добавить тесную интеграцию с дев-тулзами и включить помощнее маркетинговую машину), а прототип «глобального» UI-kit-а — это Shoelace (недавно переродившийся в Web Awesome), основанный на Lit (остаётся перестать быть местечковым проектом одного человека). Так вот, я к чему веду: посмотрите на код веб-компонента статусной плашки, написанный на Lit, у меня этот код вызывает приятные ощущения, а у вас?

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

25 Oct, 20:22


#Пульс_веб_платформы 25.10.2024

Новости
- вышел Svelte 5, главные изменения: реактивные элементы теперь описываются явно; убран синтаксис slot, let: и <svelte:fragment> в пользу {#snippet …}; нативно поддержан TS; появился новый CLI; SvelteKit с новой версией работает
- вышел Next.js 15: headerscookiesparams и searchParams стали асинхронными; кеширование GET Route Handlers и Client Router Cache выключено по умолчанию; поддержан React 19 и ESLint 9; добавлен новый компонент <Form>
- выпущена React Compiler Beta: чтобы компайлер работал корректнее, код должен соответствовать требованиям специального плагина eslint-plugin-react-compiler, также сохранена обратная совместимость с React 17 и 18
- Netlify вслед за Cloudflare присоединяется к проекту OpenNext, но они и так раньше полноценно хостили Next.js проекты, так что это всё маркетинг
- в shadcn зарелизили «семейство» компонентов сайдбара, много всяких их вариаций, есть «ручки» CSS-переменных для стилизации, но одним большим НО всё ещё остаётся Tailwind в ядре этого кита; богоугодный React Spectrum пока что на эту тему имеет только beta-версию компонента Tree View
- IDE WebStorm стал Free for non-commercial use, делаю вывод: редактор Fleet не полетел, в JetBrains решили потратить прибыль от лицензий WebStorm на маркетинг, в момент когда есть повсеместно некая усталость от VSCode
- появились результаты опроса State of CSS 2024, интересные факты: 25% опрошенных создают свои дизайны сразу в CSS; большинство CSS-фич уже вышло, но при этом всё ещё болит кроссбраузерность; самые любимые фичи :has() и subgrid

Проекты
- hexp3 — быстрый конвертер цвета hex в похожий цвет в пространстве P3
- pragmatic-drag-and-drop — dnd-либы приходят и уходят, вот и новый подход Atlassian после депрекейта react-beautiful-dnd

Статьи и демки

JS
- обратная сторона того, что веб-тулинг написан на ненативном языке (Rust вместо JS) – его становится сложно продебажить, а также в случае браузерного рантайма уходят бесплатные браузерные плюшки — JIT и кэширование байт-кода (это когда во второй раз скрипт берётся в прекомпилированном виде из кэша, а в n-ннадцатый раз ещё и дополнительно оптимизируется); кстати, ещё есть рецепт, как включить compile cache в Node: export NODE_COMPILE_CACHE=~/.cache/nodejs-compile-cache
- недавний релиз в Node.js возможности require-ить esm-модули создало проблему: это работает только если в импортируемых esm-модулях и их внутренних зависимостях не используется top-level await
- WeakRef в JS даёт возможность создать ссылку на другой объект, которая уберётся из памяти Garbage Collector-ом, а с FinalizationRegistry можно создать колбек на сам момент очистки памяти

CSS
- функция min() понятна сходу (в отличие от container queries) и её можно применять как «односторонний стопор» при задании динамических значений для width, margin, font-size
-  Text fragments — возможность ссылаться на определённый текст на странице хороша ещё и тем, что в Chromium-браузерах есть фича «Copy link to highlight» в контекстом меню на выделенном тексте, которая сгенерит эту ссылку
- чтобы фон вложенного элемента не вылезал за скругленные углы родителя, можно принудительно унаследовать border-radius: inherit вместо добавления overflow: hidden

Платформа
- в чём веб-компоненты плохи (там есть и хорошая часть, но плохая всегда интереснее): Shadow DOM катастрофически переусложнён; SSR сложно и делается только из-под фреймворков; роутер на веб-компонентах лучше не делать; есть проблемы с доступностью; и главная проблема — нет широкой поддержки в популярных фреймворках

Разработка
- по аналогии с conventional commits есть conventional comments, для того, чтобы сделать комментарии в процессе ревью кода более осмысленными и сразу было видно, какие комментарии можно не учитывать
- хорошая абстракция в коде абсорбирует сложность, влезать внутрь приходится редко; плохая абстракция маскирует сложность дополнительными слоями смыслов и в неё надо часто залезать

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

22 Oct, 08:31


#Фикшн_веб_платформы

Придумал новый жанр. Вот есть science-fiction, а в мире разработки пусть будет dev-fiction. Индустрии веб-разработки явно не хватает своих философов и фантастов. Если бы были, то может быть и не появилось в своё время никакого «фронтенда». Начну это исправлять.

2027 год. После релиза 20 версии React и выхода нескольких мажорных версий Next.js команду разработки React вместе с проектом окончательно поглощает Vercel. Meta открещивается от React и веба и уходит целиком в индустрию ИИ. Бизнес-модель Vercel медленно загоняет развитие платформы в тупик: всё больше продуктовых компаний отказываются от хостинга переусложнённых приложений в Vercel и выбирают миграцию на альтернативные опенсорсные хостинги. Vercel теряет прибыль и перестаёт вкладываться в развитие React.

2028 год. TC39 окончательно уходит от «ежегодного» версионирования языка ES. Теперь baseline-версия языка зафиксирована в версии ESBase и больше практически не изменяется. Все нововведения в язык привносятся в sugar-версию языка — ESNext, которая компилируется в ESBase. Для этого TC39 в коллаборации с разработчиками Babel выпускает ESNext-компилятор. В языке ESNext появляется типизация. «Нативные» типы ESNext оказываются лучше по перфомансу, чем TypeScript, поэтому TS проигрывает конкуренцию и медленно деградирует. Происходит раскол в команде разработки VSCode и часть разработчиков присоединяется к проекту Zed, чтобы разрабатывать новый быстрый редактор ESNext. VSCode по факту останавливается в развитии.

2030 год. Команда React несколько лет пребывает в упадке. Компании всё чаще ищут альтернативное решение для создания быстрых SPA с простым SSR, но его нет на рынке. Многочисленные попытки создать альтернативный JSX+SSR-фреймворк спотыкаются о то, что в них не работают существующие дизайн-системы и UI-киты, «залоченные» на React API. Angular и Vue так и не обретают большой популярности и остаются нишевыми проектами.

Внутри Google решают сделать ставку на создание нового фронтенд-фреймворка на основе веб-компонентов. Для этого собирается команда во главе с Addy Osmani, которая в короткие сроки в коллаборации с Open UI, Brad Frost и группой разработчиков Devon Govett, создаёт на основе React Aria универсальный, не привязанный к конкретному фреймворку набор веб-компонентов GlobalComponents.

2032 год. Команда берётся за создание самого фреймворка, FinalFramework, который тесно сынтегрирован с набором компонентов GlobalComponents.
Киллер-преимущество нового фреймворка — он не требует дополнительной сборки, кроме компиляции ESNext в ESBase (если писать код сразу на ESBase, то его можно в принципе не билдить, а запускать как есть в браузере, подключив один JS-файл фреймворка в рантайме).

В дев-тулзах Chrome появляется нативная интеграция с GlobalComponents и FinalFramework. Кроме средств работы с DOM (надстройка над темплейт-литералами вместо JSX), фреймворк содержит встроенную систему атомарных реактивных сторов, основанную на событийной модели. Также из коробки идёт инкапсуляция стилей и JS, что больше не требует от команд заботиться о бандлировании и внедрять «микрофронтенды». Парадигма меняется: один веб-компонент — это и есть «микрофронт» со своим JS/CSS. Данными с окружающей средой он обменивается посредством событий, глобального контекста и нативных браузерных API.
Так как фреймворк построен на веб-компонентах, которые могут отдаваться с сервера как есть простыми строками, SSR-режим включается одним ключом в настройке компонента.

2035 год. «Примитивный» подход к веб-разработке становится модным. Webpack уже давно в стагнации, Evan You вместе с компанией void(0) несколько лет как переключился на коммерческую поддержку легаси-проектов в крупных корпорациях.

Из-за быстродействия и лёгкости ментальной модели, а также удачного маркетинга, FinalFramework бурно захватывает рынок. Благодаря нативной интеграции с основными браузерными движками, FinalFramework начинает использоваться не только в SPA, но также в создании мини-аппов внутри крупных приложений и как решение для десктоп-приложений на основе Electron. Веб вновь захватывает мир.

Виталий и Веб-платформа

18 Oct, 16:36


#Пульс_веб_платформы 18.10.2024

Новости
- вышел Chrome 130: окончательно пофикшен CSS Nesting; в Picture-in-Picture добавлена настройка preferInitialWindowPlacement для сброса предыдущей привязки pip-окна; поддержано свойство box-decoration-break: clone для создания красивых переносов текстовых блоков; плавный скролл scrollIntoView() с опцией behavior: "smooth" больше не отменяется в случае случайного «конкурентного» скролла; выкачен клавиатурный скролл по фокусу (например, на <textarea>); в девтулзах в инспекторе появилась пометка контейнеров со скроллом
- в TC39 созревает новый план, как сделать JS более устойчивым для конечных пользователей и при этом более удобным для разработчиков: разделить JS на условный core JS0 (это то, что уже есть сейчас) + JSSugar (это надстройка, которая компилируется в JS0), и при этом обе части стандартизировать; да, это типа CoffeeScript, предлагается распространить стандартизацию на «мутант»-версию языка, из которой особо удачные фичи смогут перекочёвывать в «стабильную» версию: а там уже и «ванильная» типизация появится, и всё остальное, что сейчас добавляется надстройками
- вышла Node 23.0.0: по умолчанию теперь работает require() ES-модулей, дропнута поддержка 32-bit Windows
- Webflow купили GSAP: ждём выхода фаундеров через полгода 🙂

Проекты
- brisa — попытка поженить веб-компоненты, JSX, серверный рендеринг, actions и реактивные сигналы — получается нечитаемая костыльная каша; сравните, например, с symbiote, насколько легковесно и свежо смотрится (уже ранее рассказывал про этот проект, он жив-здоров и развивается)
- jeasx — а вот ещё один заход в JSX + серверный рендеринг (под капотом fastify и esbuild), который уже похож на React здорового человека: можно использовать await просто так, class вместо className, «контекст» лежит в this
- hello-pangea/dnd — ещё одна попытка в dnd-сортировки для React (дед-mode-on: зачем в зависимостях redux?!)

Статьи и демки

JS
- обратная сторона удобства экосистемы npm — из неё так удобно и быстро можно поставить в проект зловредное ПО: иногда злоумышленники для своих пакетов «захватывают» имена, похожие на общеизвестные названия, либо могут замаскировать пакет под «легальный», но внутри будет rm -rf ~/*, который запустится по таймеру через час после установки
- реализация drag-to-select, из которой я узнал о существовании метода e.currentTarget.setPointerCapture(e.pointerId), который не полностью выключает pointer-events, а ловит только те события, которые исходят от текущего элемента
- если нужен перфоманс, то проще делегировать его самому браузеру, чем опираться на JS-надстройки типа React, которые по умолчанию будут медленнее; к такому же выводу пришли разработчики Edge, которые до этого затащили в браузер React, а потом решили от него отказаться
- в объекте события paste есть поле clipboardData, откуда можно вызвать метод getData('text/plain'), что получить скопированный текст или HTML, а также есть clipboardData.files, где лежат скопированные файлы
- вряд ли вам это пригодится, но setTimeout может выполняться максимально ~25 дней
- в значениях по умолчанию у аргументов функции можно использовать соседние аргументы или операции с ними function myFunc(arg1, arg2 = arg1)

CSS
- скроллящаяся таблица со стики хедером и боковым столбцом делается с помощью position: sticky, а чтобы ограничить область скролла контейнеру задаётся overflow-x: auto и высота вьюпорта; а заодно из решения почерпнул, что один элемент с position: sticky можно включить внутрь другого sticky-элемента
- чтобы протестировать стили для печати не обязательно каждый раз запускать печать в браузере, в девтулзах есть эмуляция print media type, которая также работает и в cypress
- небольшой и симпатичный гайд про цветовой формат OKlch: считаю, что именно фронтам удобнее всего затаскивать эту тему в проекты (поддержка позволяет — с 2023 работает во всех браузерах)
- конический градиент можно использовать для создания не только круглых форм, но и прямоугольных, например, repeating-conic-gradient(#000 0 25%, #fff 0 50%)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

11 Oct, 15:13


#Пульс_веб_платформы 11.10.2024

Новости
- вышел Firefox 131: поддержана фича Text fragments — возможность ссылаться на произвольный текстовый фрагмент: https://example.com/page[#:~:text=human] проскроллит страницу к первому встретившемуся слову «human», стилизовать его можно псевдоклассом ::target-text (поддерживается во всех браузерах); в девтулзах поповеры кастомных свойств показывают computed-значение и параметры @property
- сообщество e18e, которые взяли на себя роль «санитаров платформы», ходят в популярные пакеты, предлагают улучшения перфоманса, помогают выпилить ненужные зависимости; в сентябре удалось помочь выпилить смешную (да не очень) зависимость is-number из chokidar, также подчистили Storybook и jimp
- выпущен Deno 2.0: уже рассказывал о фичах раньше, в этом релизе обратил внимание на команду deno compile, собиращую приложение в запускаемый файл (с иконкой в Windows); и тут я понял, что на самом деле Deno конкурирует больше с Bun, чем с Node, на поприще все-инструменты-в-одном
- в Bun завезли экспериментальную поддержку сборки CSS на базе LightningCSS

Проекты
- one — React-фреймворк, собирающий приложение в веб и нейтив: под капотом Vite, также обещают локальную БД Zero (попробовать можно командой npx one — интересно, а козырные названия пакетов, как и домены покупают-продают?)
- scalar — REST-API-клиент в формате OpenAPI (для одного пользователя бесплатно)

Статьи и демки

JS
- local-first веб-приложение, в котором можно описывать путешествие текстом и смотреть маршрут на карте: используется CRDT-либа Yjs, которая хранит данные локально на устройстве, и Y-Sweet — клиент и сервер для синхронизации состояния по вебсокет-соединению, чтобы пользоваться приложением одновременно с нескольких устройств
- держать секреты типы паролей в env-файлах довольно удобно, но ненадёжно: env-утекают на фронте/SSR, через логи или просто во время видео-стрима, также env-ы видны в списке процессов в Unix-like-системах
- вообще-то это статья про то, как работает фича девтулзов Chrome «pause on uncaught exceptions», но меня заинтересовало другое: на сайте без драм и обсуждений используется куча веб-компонентов, например, <devsite-code> для отображения блоков кода, причём используются они в виде «виджетов»: кастомные элементы — это обёртки, докидывающие стилизацию и часть функциональности, и в браузерах, не поддерживающих кастомные элементы, контент всё равно покажется хоть и немного коряво
- нативный нестинг в CSS правилах появился без флага в Chrome 112, но с немного другим синтаксисом (нужно было проставлять дополнительный &) и эту необходимость окончательно уберут в Chrome 130; чтобы не сесть в лужу со старыми версиями нужно в нестинге обычные правила писать перед медиа-выражениями (что и логично)
- если нужно, чтобы ключами объекта было что-то, кроме строк или символов, выбираем Map

CSS
- пример реализации цветовой темы с нативной поддержкой темной/светлой схемы:

color: light-dark(
oklch(from var(--secondary) var(--600)),
oklch(from var(--secondary) var(--200))
)

- директива @supports не может проверять доступность других директив, и можно проверять наличие «родственного» обычного свойства: @container проверяется @supports (container-type: size); в статье есть рецепты для проверки многих директив, кроме @layer@property и @starting-style
- значение свойства grid-template-rows можно сделать динамическим, если использовать внутри кастомное свойство --int, объявленное через @property, и анимировать его

Платформа
- кажется мы стали забывать свои корни: роутер можно собрать на веб-компонентах (подход, популяризированный в React Router, когда вьюхи оборачиваются в «теги» роутов идеально ложатся на кастомные элементы); для связей можно использовать события CustomEvent; компоненты нативно реагируют на смену атрибутов («пропсы»)
- использование не по назначению двухбуквенных доменов названий стран имеет сайд-эффект: если страна перестаёт существовать, то что делать с неактуальным доменом? Эта ситуация коснулась домена .io «страна-владелец» которого перестаёт существовать

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

04 Oct, 16:17


#Пульс_веб_платформы 04.10.2024

Новости
- обновилась библиотека компонентов React Spectrum: компоненты для работы с цветом (пикер, колесо, инпут…) вышли из беты, а компоненты Tree и TreeView выведены в бету
- Evan You сотоварищи основали компанию void(0) и подняли денег, чтобы дальше пилить Rolldown и Oxc, а на их основе сделать коммерческий тулчейн для энтерпрайзов
- вышла версия Eleventy v3.0.0: теперь на ESM, поддерживает pnpm, yarn, Deno, разнообразные улучшения API (например, поддержка темплейтных языков вынесена из кора во внешние плагины)
- ESLint теперь поддерживает линтинг JSON- и Markdown-файлов (ждём официального переименования в E(xtremely)S(uper)Lint)
- вышла pnpm 9.12: команда pnpm outdated сортирует пакеты по алфавиту, добавлена возможность убрать пакет из зависимостей в overrides указанием "-"
- выпущена версия Tauri 2.0 (фреймворк для создания кроссплатформенных нативных приложений из фронтенд-кода): появилась поддержка мобилок iOS и Android (также поддержан Hot-Module Replacement (HMR) для мобилок), добавлена онбординг-установка для шелла и популярных менеджеров пакетов, обогащена система плагинов
- скоро выйдут React DevTools 6.0.0: поддержаны ServerComponents
- в яндексовском ui-kit GravityUI вышел wysiwyg-редактор, поддерживающий markdown (заодно выяснили, что кит остался тому Яндексу, который остался в РФ)

Проекты
- superdiff — либа для отображения diff-а между двумя массивами или объектами
- zod.fyi — «визуализатор» JSON ошибки ZodError
- mockoon — инструмент для разворачивания локального мок-сервера API

Статьи и демки

JS
- гайд по парадигме функционального программирования применительно к JS: раскрываются темы чистых функций, идемпотентности, замыканий, иммутабельности, а также как с этим жить в контексте JS; в контексте React, кстати, видел такой фокус: чтобы не вкладывать контексты друг в друга матрёшкой, они создаются друг за другом, а потом «функциональным методом» compose вкладываются друг в друга
- обычно про воркеры вспоминаешь, когда начинаются проблемы с производительностью, но об их существовании хорошо бы вспоминать почаще: в случае тяжёлых вычислений, процессинга картинок или видео, аналитики данных, фоновых задач, реалтайм-соединений

CSS
- если элемент с position: absolute не имеет предков, то он позиционируется относительно initial containing block — прямоугольника по размерам совпадающего с вьюпортом, но при этом сдвигающего при скролле
- в дев-тулзах Chrome во вкладке Performance сейчас есть возможность записать влияние CSS-селекторов на быстродействие, но нужно учитывать, что включённый анализ сам по себе увеличивает время отрисовки
- при объявлении кастомного свойства через @property немного быстрее будет задавать параметр inherits: false
- короткий сниппет для создания цветового колеса со всем цветовым спектром background: conic-gradient(in hsl longer hue,red 0 0);

HTML
- признаюсь, есть у меня некий фетиш на применение платформенных штучек, которые решают проблемы каким-либо простым способом с неожиданной стороны; вот всё жду, когда подвернётся шанс «легально» использовать этот трюк: HTML-элементы с прописанными id доступны по этому id напрямую в window: <form id="x"><input name="em"></form> x.em.onclick = …
- чем хороши <dialog> и popover помимо прочего (центровка, оверлей…), так это тем, что они гарантированно будут «выше» всех остальных элементов, так как рендерятся в специальный браузерный контейнер #top layer (больше никакая z-index-выскочка случайно не «всплывёт» над модалкой)

Платформа
- как бы платформа не развивалась, всё равно будут места, которые отстают в развитии больше других; такие вещи бесят и вынуждают, порой, добавлять костыли, и хуже всего, когда проблема кроется в браузере, и что ещё хуже — в мобильном: да, вы правильно поняли, я про iOS Safari, где встречаются баги, которые фиксились только спустя годы после их «релиза» или не фиксились совсем (наверняка вы сталкивались с проблемой скролла <body> с overflow: hidden)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

27 Sep, 15:13


#Пульс_веб_платформы 27.09.2024

Новости
- опубликован первый черновик CSS Values and Units Module Level 5 Working Draft, пожалуй, самое долгожданное нововведение — это возможность использовать функцию attr() не только в свойстве content, а с любым другим свойством: <span data-length="4"/> span { width: attr(length em, 0px)}, чтобы не инлайнить в style
- вышла версия Express.js 5.0: удалена часть методов; изменён паттерн-матчинг роутов: было /user*, стало /user(.*); при ошибке в асинхронных функциях теперь не нужно вручную вызывать next(err); минимальная версия Node.js 18
- выпущен Deno 2.0 Release Candidate: лучше поддержаны cjs-модули; ещё более тесно сынтегрировались с npm; добавили тестирование примеров в коментах JSDoc (тайпчек и выполнение); поддержали новый TS 5.6
- а вот в Node.js наоборот двигаются в сторону прекращения поддержки cjs-модулей, флаг --experimental-require-module перестаёт быть экспериментальным

Проекты
- qrcode — либа для генерации QR-кода в браузере (отрисовывается в canvas) или Node.js в рантайме
- react-diagrams — генерация диаграмм, много гибкости и настроек

Статьи и демки

JS
- что по дата-фетчингу в React в 2024: фетч в серверном компонента, проброс промиса в клиентский компонент и резолв данных с помощью use — в теории красиво, но пока всё ещё экспериментальная фича; React Query для SPA и клиентских компонентов; trpc для создания типобезопасной API-прослойки, но требует Node.js и TS на бэкенде
- в React в зависимости useEffect можно не включать сеттер useState, диспатчер useReducer и useActionState, ссылку useRef и useEffectEvent, так как они и так стабильны, то есть ссылаются каждый рендер на один и тот же объект; если говорить про сторонние хуки типа useAtom из Jotai или useMutation из tanstack-query, то про их «стабильность» достоверно неизвестно
- рецепт собирания велосипеда по отложенной загрузке изображений: выносим изображение в CSS-фон, по умолчанию убираем все фоны спец классом deffered, при попадании изображения во вьюпорт (хэндлим через IntersectionObserver) убираем класс deffered и задаём актуальный фон
- AbortController API позволяет прерывать fetch-запросы (также по таймауту), убирать все event-listener-ы разом, а также несколько контроллеров можно сгруппировать через AbortSignal.any (как Promise.race()); такой вполне себе дизайн-паттерн: передаём контроллер извне внутрь модуля и прерываем внутренние запросы или отменяем события
- интересная идея, как можно использовать Web Audio API для создания фингерпринта текущего устройства: с помощью OfflineAudioContext создаётся осциллятор, который «рендерит» уникальную для текущего устройства звуковую волну, затем она преобразуется в строку и из строки генерится хэш
- пример реализации шины событий на React/TS: иногда по тем или иным причинам, например, чтобы избежать проп-дриллинга или чтобы связать (не увеличивая coupling) совсем разнесённые части одной системы, выгодно создать собственный канал межмодульного общения посредством событий — эта реализация шины в React выглядит хорошо и минималистично

CSS
- свойство content-visibility — наколеночное средство виртуализации большого количества DOM-элементов (>40k), которое может ограничить размеры области для рендера, внутри которой происходит обычная отрисовка, а на всё вне этой области браузер не тратит драгоценные ресурсы
- появилось предложение добавлять :root { interpolate-size: allow-keywords; } в базовые стили проекта, чтобы была возможность анимировать от числа до ключевого слова (например, auto) — жаль пока работает только в последнем Chrome

HTML
- вообще-то это пост с несмешными IT-шутками, но напомнил мне о существовании <input type="hidden">, который раньше как-то часто использовался при клиент-серверном взаимодействии, а в последнее время стал как-то позабыт

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

20 Sep, 06:01


#Пульс_веб_платформы 20.09.2024

Новости
- в Font Awesome, к которому недавно присоединился Zach Leatherman с 11ty, начинает работать Lea Verou в качестве Product Lead, видимо будут продвигать Pro-иконки через движок статических сайтов + общую поддержку веб-стандартов и платформы
- выпущен Safari 18.0: в браузер добавлен блокировщик попапов (привет, дизайнеры, любящие модалки 👋); в связке с новой macOS появилась интеграция с iPhone, чтобы проще дебажить iOS на десктопе; поддержаны View Transitions и Style Queries @container style(--background: black), а также анимация свойства display; окончательно поддержан backdrop-filter и свитч-режим чекбокса <input type=checkbox switch>; в JS появился метод URL.parse(), возвращающий null вместо исключения в случае ошибки
- зарелижен Chrome 129: поддержано CSS-свойсво interpolate-size и функция calc-size(), позволяющие анимировать значение до auto (выглядят костыльненько); добавлена поддержка Intl.DurationFormat для форматирования длительности в нужной локали; появились обещанные ранее Snap Events для колбеков snap-скроллов и scheduler.yield() для разгрузки потока от длинных непрерывных тасок
- вышла Astro 5.0 Beta, в которой стабилизирована фича Content Layer с запросом контента из внешнего ресурса (топчик!), а также фича astro:env для типобезопасной работы с env-ами на клиенте и сервере (удобно)
- вышла date-fns 4.0: появилась широкая поддержка для работы с таймзонами, также автор морально готовится к грядущей эре господства Temporal API
- выпущена Fastify v5: поддерживает Node20+ (из-за лучшей поддержки node:test), загрузки, спонсоры и контрибьюторы растут

Проекты
- safe-await — либа, добавляющая возможность «распаковки» промисов const [error, data] = await safeAwait(promiseOne())
- modern-font-stacks — наборы похожих системных шрифтов на разных системах, если не нужен pixel-perfect (также есть отдельный набор шрифтов эмодзи)
- ts-blank-space — «а что так можно было?» из мира компиляторов TS->JS: все указания типов заменяются буквально символами пробела, сохраняя при этом структуру оригинального кода (поэтому не нужны сорсмапы)

Статьи и демки

JS
- чтобы побороть развесистые условия или вложенные тернарники (особенно может быть актуально в JSX), есть pattern-matching-подход (пропоузал)
- когда речь заходит про типобезопасность, не очень понятно сходу, где остановиться: на TS можно нагрузить задачу проверять корректность роутов, или, например, забахать типизацию стилей. Всё это как будто бы хорошо, то есть ради всего хорошего и против всего плохого, но при этом порождает сложности с перфомансом и создаёт переусложнённые абстракции
- в React Router есть специальное API для параллелизации запросов самого компонента и нужных данных для него <Route path="/users/:userId" loader={loader} lazy={() => import('../components/UserProfile')} />

CSS
- если ли что-то сильнее !important? Да, это вечный транзишн, который всегда показывает окончательные стили: input { transition: background-color calc(infinity * 1s) step-end; background-color: transparent; }
- разработчики Chrome на правах «законодателя мод» выкатили экспериментальную стилизацию <select> с помощью ::picker(select) {}, option::before, option:hover, option:checked {} (глядишь через пару лет наконец заборят финального босса CSS)
- если применить gap к контейнеру с <label> и <input> внутри, то в промежутке возможно появление «мёртвой зоны», в которой клик по лейлбу не выберет инпут
- интересное наблюдение, что анимация кастомных свойств выполняется на CPU даже если в итоге меняется значение transform, которое по идее должно вытаскиваться браузером в композитный слой и просчитываться GPU (лечится немного will-change, но не везде)
- простой селектор предыдущего элемента :has(+ &)

HTML
- чеклист по созданию идеальных форм: естественно, это тег <form>; инпуты с верными inputmode и autocomplete, которые часто забываются; базовая стилизация через accent-color; а также есть проверка navigator.onLine перед попыткой отправки

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

13 Sep, 16:04


Фронтвестник 13.09.2024

Новости
- ESLint v8.x перестанет поддерживаться мейнтейнерами 5.10.2024, вот и сказке конец, пора или болезненно переезжать, или выбирать альтернативу (кстати, Biome исполнился уже 1 годик и ещё он стал поддерживать .editorconfig), или оставаться на коммерческой поддержке legacy-версии специального партнёра HeroDevs; ещё из интересненького про ESLint — в версии v9.10.0 в пакет включены также типы @types/eslint, которые раньше шли отдельно
- веб-версия VSCode for the Web уже настолько хорошо работает, что даже в CodeSandbox окончательно задепрекейтили свой собственный редактор в пользу встроенного VSCode ftW (а помните, у Edge тоже когда-то был собственный рендеринг движок?)
- кстати, VSCode переходят на ESM с AMD (помните такие прото-модули?), может ещё быстрее заработает 😁
- к Font Awesome, недавно «поглотившей» библиотеку компонентов Shoelace, теперь присоедняется и 11ty (движок статических сайтов); норм они на иконках-то зарабатывают


Проекты
- satori — инструмент от vercel для конвертирования HTML-CSS в SVG (может быть для генерации OG-картинок для embed-ов)
- svg-use — если в JS-приложении инлайнить SVG в DOM как есть, то распухает как сам DOM, так и итоговый JS-бандл; заместо этого авторы либы предлагают использовать тег <use>, который ссылается на внешний ресурс с конкретным символом без инлайнинга с возможностью задать доп стили, например, для покраски
- react-call — API для создания асинхронных оконных диалогов (конфирмов) потипу window.confirm, но прикручиваемое к любому React-компоненту

Статьи и демки

JS
- извечная история фронтендеров, которые куда-то постоянно откуда-то мигрируют, в этом случае интересно изучить итоговый vite.config.js (подсмотрел плагин viteCompression, к примеру)
- Zod обычно воспринимается как валидатор приходящих с бэка данных, но ещё может использоваться для «типизации» по схеме пользовательского ввода в форму, в том числе через API FormData
- children в React никак не сделать «типобезопасными», выход — использовать пропы вместо children, там где нужна типобезопасность
- многие сайты и приложения в вебе до сих пор транспилируются в ES5, хотя чаще всего по недосмотру, так как одновременно в бандле оказываются и нетранспилированные ES6+ куски: рекомендуется не фиксировать версии в browserlist, сторонние либы нужно тоже прогонять через процесс билда
- что происходит когда вы нажимаете copy в Figma: в буфере обмена контент оказывается в виде HTML, в data-атрибут <span> внутри записывается base64-строка, в которую закодирован мини-файл в формате .fig; также есть много другой инфы про копирование в браузере, например, что в событии copy есть поле e.isTrusted, которое в true выставляется только для событий вызванных действиями пользователя, а не синтетических через dispatchEvent


CSS
- если нужно растянуть грид на определённую высоту, но при этом нет возможности задавать высоту видимым элементам грида, то в грид можно добавить пустой элемент, на который могут накладывать другие элементы, а он будет выступать только «распоркой» (повеяло табличной вёрсткой под старые IE)
- этот рассказ о :has() доносит главное предназначение этого селектора: он позволяет декларативно объединять элементы не только в родительско-дочернем направлении, но и в обратном дочерне-родительском, да и вообще в любом (что раньше достигалось только императивным скриптом); самый типичный кейс — убрать у html скроллбар в момент показа модалки html:has([data-disable-document-scroll="true"]) { overflow: hidden;}
- ещё немного юзкейсов :has(): стилизация рядов в таблице или элементов формы в зависимости от содержимого, изменение стилей фокуса по наличию внутри элемента определённого контента
- помимо примера «сверкающей кнопки», которая уже была в прошлом выпуске, в этом демо к кнопке применяется одновременно две одинаковых анимации, одна из которых работает по умолчанию (крутит угол градиента), а вторая (в два раза замедленная) поставлена на паузу, и по ховеру включается и оверрайдит первую анимацию, а при убирании ховера продолжается в ускоренном режиме

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

06 Sep, 08:46


Фронтвестник 06.09.2024

Новости
- в Safari Technology Preview 202 поддержано CSS-свойство scrollbar-width, добавлена возможность анимации для нечасто встречающихся свойств, доработан API PointerEvent, пофикшено применение clip-path к SVG-элементам
- вышел Chrome 128: добавлена поддержка Promise.try (тест функции возвращает ли она промис без её вызова), жаль пока Chromium-only, но полифиллится; CSS-свойство zoom теперь стандартизированное и кроссбраузерное (кстати, и в FF 126 тоже)
- вышел Firefox 130: поддержана технология WebDriver BiDi (Puppeteer теперь работает с Firefox «нативно»), а также множественные <details> с одинаковыми name (HTML-аккордеоны), больше ничего интересного
- в будущих версиях Chrome будет раскатана новая экспериментальная версия панели Performance в дев-тулзах: в ней по умолчанию будет показываться информация о Web Vitals (сейчас инфа доступна через отдельный браузерный плагин), а также станет можно записывать процесс с заданием тротлинга прямо из панели
- в React-команде начали разбираться с ситуацией блокировки отрисовки фоллбека при использовании <Suspence>: теперь сначала будет показываться фоллбек, а потом уже запускаться рендер
- формат изображений AVIF теперь индексируется в Google Search
- анонсирован Vue 3.5: давно не заглядывал внутрь, заглянул, а там внутри React 🙂: useId() для генерации уникальных наборов символов, useTemplateRef для создания динамических рефов, onWatcherCleanup для очистки «эффекта» (аналог возвращаемого колбека в useEffect), но есть и того, что в React нет — более тесная интеграция с веб-компонентами

Проекты
- style-observer — аналог API MutationObserver для CSS, позволяющий отследить изменение значения определённого свойства: под капотом для всех отслеживаемых свойств создаётся подписка на событие transitionstart и если значение свойства меняется, то триггерится микро-транзишн, по которому срабатывает колбек
- reasonable colors — простая, доступная, контрастная палитра в CSS/SCSS

Статьи и демки

JS
- e2e-тестирование хорошо тем, что тестирует реальный интерфейс пользователя, но тесты выполняются медленно, не покрывают всех состояний и сценариев и это чёрный ящик без доступа внутрь; в Storybook предлагают альтернативный подход — компонентное тестирование: берутся стори-компоненты, мокаются данные и проверяется соответствие всех состояний компонента «образцовым» в сторибуке (выглядит прикольно, но лочит на API @storybook)
- обычно при старте нового проекта файл tsconfig.json копируется из предыдущего, а если вам хочется наконец настроить его осознанно, пригодится шпаргалка по tsconfig.json от Matt Pocock: варианты опций с транспиляцией и без, билда для библиотеки (в том числе в монорепе), если проект живёт в DOM или нет

CSS
- начиная с Chrome 123, Firefox 125, Safari 17.4 свойство align-content работает для обычных flow-элементов с display: block
- с помощью неказистого на первый взгляд свойства background-clip можно, например, сделать так, чтобы одно фоновое изображение «выглядывало» из-под другого, а если это «нижнее» изображение — это анимированный конический градиент (с динамическим параметром угла), то выйдет спецэффект «сверкающей» кнопки
- не анимируйте свойство mask-position, вызывает репейнты
- синтаксис :nth-child(2 of .foo), выбирающий N-й элемент с определённым классом, уже с 2023 поддерживается во всех браузерах
- разбор display: contents и его юзкейсы: «стилевое устранение» нежелательной обёртки в сгененированной разметке .content p:has(img) {display: contents} или «реструктуризация» разметки при адаптивной перестройке


Платформа
- однажды один разработчик сделал сайт One Million Checkboxes, где любой желающий мог нажимать на чекбоксы, результат сохранялся в БД и был виден другим людям; люди начали рисовать на этом холсте 1000Х1000 «пикселей» картинки и даже «видео», а также кодировать из комбинаций выделенных (1) и пустых (0) чекбоксов побитово символы ASCII и составлять из этих символов URL на свой фанатский дискорд-сервер

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

30 Aug, 16:18


Фронтвестник 30.08.2024

Новости
- выпущен Deno 1.46: удивительный пример живучего проекта (6 лет!), который чтобы выжить всё больше адаптируется к Node и её экосистеме (playwright, pglite, mysql2…), но при этом переосмысляет отдельные вещи типа file watcher, лок-файла, менеджа зависимостей, делая их проще и удобнее, и в добавок ещё и привносит свою библиотеку «часто используемых велосипедов», чтобы не тянуть это отдельными зависимостями
- если ваш проект с webpack не новый и Vite завезти туда сходу не получится, то возможно это повод попробовать бандлер Rspack, тем более, что вышла его версия 1.0 (с версии 0.1 прошло 18 месяцев), то есть он теперь хорошо совместим с webpack v5 API, но при этом в 10 раз шустрее, а в добавок имеет отдельные тулы, например, билд-тула Rsbuild — аналог CRA или Vue CLI для создания «просто работающего» приложения без доп настроек и танцев с бубном или Rspress — генератор статических сайтов
- в Chrome 129 появятся события scrollSnapChange и scrollSnapChanging, чтобы добавлять обработчики snap-скролл-событий (нативное «прилипание» блоков при скролле/свайпе): будет легче делать карусели и обходиться без Intersection Observer или вычислений
- анонсирован TypeScript 5.6 RC: появится опция --noCheck, которая позволяет не запускать тайпчекинг, а совместно с опцией --isolatedDeclarations --noCheck позволяет быстро генерить .d.ts-файлы без тайпчекинга

Проекты
- freepublicapis — курируемый список свободно доступных публичных API с тестовыми данными (есть фильтрация по скорости и надёжности работы)
- dearconsole — набор копипейст-скриптов для браузерной консоли, есть интересные находки, например, document.fonts выдаст набор шрифтов сайта
- clipboard-inspector — анализ содержимого буфера обмена: туда копируется не только сам текст, но и окружающие HTML и CSS

Статьи и демки

JS
- грядущий, но уже доступный через полифилл стандарт Temporal.ZonedDateTime, расширяет дату в формате ISO явным указанием таймзоны и региональности календаря, что снимает боль при работе с датами в разных часовых поясах, а заодно приносит приятные плюшки типа hoursInDay — размера суток с учётом «летнего» времени или сравнения двух дат в разных часовых поясах, чтобы понять какая более ранняя
- в React Router есть встроенная функция generatePath для того, чтобы типобезопасно сгенерировать строку роута по схеме из данных, то есть перед непосредственно навигацией нужно выполнить построение роута navigate(generatePath(Routes.USER_DETAILS, { userId: "1" }))
- здесь просто пошаговая инструкция, как не сдаться в процессе публикации нового npm-пакета, интересные части: @arethetypeswrong/cli — либа для проверки корректности экспортов перед публикацией пакета; tsup — либа для компиляции TS-кода сразу в оба формата CJS и ESM; опция "noEmit": true для TS, чтобы использовать tsc только для тайпчекинга кода; либа @changesets/cli для публикации пакета, в том числе для локальной публикации с целью проверки

CSS
- наверняка вам когда-нибудь приходила в голову мысль, что с помощью box-shadow можно «сгенерировать» попиксельно целую картинку (теней при это потребуется много: один «пиксель» — одна тень); так вот эту идею можно развить дальше и сделать из теней «видео»: генерируем для каждого кадра «видео» кейфрейм анимации и затем проигрываем анимацию, например, по скроллу!
- среди всего навороченного CSS 70lvl (который мало где работает) из этого демо можно выцепить годные идеи, которые можно использовать уже сейчас, например, transition: --e .1s ease-out для кастомного свойства, объявленного с @property, или же использование кастомного свойства внутри CSS-счётчика counter-reset: num var(--val)
- примеры селекторов c :has(), выбирающие контейнер в зависимости от количества потомков, например, .container:has(> :last-child:nth-child(even)) выберет контейнер с чётным количеством элементов

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

23 Aug, 10:53


Фронтвестник 23.08.2024

Новости
- в Node.js решили не включать corepack по умолчанию, а также выделить его в отдельный проект и выпилить его из базовой поставки Node; с одной стороны вроде как шаг назад, с другой — corepack даёт возможность установки пакетных менеджеров не из npm, что создаёт риски безопасности, и на мой взгляд явно воспринимается как инородный инструмент внутри Node, так что отдельным проектом ему быть не повредит
- в альтернативный RSC-фреймворк Waku завезли Server Actions, и это безусловно хорошо в качестве альтернативы и конкуренции
- в Astro 4.14 появилась API для загрузки контентной структуры файлов извне проекта, есть теперь не обязательно держать движок контентного сайта и сам контент в одном проекте
- в Node v22.7.0 (current) появилась экспериментальная поддержка TS-синтаксиса (Enum и namespace)
- в Node v20.17.0 (lts) бэкпортирован require ESM-модулей, CommonJs-подход окончательно уходит
- вышел Cheerio 1.0 (7 лет разрабатывали до 1.0!) — либа для парсинга и манипуляций с HTML и XML, позволяет, к примеру, методом fromURL спарсить HTML с урла, может быть полезно для скрейпинга

Проекты
- stepperize — React-либа для создания пошаговых интерфейсов (например, визардов), типизированная, мало весит, без дефолтных стилей
- logtape — логгер для JS/TS с подсветкой типа лога, встроенными фильтрами и выводами в разные места назначения (консоль, поток, файл…)
- little-date — форматтер диапазонов дат на основе date-fns
- defensivecss — сборник «пуленепробиваемых» техник в вёрстке от Ahmad Shadeed

Статьи и демки

JS
- в двух словах для чего нужны TanstackQuery — чтобы обернуть асинхронный запрос в синхронный хук и обработать кеширование, и Zod — для объявления типа данных один раз в схеме и инфера типов из схемы, а также для валидации приходящих данных (тк TS не гарантирует типобезопасности входящих данных, Promise<FetchedData> усыпляет бдительность)
- если нужно сгенерить pdf из сайта, то для этого есть пара специализированных либ, либо Puppetier, в котором как и обычном браузере, можно программно сохранить страницу как pdf
- в последнее время развелось так много state-менеджеров, что их уже начинают использовать для продвижения других либ: вот, к примеру, Legend State — реактивный state-менеджер, стейт заворачивается в observable, а компонент в observer, у стейта есть методы get и set, а если понравилось, то можно купить оптимизированные для этого стейт-менеджера компоненты, хуки и хелперы за 200$ (на торрентах отсутствует)
- в истории развития регекспов есть интересные моменты, например, появление lookbehind-выражения ?<=... в es2018, matchAll в es2020 и flag v в es2024, но тем не менее регекспы нечитаемые (навечно) и поэтому есть пространство для появления либ, «очеловечивающих» регекспы, например, regex
- основной юзкейс генераторов в JS — пошаговое исполнение чего-либо, например, пошаговое исполнение цикла алгоритма с целью демонстрации его процесса

CSS
- если вы всё ещё используете sass, то в Vite и Webpack можно переключить компилятор с sass на sass-embedded для ускорения работы
- проверка поддержки @starting-style в CSS: создаётся числовое кастомное свойство и внутри @starting-style задаётся значение 1, дальше используется в качестве «реле» в транзишнах
- свойство contain позволяет изолировать элемент, то есть элемент как бы рендерится внутри страницы, но не влияет на общий рендер

HTML
- если вдруг вам нужно отрендерить огромные таблицы, используя colspan и rowspan, то вероятно можно уткнуться в максимальное значение для colspan — это 1000, а для rowspan — 65534; если так подумать, то наиболее распространены высокие и неширокие таблицы, что вероятно пошло от бумажного формата ленты и перекочевало в браузеры, это отражено в магических значениях

Платформа
- а что если подсветку синтаксиса кода в браузере можно сделать без JS и даже CSS? Просто встроить цветные глифы в сам моноширинный шрифт! Правда размер шрифта должен подрасти (из-за дублей одинаковых символов во всех цветах), но зато для работы достаточно загрузить и подключить один шрифт

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

16 Aug, 07:02


Фронтвестник 16.08.2024

Новости
- в Webkit (Safari) будет поддержано свойство scrollbar-width: в среде разработчиков принято считать, что монополизация индустрии веба Google с помощью Chrome приведёт к стагнации и неминуемой деградации, но есть непопулярное мнение, что централизация движухи в одной ведущей компании сразу же заставляет остальных игроков оперативнее подтягиваться за лидером; так вышло с поддержкой scrollbar-width: в FF это свойство поддерживалось сто лет в обед, но стоило его внедрить в Chrome, как зашевелились в Safari
- но у монополии есть и обратная сторона — к компании сразу же начинают пристальнее присматриваться регуляторы; вот и Google проигрывает дело, в котором компания обвиняется в приплачивании, чтобы сделать гуглопоиск вариантом по умолчанию; помимо штрафа речь может идти об отделении поискового бизнеса от Android и Chrome
- вышел Firefox 129: https-протокол теперь применяется к сайтам по умолчанию, добавлена поддержка @starting-style (но пока без анимации из display: none) и transition-behavior, добавлено превью по наведению на таб и подсветка неправильно использующихся CSS-свойств в дев-тулзах
- OpenAI выкатили Structured Outputs API: в предыдущих сериях в компании научили LLM выдавать данные в виде JSON, но проблема в том, что не было гарантии, что в 100% случаев будет соблюдена схема данных и формат; с новым API можно приложить JSON schema и данные будут валидироваться по ней, как если бы это делалось, например, с помощью Zod
- в Sentry придумали и запустили новый вид лицензии открытого кода — Fair Source Software, идея такая: вы опенсорсов продаёте? нет только показываю
- появилось предложение ECMAScript Safe Assignment Operator Proposal для более краткого написания возможного фейла промиса или throw ошибки: const [error, response] ?= await fetch("https://url")
- CSS Tricks подтвердили, что они ожили! Не просто так начали появляться статьи в последнее время, на ресурсе будут теперь публиковаться Geoff Graham, Juan Diego Rodriguez (ранее часто писал для SmashingMag-а) и Ryan Trimble; так глядишь и Крис вернётся
- история с нативной поддержкой TS в Node получила продолжение: теперь поддерживаются TS-only штуки (Enum and namespace)
- в Chrome начали завозить ai: в dev-версии браузера появился объект window.ai с методами canCreateTextSession, createTextSession, textModelInfo

Проекты
- pdom — ещё один заход в «параллелизацию потоков» DOM, трюк такой: создаём cross origin фрейм для «параллельного» компонента, рендерим туда нужный компонент, встраиваем в хост-приложение и общаемся с компонентом через postMessage
- floating-ui — Popper умер, да здравствует Floating UI! Либа-наследник Popper для показа всплывающихся тултипов с плюшками в виде анимаций, якорения, обработки скролла
- react-figma — рендерер React-компонентов в Figma (не наоборот!)

Статьи и демки

JS
- в веб-компонентах в <slot> можно прокидывать внутрь shadow DOM обычный DOM-элемент, а с помощью псевдоэлемента ::slotted(SELECTOR) можно изнутри shadow DOM стилизовать обычный DOM-элемент (при этом стили снаружи веб-компонента будут приоритетнее внутренних): с печалью считаю, что в рабочем коде это всё будет выглядеть как минимум экзотикой, а как максимум оверинжинирингом
- если вы используете zustand, но вам не хватает событийной модели, можно присмотреться к xstate/store, у которого похожий API, но ещё есть вдобавок и триггер событий типа store.send({ type: 'actionName', someEventParam: 123 }); бонусом идёт конверт сторов в полноценную state machine (конечный автомат) xstate
- а что если БД будет поставляться прямо в браузер в сжатом виде, с UI и со встроенным ai-помощником? Получите postgres.new!

CSS
- раньше, чтобы сделать текущий цвет более прозрачным, тёмным или светлым, использовались цветовые функции CSS-препроцессоров; ожидаемо, эту функциональность воссоздали со стороны платформы, только не в виде функций, а с помощью нового цветового формата — relative color syntax (с недавних пор доступного во всех браузерах)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

09 Aug, 08:39


Фронтвестник 09.08.2024

Новости
- вышел новый бэкенд-фреймворк для TS Encore, который вы вряд ли будете использовать, но интересна ключевая фича, которая даёт существенный прирост в скорости работы (быстрее express в 9 раз): узкое горлышко Nodejs — однопоточный eventloop, который быстрее не сделать, поэтому создатели Encore придумали сделать ещё один эвент-луп (Rust, многопоточный), этим эвентлупом обрабатывать входящие запросы, декодировать и делать прочие дорогие операции и затем уже передавать в эвентлуп Node; заодно не нужно долго воссоздавать API для совместимости Nodejs, как это делают в Bun, так как дело всё равно в итоге происходит в Node
- выпущен Tauri 2.0 RC, который вы тоже вряд ли используете, но у него тоже интересный подход: вместо того, чтобы в десктопное приложение встраивать Chromium, он заменён на более лёгкий web view на Rust
- в Puppeteer завезли Firefox: большинство основных API уже поддерживается, но дольше ещё будут довозить более специфичные API
- 6 августа исполнилось 33 года со дня выпуска первого сайта в интернете (это что, они 33 года подряд не забывают продлить домен?!)

Проекты
- formatify — аудио-видео-картиночный конвертер в любой формат
- css-springs — копипейст генератор «пружинных» CSS-изингов
- tschema — микроутилита для создания JSON-схем и вывода TS-типов из них (идеально создавать общий контракт для бэка/фронта и затем генерить типы, всместо того, что писать их руками)
- color — либа для процессинга современных форматов цветов (oklab, xyz, p3, rec2020…)

Статьи и демки

JS
- напоминание, почему default-экспортами лучше не злоупотреблять: сложно искать в проекте, не выводится название из модуля в IDE, излишняя свобода при выборе имён разработчиками; заодно есть рецепт, как переэкспортить неименованный модуль как именованный export { default as Row } from './Row.jsx'
- от XSS-атаки можно защититься с помощью CSP (Content Sucurity Policy) — директивы браузеру не запускать инлайновые срипты и стили, а разрешать запуск только с проверенного источника; самый простой способ её включить — метатег <meta http-equiv="Content-Security-Policy" content="script-src 'self' https://safe-external-site.com">
- в Svelte 5 представили новый концепт выделения небольших блоков «HTML-контента» в так называемый snippet; это что-то похожее на «шаблоны», которые можно заинжектить в компонент (children в мире React такой тоже своеобразный snippet); фича выглядит, если честно, странновато, скорее как замена задепрекейченным slot-ам (хотя по мне slot-ы — норм тема, немного непривычная, но прикольная)
- рефакторинг типичного навороченного React-компонента в идеале начинается с написания тестов (чтоб сигнализировать, если сломалось), удаления неиспользуемого кода, разделения на более мелкие компоненты и вынос в них состояния, упрощение условных конструкций, вынос утилитарных функций, дата-фетчинга и инлайновых стилей вне компонента, улучшение отмены запросов, отправки и валидации формы

CSS
- возможно, лучший способ использования стилизуемых SVG — это «спрайты», то есть библиотека <symbol>, подключаемая с <use>; но есть и ограничение — SVG должно лежать на том же домене, где оно используется
- признавайтесь, вы ведь тоже не используете container queries в повседневной работе? А если вдруг всё таки решитесь использовать — у них есть ограничения: для корректного применения стилей нужен «обёрточный» элемент только для применения «контейнерных» стилей, также контейнерные единицы измерения не всегда уместно применять к тексту (надо ограничивать слишком мелкий/крупный размер шрифта)

Платформа
- cURL — утилита для проверки, что какой-то URL что-то отдаёт, или нет? На самом деле это целая библиотека, которая может отправлять несколько параллельных и последовательных запросов, а также POST-запросы, поддерживает передачу кастомных заголовков (например, для прокси) и логина/пароля в конфигах .curlrc и .netrc, умеет парсить URL в JSON, и ещё поддерживает не только HTTP/HTTPS-протоколы, но и, например, почтовые IMAP и SMTP, то есть с помощью cURL можно отправить письмо из консоли

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

02 Aug, 09:36


Фронтвестник 02.08.2024

Новости
- в Node.js начали завозить «нативную поддержку» TS, пока на уровне вырезания аннотаций типов из кода, то есть enum-ы и другие штуки, которые просто вырезать не получится, пока что не работают (под капотом работает либа @swc/wasm-typescript)
- обновился Babel до версии 7.25.0: как-то Babel всегда воспринимался как инструмент для использование ультрасовременных фич в браузерах; в целом, этот апдейт так же об этом, но что интересно, добавлен плагин для фикса браузерного бага в Safari 16, и тут я задумался, а сколько там возможно интересного скрыто под капотом популярных инструментов типа Vite, которое незаметно что-то фиксит, и всё просто продолжает работать чуть лучше
- зарелизился Safari 17.6: поддержали ключевое слово safe во флексбоксах justify-content: safe center, завезли багфиксы события loadeddata для <audio> и <video> на загрузке страницы
- в Google отказались от идеи блокирования 3d-party cookies, но зато пообещали дать браузерные настройки, где можно будет явно настроить приватность (делать это конечно же никто не будет)

Проекты
- turndown — преобразователь HTML в md для браузера и Node.js
- vaul — нестилизованный компонент выдвигающейся «шторки» для React
- react-movable — ещё одна drag-n-drop либа для React, апишка с первого взгляда простая

Статьи и демки

JS
- в до-реактовые времена как-то повсеместно была распространена инфа, что innerHTML медленный, и что DOM лучше менять пачкой, а не на каждый чих использовать appendChild; потом как-то это всё подменилось знаниями о ререндерах в SPA, тем не менее DOM никуда не делся и все ранее работавшие приёмы, а так же новые, работают! Например, AbortController().abort() может отменить пачкой навешенные event listener-ы, а WeakMap и WeakRef можно использовать для создания ссылок на DOM-элементы, которые при их удалении, подчищаются и из памяти
- в интеграционных тестах на Playwright часто используется await page.goto(), которая по умолчанию открывает страницу и ждёт полной загрузки и отрисовки, что обычно избыточно для тестирования того, что, например, нажатие по кнопке вызывает появление модалки; поэтому лучше пользовать page.goto("/", {waitUntil: "commit"})
- тип unknown полезен для типизации неизвестного user-input-а, когда он может быть, а может не быть, поэтому при попытке обращения, к примеру, к методам строки, тип ругнётся и сообщит, что этого метода может и не быть
- в Vercel провели прикладное исследование, как сейчас JS влияет SEO в Google: SPA индексируются также, как и статические сайты; JS выполняется, в том числе на «сервере» Next.js, импорты CSS тоже работают; нагруженные JS сайты индексируются также быстро, как ненагруженные, но если рендер требует большего времени и при этом страниц много, то бот будет дольше их обходить
- barrel-файлы (только реэкспортирующие внутренности модуля) создают дополнительную вычислительную нагрузку на проект, и если таких файлов много в большом проекте, то с этим что-то нужно дополнительно делать (убирать такие файлы или преобразовывать пути импортов в обход таких файлов)
- затягивая в замыкание «большой» объект, следует помнить, что если к нему будет обращаться функция внутри замыкания, то это может привести к утечке памяти (если создаёте замыкание, стоит проверить, что в него попадёт)

CSS
- директива @property, недавно завезённая во все браузеры, позволяет делать типизированные наборы CSS-переменных (например, в рамках дизайн системы), и типы эти будут, если что, стрелять в рантайме в браузере (при желании наверное можно и stylelint-ом отлавливать неправильно заданные типы во время разработки); кроме того, есть интересные варианты, которые может быть были позаимствованы из TS: тип syntax: "blue | cyan | dodgerblue" для задания в переменную только этих цветов или же тип syntax: <image># для задания множественных значений через запятую (также есть тип '*' — аналог any, тип по умолчанию)
- если вдруг PopopevAPI (с недавнего времени доступный во всех современных браузерах) прошёл мимо вас, то вот свежий гайд в тему (годится для создания простых модалок)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

26 Jul, 09:44


Фронтвестник 26.07.2024

Новости
- в Google Docs завезли полноценную поддержку markdown (импорт/экспорт/копипейст)
- вышел Chrome 127: поддержано свойство font-size-adjust (костылим везде, теперь поддерживают все браузеры!), alt-текст в content, Document picture-in-picture теперь общается с основным окном, на контейнеры со скроллом теперь можно сфокусироваться с клавиатуры
- в React завозят server-only плюшки: отдельный пакет renderToMarkup предназначен для асинхронного рендера JSX в статику, которая не будет дальше никак обновляться (например, для генерации писем и другой статики); использование state, effect будет сыпать ошибки (впрочем, всё же сделали отдельный пакет для клиент-сайда, пометив сразу «для поддержки легаси-сред»)
- вышли результаты Stackoverflow Developer Survey 2024: веб всё ещё на коне, хотя зарплаты, как и почти везде (за исключением Erlang) уменьшились (при этом фронтендеры — почти самые низкооплачиваемые IT-специалисты), в БД лидирует PostgreSQL, jQuery популярнее Next.js, Markdown File — третий по популярности инструмент для асинхронной коммуникации
- опубликованы результаты опроса State of React 2023: RCS заходит туго, боли вызывает forwardRef, Redux и тот же RCS, популярны Tanstack Query, Zustand, Astro, Radix, shadcn/ui, Next.js; доминирует по прежнему SPA

Проекты
- swapy — создание в приложении виджетного лейаута с драг-н-свапом
- designgui — расширение Chrome для просмотра и управления CSS-переменными с цветами темы (как минимум, чтобы поудобнее искать и копировать цвета)
- svg.wtf — инструмент для изучения и экспериментирования с SVG

Статьи и демки

JS
- Svelte дозрел до того возраста, когда уже поднакопилось достаточно массы, чтобы нужен был двусторонний interop между двумя мажорными версиями (читать как «достаточно наворотили»), в то же время изменения к лучшему в понятности API в новой версии налицо (читать как «исправляют навороченное, но надо поддерживать старый синтаксис»); в целом, впечатления о нём странные: что-то похожее на vue c mobx, при этом с костыльками для работы с TS, типа <script lang="ts" generics="T extends { name: string }">
- когда читаешь про всякие WASM SQLite, Origin Private File System (OPFS) и их использование через SharedWorker и WebWorker, обычно это всё кажется какой-то далёкой от реальности фантастикой, только если ты не работаешь в Notion и тебе надо ускорить навигацию между страницами, сохраняя бд в файловой системе устройства и шаря её на все открытые табы
- отличия «объектов» в TS: Object — это любые объекты типа string, boolean, number, bigint, symbol (у них есть свойства cunstructor, toString…), {} — это пустой объект без полей, а object — не непримитивные типы, то есть {}, [] и () => {} (object также имеет аналог Record<string, any>)
- напоминание: DRY как самоцель может подтолкнуть к созданию ненужных абстракций, которые часто оказываются ещё и негибким, а гибкость — наверное одно из важных качеств абстракций
- хук useId можно использовать для генерации id DOM-элементов в рантайме

CSS
- в гайдах от Ahmad Shadeed обычно интересны практические юзкейсы использование фич; вот и в этом гайде по grid-area приводятся жизненные примеры использования: перестановка блоков местами в лейауте на разных разрешениях, «вылезающие» из прямоугольной сетки блоки, накладывающиеся области грида, has()-комбо .card:has(figcaption) { grid-template-areas: 'update layout'}
- схема, которая с появлением scroll-based-анимаций, стала ещё актуальнее: кастомное свойство — стейт, анимация — способ изменения стейта, счётчик — способ отображения стейта
- напоминание: контейнер с overflow: hidden всё равно можно проскроллить выделением текста или программно, а с overflow: clip возможность скролла будет гарантировано полностью выпилена

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

19 Jul, 09:02


Фронтвестник 19.07.2024

Новости
- GitLab ищет, кому продаться: конкурировать с GitHub с копайлотом и нейросетям не вариант, пора выводить вложения; факт — пуллреквесты победили мерджреквесты
- вышел Deno 1.45: среди прочего поддержаны npm workspaces (ну и конечно представлен свой кошерный аналог), так что работа с монорепами всячески улучшается с разных мест индустрии
- разработчики jQuery готовятся выпустить вторую бету, в которой переработали тесты: в нынешних реалиях нужны смоук-тесты для проверки, что проект собирается на webpack, rollup с виде cjs + esm, и чистом esm, а также импортируется в node
- Astro и Netlify теперь партнёры, будут получать ежемесячно денежку за то, что мягко приземляют проекты в облако; считаю, это хорошо, Astro — крутой проект
- в хромиум-браузерах заработал copy-paste SVG-элементов

Проекты
- tinybase — (в догонку к прошлому выпуску фронтвестника) local-first хранилище данных с возможностью синхронизации с сервером, минимального размера 5-15кб в зависимости от опций, хранит данные в виде пар ключ-значение или таблицы
- act — запускальщик GitHub Actions локально, чтобы не гонять CI почём зря

Статьи и демки

JS
- как на коленке собрать TanStack Query, а также Suspence c хуком use(): внутри кеши с Map и Set, промисы и использование их полей status, reason и value, а также контекст для распространения
- история о том, как от идеи хранения глобального состояния в React-контексте (чтобы задействовать Concurrent Mode) автор перешёл к идее отдельного стора, который по необходимости контекстом только распространяется, но не «живёт» в нём, и так родился современный Zustand, заботливо выращенное дитя, который, верю, ждёт хорошее будущее (уже скоро Zustand 5)
- для лучшей производительности интерфейса, рекомендуют разбивать большие таски, загружающие тред, на более мелкие, откладывая из выполнение с помощью setTimeout, requestAnimationFrame, а также нового API scheduler.yield; также можно откладывать выполнение служебных задач (аналитика и тд) до срабатывания события страницы visibilitychange
- ['1', '5', '11'].map(parseInt) вернёт [1, NaN, 3], тк вместе parseInt вместе с числом заодно получит вторым параметром индекс элемента, который будет использоваться в качестве системы счисления; вывод: так себе идея прокидывать в map напрямую «служебные» функции, внутри неявность, что плохо

CSS
- из всех способов спрятать что-то на странице самый удобный — атрибут hidden, если не хочется подключать CSS; visibiliy: hidden и display: none скрывают элементы также визуально и от скринридеров; и ещё парочка способов для сокрытия только от скринридеров и для видимости только им
- радиальный градиент внутри маски + карусель с картинками = эффект линзы, элегантный, чисто визуальный трюк с беспощадным кодом
- объявление кастомных свойств через директиву @property (которая недавно, наконец, стала поддерживаться во всех браузерах) мало того, что открывает возможность анимировать переменную, так ещё и даёт лучшую поддержку типизации в браузере (да, в CSS тоже есть типы) + ещё есть, например, немного фриковая возможность получить пиксельную ширину/высоту экрана --w: tan(atan2(var(--_w),1px))
- вендорные префиксы были плохим решением для внедрения экспериментальных фич, а вот с фича-флагами вышло уже хорошо: они доступны повсеместно во всех браузерах, чтобы попробовать экспериментальные фичи

HTML
- инициатива добавить в стандарт атрибуты commandfor и command, чтобы унифицировано связывать интерактивные элементы прямо в HTML: <button commandfor="custom-video" command="play"> запустит <video id="custom-video"> (полный список предложений включает dialog, input, audio/video, select, details…)

Платформа
- кулстори о том, что технологические барьеры — не инновация, а бесячья тупость; о том, что offline-first — лучший подход, так как он имитирует реальность; о том, что веб — открытая среда, в которую несложно внедриться для реверс-инжиниринга (особенно когда клиент-сервер пересылают в открытую токены для генерации TOTP-строки, которая является, к примеру, билетом на концерт)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

12 Jul, 09:33


Фронтвестник 12.07.2024

Новости
- вышел pnpm v9.5.0: появились catalogs-алиасы, чтобы один раз в конфиге объявить набор зависимостей, например, catalogs: react16: react: ^16.7.0 react-dom: ^16.7.0, а затем в package.json писать алиас вместо версии напрямую "dependencies": { "react": "catalog:react16", "react-dom": "catalog:react16" }; так можно лайтово организовать монорепу без оверхеда на одном пакетном менеджере
- SQLLite завезут в Nodejs для реализации localStorage/sessionStorage, а заодно откроют возможность его использования просто так; всё таки там, где есть борьба или хотя бы конкуренция, сразу идёт развитие (спасибо Bun и Deno)
- вышел Firefox 128: появился встроенный в браузер переводчик, включен relative color syntax, поддержан альтернативный текст для свойства content, заработала директива @property и registerProperty(), а также появился Resizeable ArrayBuffers
- вслед @property в FF вскоре появится и @starting-style, то есть он будет во всех браузерах
- после недавних больших обновлений eslint начинается перелопачивание архитектуры: появятся отдельные пакеты для линтинга не-JS-файлов (json, md), агностик-ядро и пакеты переедут в новую репу, будет написан новый CLI; в общем, за этим крайне интересно наблюдать, как именно в большом проекте справляются с архитектурными проблемами, миграцией, и справятся ли в итоге
- вышел vitest v2.0.0: браузерный режим работы, брейкинг-изменения, багфиксы

Проекты
- fast-json-stringify — более быстрый аналог JSON.stringify(), если скормить ему схему JSON, который нужно распарсить
- nolyfill — npx nolyfill уменьшит содержимое node_modules за счёт выпиливания ненужных более полифиллов
- es-toolkit — новый более быстрый и компактный аналог lodash (который в свою очередь был более быстрым аналогом underscore)
- react-jsx-parser — React-компонент парсер JSX (если нужно распарсить в JSX динамически формируемую строку HTML или JSX)

Статьи и демки

JS
- написание тестов — тонкая штука, вот и описания идеальных тестов звучат довольно расплывчато, но как ещё описать тонкие материи? Тест — это скорее ассистент, а не математическая формула. Тесты должны быть простыми и сфокусированными на одной вещи. Тестов без причины не должно существовать. Тесты не должны содержать деталей реализации.
- сайт — это то же приложение, но которое не надо отдельно устанавливать/обновлять, а его просто когда нужно открываешь, оно подтягивает данные и работаешь с ним; если развить идею, то сайт может в целом иметь свою БД в браузере (IndexedDB, WASM + SQLite), хранить состояние и, когда есть возможность, синхронизировать состояние с сервером и другими клиентами; так автоматом повысится UX (не нужно на каждый чих ходить на сервер), тем более что современные клиенты позволяют
- фича Isolated declarations в TS 5.5 меняет то, как можно публиковать проекты: раньше в пакет публиковались отдельно d.ts-файлы и скомпилированные js-файлы, так как их генерация была затратной по производительности операцией; теперь же можно публиковать исходный ts-файл, а артефакты d.ts будут генериться на лету во время установки пакета за счёт более производительного движка
- бывают случаи, когда некорректно созданная мемоизация создаёт утечку памяти за счёт удержания замыкания с большим объектом в нём; печаль в том, что то же самое может сделать автомемоизатор React Compiler, но дебажить это станет сложнее

CSS
- рецепт градиентной рамки: с вырезанием маской куска градиента, если нужна прозрачность, и с двойным градиентом (конический + линейный), если без прозрачности
- мощь свойства clip-path не только в возможности «вырезать» любую форму, но также и анимировать её (нужно в слайдерах, шторках, подложках)
- божественный селектор :has() всемогущ тем, что не требует структурной связи проверяемого селектора и стилизуемого элемента (проверяем одно, стилизуем другое)

HTML
- у <script> или <link> есть атрибут integrity, в который передаётся хэш, и если содержимое файла скрипта или стилей изменится, а хэш нет, то тогда браузер выкинет ошибку и не выполнит файл (сгенерить хэш можно тут)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

05 Jul, 15:36


Фронтвестник 05.07.2024

Новости
- математические CSS-функции round(), mod() и rem() — теперь доступны во всех браузерах: это про округление и остаток от деления одной единицы на другую; интересен юзкейс округления с определённым шагом — такой своеобразный аналог «тротлинга» в CSS, когда задаются, например, только целые или кратные 5 значения, а остальные отсеиваются
- вышел Playwright v1.45.0: на борту новый Clock API, который позволяет протестировать временные интервалы (устанавливаем время, пользователь закрыл ноут, перематываем время на 10 часов вперёд, возобновляем время, проверяем, что времязависимый код отработал корректно)
- вышел Rolldown v0.10.5: потихоньку кродёться новый бандлер на замену Rollup в Vite, в этом релизе поддержана сборка TypeScript и разных типов файлов

Проекты
- eslint-plugin-depend — плагин для eslint, указывающий на либы в раздутыми зависимостями и на использование ненужных полифиллов
- ladybird — разработка нового браузера не по карману большим бизнесам, но зато по силам энтузиастам, которые по приколу строят систему современного браузера (рендеринг-движок, JS-движок, WASM-имплементация, HTTP-клиент, эвент-луп и взаимодействие с ОС…)
- HTTP observatory — сканер HTTP-заголовков, которые отдаёт сервер вашего сайта, пишет чего нет, что есть, даёт рекомендации
- letsform — тут рекомендация не самого сервиса, а подхода генерации форм из JSON-схемы, чтоб перенять практики при необходимости сборки своего велосипеда

Статьи и демки

JS
- напоминание, что для базовой конвертации строки в DOM и DOM в строку есть 2 браузерных API: DOMParser и XMLSerializer (для ноды есть отдельные либы типа JSDOM)
- замечали, что при копипасте текста иногда он вставляется вместе со стилями? Дело в методе вставки: на событии paste метод e.clipboardData.getData('text/html') вставит текст вместе с прилагающимися стилями
- 534 и 1 способ перезагрузить страницу из JS: а на самом деле комбинации методов assign, replace и reload у location
- отменяемый fetch легко реализуется с новым Promise.withResolvers() (это правда не совсем отмена, а ранний reject), а также есть вариант с отменой с помощью AbortController
- тема с «неточным» округлением чисел крайне важная в финансовых приложениях, поэтому там можно использовать или микроприбавки Number.EPSILON к числам перед округлением, или спец либы типа currency.js, на которой в итоге и остановился автор, чтобы избежать проблем
- Deno, Bun — это конечно хорошо, но всё таки стоит их воспринимать как надстройками над Nodejs и не использовать проприетарные API, держать в уме, что должно быть можно сфолбечиться к базовому API Nodejs
- как в JS проверить наличие нужной браузерной фичи: CSS-фичи преимущественно с помощью CSS.supports(), HTML-фичи через наличие в DOM-е определённых интерфейсов

CSS
- если принять тот факт, что в tailwind излишне выкрутили идею утилитарных классов, сделав примитивы слишком низкоуровневыми, и попытаться переосмыслить идею, то получится такое разделение: оформительские (.card, .aside), лейаут (.center, .cluster), отступы (.gap-s, .gap-m); классы примитивы более высокоуровневые и из них приятно собирать композиции
- если сделать фон из конического градиента и сдвигать его транзишном, а также применить к нему mix-blend-mode: screen, то текст будет плавно проявляться «из маски»
- короч, это не учебная тревога: в канареечный Chrome завезли height: calc(auto), чтобы транзишном можно было плавно изменять высоту с height: 0 до актуальной без хаков

HTML
- статья, что не стоит использовать aria-hidden="true" на интерактивных элементах, также напоминает, что существует и поддерживается во всех браузерах атрибут inert, который «выключает» интерактивный элемент (на него нельзя нажать, дотабать или найти через средства доступности) — хороший юзкейс для ограничения пределов фокуса при показе модальных окон

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

28 Jun, 16:26


Фронтвестник 28.06.2024

Новости
- Figma провели конференцию Config 2024, показали: обновлённый UI с поддержкой светлой темы и плавающих панелек; Figma Slides — режим для создания и показа презентаций (плавные переходы между слайдами, заметки докладчика, интерактивные элементы); Code Connect — режим с генерацией компонентов (отношусь скептически); более удобный dev-mode, чтоб просматривать сразу все готовые макеты; допиленные автолейауты и адаптивные прототипы (подстраиваются под размер экрана)
- в Astro 4.11 поддержаны прекрасные Shiki transformers для компонента отображения <Code>

Проекты
- ky — обёртка над браузерным fetch: есть алиасы для отправки всех видов запросов, retry логика, хуки (до запроса, до ошибки, до ретрая, после ответа), отправка данных формы, отменяется по controller.abort()
- pdfslick — либа для просмотра и взаимодействия с pdf (интересно, что под капотом используется Zustand)

Статьи и демки

JS
- у WeakMap есть такая полезная особенность, что если объект более не существует, то значение, привязанное к нему, удаляется из памяти garbage collector-ом; это можно использовать, например, для организации кеша, который автоматически подчищается, когда закешированные объекты не существуют (простая версия того же на mdn)
- если хочется сделать тип, принимающий любую строку, но при этом чтобы в автокомплите выдавались «предустановленные» варианты, то в юнион в конце надо добавить string & {}

type Status = 'open' | 'closed' | string & {}

- если вдруг у вас возникнет желание использовать Web Crypto API для генерации рандомных чисел вместо Math.random(), то это будет гораздо медленее и для простых (не крипто) задач «типа немного лучше»
- сможете сходу сказать, чем Screen Orientation API отличается от Device Orientation API? Screen — это горизонтальная/вертикальная раскладка, Device — это про гироскоп и ориентацию в пространстве; также есть рецепт по блокировке экрана в Fullscreen API, и ещё немного про Vibration API и малодоступный Contact Picker API
- новые методы Set (intersection, union…) доступны во всех браузерах, их можно адоптить, тем более, что уже поддержаны в TS 5.5
- Intersection Observer API норм адоптится в React, правда нужно намазать парочкой useRef, чтоб лишний раз не пересоздавать обсервер
- юзкейсы Proxy: геттеры, подсчёт доступов, немутабельные объекты, кеширование, создание цепочки методов, валидация, вотчер изменений поля

CSS
- ещё один сборничек современных фишек CSS от Michelle Barker, из находок: inset можно задавать не только 0, но и inset: 50% 50% 0 0 (направление значений по часовой стрелке — верх, право, низ, лево); растяжка элементов на весь контейнер { display: grid; * > { grid area: 1 / 1; } }; также есть container-queries, :has (куда же без него), anchor positioning
- если у вас Chrome-only приложение (киоск, например), то там уже завезли anchor positioning, и его можно использовать для создания линий между элементами (аля стрелки в miro) — линии будут привязаны к заданному боку элемента и сохранять свою позицию при перемещении самого элемента
- если задать одиночный кейфрейм 50% { transform: scale(1.5) }, то он будет работать: на 0% будет изначальным, затем изменится до заданного, а затем снова вернётся к изначальному; тут можно посмотреть другие одиночные кейфреймы
- если нужно сверстать текст по кругу, можно использовать тригонометрические функции и transform, которые доступны во всех браузерах (похожее есть в SVG-элементе textPath, расставляющем текст по path)
- как на clip-path: polygon() создать форму и её инвертировать: прикольно, что на polygon() можно создать любую геометрическую форму

HTML
- текстовые инпуты несколько перегруженные в настройках, так что часть из них забывается: помимо type, pattern, inputmode можно ещё задать spellcheck (управляет проверкой правописания), autofocus (устанавливает автофокус), autocapitalize (автоматическая капитализация букв, слов, предложений), autocomplete (автодополнение имени, одноразовых кодов, паролей), autocorrect (нестандарт в Safari исправляет правописание)

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

21 Jun, 08:15


Фронтвестник 21.06.2024

Новости
- в спецификацию CSS-values-5 будет добавлен синтаксис инлайновых условий для кастомных свойств (логичное продолжение style-container-queries только для всего), можно будет писать так:

background-color: if(style(--variant: success), var(--color-success-60));
border-radius: if(style(--shape: pill) ? 999em : .2em)

- вышла Node 22.3.0: в тест-раннер добавлено снепшотное тестирование
- в React-сообществе бомбануло, что в 19 rc версии асинхронные сиблинги в <Suspence> стали рендериться последовательно, а раньше было параллельно (что использовалось, к примеру, в tanstack-query); команде React пришлось признать, что они недооценивали, сколько людей продолжают делать SPA, а не рендерить на сервере и отложить релиз 19 версии (что забавно, pr спокойно себе был в работе с марта 2023)
- опубликованы результаты опроса State of JS 2023 (преимущественно американцы и европейцы мужчины среднего возраста поделились, что думают): в JS из коробки не хватает статической типизации, боль вызывает ситуация с ESM/CJS-модулями, поддержка TS, работа с датами, браузерная поддержка (особенно Safari); Vite многие пользуют и почти все довольны (то же актуально для Vitest), что не скажешь о webpack — пользуют меньше и больше недовольных; у Next и Vue сравнимое количество использующих и недовольных; недовольных React становится больше; растёт популярность pnpm в том числе как инструмента организации монореп

Проекты
- React Internals Explorer — визуализация происходящего в дереве рендера React, в том числе проиллюстрирован пример с <Suspence>: в SPA в 18 версии React они будут рендериться параллельно, а в rc 19 — последовательно

Статьи и демки

JS
- как использовать встроенный тест-раннер Node, в том числе свежедобавленное снепшотное тестирование: describe, mock, it живут в node:test, как и snapshot; названия утилит классические, API вполне предсказуемый; snapshot сам по себе не рендерит компоненты, а работает в паре с каким-либо рендерером, например, @testing-library/react
- вроде и маркетинговая статья, но как-то честно составленная: Node — самая популярная технология, скачивания растут, баги правятся, плюшки появляются: ems, fetch, watch, AsyncLocalStorage, WebCrypto
- Page Visibility API — сто лет в обед, но как-то не на слуху, используется, например, чтобы на событии visibilitychange, когда страница не просматривается, отправить аналитику или понизить битрейт проигрываемого видео
- проблема, которую решает React Compiler с автомемоизацией состояния в компонентах, уже давно решена из коробки в MobX (видимо поэтому MobX помечен как несовместимый с RC)

CSS
- единица измерения 1cap — это высота заглавной буквы в шрифте, если нужно сделать что-то такой высоты (например, отступ между словами или размеры иконки), то можно пользовать (доступно во всех браузерах с декабря 2023)
- в браузерах в последнее время имплементировано много CSS-фишек, но не все доступны повсеместно: пока нельзя использовать View transitions, Style Queries, @starting-style, зато можно URL.parse(), Safe flexbox alignment, currentcolor в relative color syntax
- редкий юзкейс для em — для задания размера отступа text-underline-offset

HTML
- в Chrome предложили элемент <permission>, который встраивается в страницу и показывает, какие есть доступы к камере и микрофону, а также позволяет включить или выключить их; интересно, 1) как с появлением веб-компонентов и React расширилось понимание элементов страницы, 2) что элемент будет не веб-компонентом, а именно стандартным браузерным элементом, чтобы гарантировано сделать его визуально доступным с ограничениями по стилизации

Платформа
- помню, когда GitHub выкатили GraphQL-песочницу, было интересно её тыкать, казалось, вот она — настоящая гибкость, но в итоге оказалось всё не так радужно: не легко спрятать за авторизацию частичные поля и наоборот легко с клиента отправить схему, которая выгребет мегабайты JSON-а, а также есть другие проблемы; а подходит GQL в случае, если есть контроль над всеми клиентами, их <= 3 и сервер и клиенты написаны на разных языках

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

14 Jun, 11:26


Фронтвестник 14.06.2024

Новости
- анонсирован Safari 18 beta: добавлена поддержка View Transitions API (ждём FF), а также Style Queries @container style(); currentcolor теперь заработает в relative color syntax oklch(from currentcolor calc(L * 4) C H); заработала анимация для display; у backdrop-filter отпал вендорный префикс; заработал режим justify-content: safe center для флексбоксов (предотвращение обрезания при узком контейнере); поддержано свойство content-visibility; доработаны инпуты (свитч-чекбокс, дата, время); появился URL.parse(); задепрекейчен resize: auto, а также другие API, которые работали только в Safari
- вышел Firefox 127: появилась поддержка rel="dns-prefetch"; для img, video, audio браузер попытается заменить ссылки http на https; доработан внутренний тул скриншотов; включен navigator.clipboard.read()/write()
- вышел Chrome 126: view transitions заработал для cross-document (работает так же: незаметно загружается следующая страница, делается и показывается скриншот и затем подменяется на загруженную страницу) (ребята из Astro тут же выкатили обнову); включён CloseWatcher API, управляющий закрытием dialog и popover; в девтулзах в Network в запрос теперь можно копипастить заголовок запроса целиком, а также обновлён Lighthouse 12.0.0
- в Mozilla пошли на рынок инструментов для «безкодового» создания сайтов и выпустили soloist.ai: готовый сайт захостится на soloist.ai, под капотом будет next.js (хм, где-то это уже было 🤔)
- вышел Prettier 3.3: интересен тем, что ещё лучше форматит TS, JS, React, а также Flow-код, и все улучшения для Flow написали инженеры самого Flow
- анонсирован TypeScript 5.5 RC: новые методы Set (union, intersection…); проверка синтаксиса регекспов; импорт типов в js-файлах в JSDoc; Inferred Type Predicates \(решает проблему с типами .filter(x => x !== null))

Проекты
- JsonDiscovery — расширение для браузеров для интерактивного просмотра JSON (в том числе больших >512MB, на которых JSON.parse положит браузер)
- coolify — опенсорсный селф-хостед аналог netlify/versel
- telefunc — как-то уже писал про концепт «серверных» методов, которые напрямую «вызываются» на клиенте, вот эта либа реализует подход «функции вместо API»
- web-features-explorer — инструмент для проверки доступности веб-фич в браузерах (в том числе показывает разбивку по месяцам)

Статьи и демки

JS
- тема узких горлышек в оптимизации всегда актуальна (да, я смотрю на тебя, React) и тут есть, где разгуляться: в React 18 стоит использовать concurrent-режим рендера ReactDOM.createRoot вместо ReactDOM.render; большие таски можно разделять «перебивками» new Promise((resolve) => setTimeout(resolve, 0)) или await window.scheduler.yield(); хуки react-router useLocation, useRouteMatch, useHistory вызывают ререндеры, лучше пользовать history и location из window, если дело происходит на клиенте
- идея использование тайп-чекинга не только для «базовой» проверки типов, но и «для чего-то большего», всегда вызывала у меня отторжение из-за «комплексности» затеи, но если вам это не страшно, можно, к примеру, писать типы-«тесты» для проверки других TS-типов
- с Document Picture-in-Picture API можно в мини-окошке браузера рендерить произвольный контент, а не только видео, поэтому там можно показать, например, мини-плеер с помощью createPortal() (жаль, что пока только Chrome)
- оператор satisfies позволяет проверить соответствие типа объекта без лишнего «расширения» этого типа
- чтобы проект использовал конкретную версию пакетного менеджера, нужно включить corepack enable && corepack enable npm и прописать в package.json конкретную версию "packageManager": "[email protected]"

CSS
- решение интерфейсной проблемы ссылки, вложенной в ссылку: выносим «родительскую» ссылку в отдельный слой с position: absolute и растягиваем на всю ширину с inset: 0, а «дочерней ссылке» задаём position: relative
- CSS Tricks продолжает оживать с новым гайдом про Container Queries
- чтобы «прилепить» к краям контейнера картинки-маски, чтобы сам он тянулся по высоте, есть mask-image

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

12 Jun, 09:06


Откуда взялся Octocat

Операция git merge используется для слияния веток. Но слияние может происходить по-разному. Есть дефолтный алгоритм слияния, который используется, если выполнить команду git merge (также мердж неявно происходит при git pull). Для слияния двух веток в версиях git с v0.99.9k до v2.33.0 использовался алгоритм recursive (наверняка вы видели в консоли сообщение «Merge made by the 'recursive' strategy» — это вот оно).

В более новых версиях дефолтный алгоритм recursive был заменён на ort (Ostensibly Recursive’s Twin — «Как будто бы близнец Recursive», видимо разработчики посчитали что называть его recursive-v2 как-то не оч). У него тот же интерфейс и настройки (работает для слияния двух веток), но он работает побыстрее в больших репозиториях (особенно при мерджах, где было много переименований) и учитывает граничные случаи, которые в recursive решались неоптимально.

Но помимо двухветочных алгоритмов есть ещё и специальная стратегия для слияния более чем двух веток. Например, когда мы сливаем несолько веток разработки в одну для тестирования:


git checkout -b testing
git merge feature/one feature/two feature/three


В этом случае применится алгоритм слияния octopus. И буквально три ветки будет слито в одну (в целом, количество веток может быть любым, но лучше не превращать слияние «осьминога» в слияние «ктулху»).


*-. dbc6a8b (HEAD -> testing) Merge branches 'feature/one', 'feature/two' and 'feature/three' into testing
|\ \
| | * 0260176 (feature/three) add test-3.txt
| * | abc9e86 (feature/two) add test-2.txt
| |/
* / 77e0aa8 (feature/one) add test-1.txt
|/
* 82acd11 (master) init


Также стратегию можно передавать явно в параметре вот так: git merge -s recursive.

Так вот, давным-давно, когда начинался GitHub, его основатели захотели создать забавную страницу ошибки и купили на стоке ту самую картинку котоосьминога, которая называлась «Octopuss» у дизайнера Simon Oxley.

Позже Octopuss стал более «корпоративным» Octocat, GitHub нанял дизайнера-разработчика Cameron McEfee, чтобы сделать из одной картинки целую мерч-индустрию и, что называется, завертелось.

Забавный факт: на двумерных картинках у октокота всегда видны только 5 лап (по разным версиям одна из них — хвост). И когда появилась задача сделать трёхмерную фигурку, то встал вопрос сколько всё таки у него будет ног: 4 ноги и хвост или же 8 щупалец (3 из которых не видны на картинке). В итоге решили, что у фигурки будет 4 ноги и один хвост. Впрочем, потом появились анимации, где у октокота много щупалец.

@web_platform | Поддержать канал 🤝

Виталий и Веб-платформа

07 Jun, 07:00


Фронтвестник 07.06.2024

Новости
- в FF будет добавлена генерация alt-ов с помощью нейросети прямо на устройстве: фича хорошо ложится в тренд, что AI будет появляться в браузерах и помогать пользователям с взаимодействием с сайтами и приложениями
- вышла react-testing-library v16.0.0: @testing-library/dom и @types/react-dom вынесены в отдельные зависимости, чтобы устранить возможные конфликты
- история с эпичным обновлением eslint продолжается: анонсирован ESLint Configuration Migrator — тула для автоматического перевода помощи в переводе .eslintrc.*-файлов в flat-формат eslint.config.js, чтобы не делать это руками (пока умеет немного и работает с простыми конфигами)
- анонсирован intent to ship директивы @property в FF (чтобы объявлять кастомное свойство с нужным типом): пригодится, например, для кроссбраузерного создания CSS-таймеров
- вышел Rspack v0.7: добавили lazy compilation (собирается не сразу весь проект, а только входные точки; остальное собирается на лету в момент доступа) и ускорили сборку CSS
- вышел Turborepo 2.0: новый консольный UI и watch mode для автозапуска скриптов, у которых нет своего режима --watch, например, eslint

Проекты
- client-side-rendering — у нас был Webpack, ленивая подгрузка чанков и ассетов, MutationObserver, современный React, несколько хуков, парочка сервис-воркеров и большое желание не юзать SSR. Не то, чтобы всё это было категорически необходимо в разработке, но если уж начал оптимизировать CSR, то к делу надо подходить серьёзно
- fxts — либа для функционального программирования на JS/TS c each, filter, fx, map, pipe, range и другой функциональщиной на борту

Статьи и демки

JS
- разбор темы дата-фетчинга в SPA c асинхронной реализацией, параллельными запросами, и, что показалось мне интересным, с разбором паттерна prefetch с помощью либы swr: предзагружаем бандл следующего компонента по onMouseEnter и заодно результат запроса кешируется и больше повторно не запрашивается
- Intl.DateTimeFormat как альтернатива moment.js и date-fns для форматирования даты в нужном виде, умеет: длинный/короткий формат в зависимости от локали, дни недели, минуты, часы, секунды, таймзоны, 12/24 часа
- статьи Josh Comeau всегда приятно читать, независимо от темы, вот и статья про промисы подоспела, вроде база, а изложена хорошо
- бестпрактисы создания хуков на примере SOLID-принципов: к примеру, HOC, подмешивающий данные через проп в компонент — это такой себе DI «на коленке»
- сборник новинок Node за последнее время: встроенный test runner, watch mode, corepack, .env loader, import.meta.file для __dirname и __file, timers promises

CSS
- свежий гайд по единицам измерениям CSS, примечателен двумя моментами: 1) выглядит, что Geoff Graham вернулся к написанию статей на CSS Tricks, возможно ресурс оживёт, 2) когда объявляется кастомное свойство @property --hue { syntax: "<number>" }, по сути это пользовательская «единица измерения»
- свойство gap для флексбоксов работает с Chrome 84, FF 63, Safari 14.1, то есть давно достойно применения, если нужен условный отступ между элементами, выключающийся при переносе на новую строку, в двунаправленных лейаутах, комбинируется с марджинами
- есть такой частый кейс — анимация с 0 до auto, которую из-за особенностей CSS не возможно сделать через calc(), поэтому есть предложение ввести новую функцию calc-size(), которая сможет анимировать между значениями, если одно из них intrinsic (auto, fit-content, stretch…)

HTML
- как можно улучшить якорные ссылки: scroll-behavior: smooth для плавного скролла, scroll-margin-top и scroll-padding-top для отступа после скролла, :has(h1:target) для стилизации таргет-элемента
- если вы до сих пишете rel="noopener" для безопасности, это можно уже не делать, так как браузеры сами неявно применяют эту фичу

Платформа
- то, что размер DOM (количество DOM-элементов) напрямую влияет на перфоманс как-то интуитивно понятно, но интересна деталь, что существенно сказывается именно глубина вложенности DOM-элементов друг в друга (глубина в 5000 элементов скажется уже на этапе построения дерева, даже до стилей)

@web_platform | Поддержать канал 🤝