Веб-платформа – Telegram
Веб-платформа
2.03K subscribers
4 photos
2 videos
153 links
📍 О том, как всё устроено в веб-платформе и что происходит в индустрии фронтенда

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

👨‍💻 Вопросы и предложения @web_platform_support

🔗 webplatform.tech
Download Telegram
#Пульс_веб_платформы 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 | Поддержать канал 🤝
👍15🔥8
#Фикшн_веб_платформы

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

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 | Поддержать канал 🤝
🔥13👍5👎1
Channel name was changed to «Журнал «Веб-платформа»»
Веб-платформа

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

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

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

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

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

2025 — поехали! 🏁

@web_platform | Поддержать канал 🤝
👍388❤‍🔥3🔥2
#Пульс_веб_платформы 03.01.2025

Новости
🔡 вышла версия новая версия Astro 5.1:
🔵 завезли экспериментальную поддержку хранения на севере данных сессии пользователя (на клиенте не хранятся никакие данные, кроме session id в куки), есть интеграции хранилища сессий с Redis и другими БД
🔵 появилось кеширование не только локальных картинок, но и удалённых
🔵 добавили хэлпер getActionPath для того, чтобы узнать урл серверного action-а на клиенте

Проекты
🔡 ghostty — быстрый и заточенный под «нативность» терминал для macOS и Linux

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

JS
🔡 напоминание, что React Server Components могут работать и без рантаймового сервера, в этом случае «сервер» в билд-тайме рендерит компоненты и сериализует их в текст, а уже этот текст может быть доставлен в SPA «лениво» по необходимости в виде статического файла с обычного файлового хостинга, в таком случае разгружается общий клиентский JS-бандл, то есть теперь SPA уже не всегда означает чистый client-side-render
🔡 если вы занялись неблагодарным делом бенчмаркинга кода, то на пути вас ждут как минимум пара движков: V8 (Chrome, Node, Deno) и JavaScriptCore (Safari, Bun), и в каждом есть свои трюки, оптимизирующие выполнение кода (JIT-кэширование, рандомный Garbage Collector, Tail Call Optimization), которые при бенчмаркинге надо наоборот обойти; но для обычных смертных из полезного можно вынести, что performance.now() более точен, чем console.time()/console.timeEnd(), но при этом выполнение кода специально может немного задерживаться для защиты от фингерпринтинга
🔡 писать на TS, в целом, приятно (не всегда), но вот преобразовывать TS в JS вручную бывает заморочно почти всегда (tsc медленный, нужны режимы билда/вотча…), но хорошо, что уже много тулов поддерживает TS из коробки, в том числе в скором времени и Node 23, так что все в дальнейшем будут ориентироваться на подход Node — просто вырезать типы (а пока будущее не докатилось до чётной версии Node, есть tsx — беззаморочный запускальщик ts-файлов в Node)
🔡 методы forEach и map массивов — всегда синхронные, то есть если вы обрабатываете ими большие объёмы данных, то эта обработка создаёт длинные таски, которые блокируют выполнение других задач в потоке, что в свою очередь может привести к зависаниям вкладки, лагающим анимациям; решается проблема переходом на цикл for .. of и батчингом: в процессе цикла нужно проверить, пора ли делать «паузу» и если да, то запускать await new Promise(requestAnimationFrame) для запуска отложенных перерисовок и scheduler.yield() для выполнения параллельных задач

CSS
🔡 фоллбек-шрифт можно не просто перечислить в font-family, но объявить в @font-face, а внутри подключить гарантированный локальный шрифт через local("Arial"), и затем потвикать его настройки с помощью size-adjust, ascent-override… для большего визуального соответствия основному шрифту
🔡 несколько полезных фактов о кейфреймах:
🔵 одинаковые значения свойств можно не дублировать в нескольких правилах, а объединять в одно правило через запятую 0%, 50% {}
🔵 порядок следования правил в кейфрейме может быть произвольным { from {} to {} from, 50% {} }
🔵 правила с одинаковыми процентами каскадируются, то есть последнее перекрывает предыдущие; внутри отдельного правила в кейфрейме можно подправить animation-timing-function, задав шагу функцию linear()

Платформа
🔡 во вкладке Sources > Overrides можно подредактировать контент в файлах сайта, например, в HTML-файле отредактировать подключение картинок, чтобы протестировать фикс перфоманса без модификации исходного кода
🔡 как в своё время ES впитал новшества CoffeeScript, так и веб-платформа со временем впитывает то, что предоставлялось билд-тулами и фреймворками: резолв пути к файлу есть в нативном import.meta.resolve() и import.meta.url, динамические импорты позволяют «лениво» запрашивать модули, минификация файлов реализуется на сервере с gzip или brotli, конкатенация файлов становится не нужна благодаря HTTP2/3; поэтому базовые кейсы из задач фреймворков/бандлеров вымываются, на их стороне остаются DX и сложные/узкоспециализированные вещи

@web_platform | Поддержать канал 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
👍156🔥5
#Книжный_клуб_веб_платформы

Kent Beck, Tidy First. A Personal Exercise in Empirical Software Design, 2023

Чистка и рефакторинг кода — это гиковская забота о себе. Можно её не делать, но с ней чувствуешь себя лучше.

Самая большая часть «стоимости» при работе с кодом заключается в его чтении и понимании, а не в написании. Когда вы пишите код, вы не только пишете инструкцию компьютеру, но скорее объясняете свои намерения компьютеру для других людей. Просто написать код для компьютера, который будет работать, не особо интересная конечная цель. В хаотично написанный код довольно быстро станет трудно вносить изменения из-за многочисленных связей (часто неявных) между его элементами и сущностями.

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

Какие вещи стоит учитывать при рефакторинге:
✳️ подчистку лучше делать маленькими шагами, настолько маленькими, чтобы их было делать не страшно; небольшая подчистка — самая лучшая
✳️ много мелких рефакторингов и подчисток дополняют друг друга и со временем становятся большой переработкой модуля или системы, за которую будут благодарны ваши коллеги
✳️ разделение кода на мелкие части важно сделать так, чтобы это помогало пониманию; то есть если связать воедино кучу мелких несвязных сущностей, то это усложнит их понимание, а если объединить однородные сущности, то их можно без проблем вынести в отдельную упрощающую понимание абстракцию
✳️ если собирать связанные друг с другом по смыслу и коду вещи (функции, модули, файлы) в одном месте, то нужно будет меньше держать в голове для понимания и работы с этим кодом
✳️ «подчищающие» изменения стоит отделять от меняющих поведение в разные коммиты

Про код:
✳️ вместо того чтобы вкладывать условия друг в друга, условия проверяются в начале функции и выполнение функции прекращается, если условия не выполняются
✳️ кусок кода, выполняющий одно понятное назначение и не сильно связанный с остальным кодом, можно вынести во внешний хелпер
✳️ куски кода, выполняющие разные вещи, можно отделить друг от друга пустой строкой
✳️ если в глубине кода встречается использование env-ов, лучше заменить их на явные параметры
✳️ разросшиеся выражения лучше поделить на отдельные промежуточные части
✳️ код про получение параметров лучше сконцентрировать в начале модуля, остальной код — после
✳️ если объявление и инициализация переменной сильно разнесены по коду, это усложняет понимание
✳️ если у модуля есть интерфейс, который вам не нравится, можно сделать для него «фасад» — свой интерфейс, который вам нравится, а уже внутри вызывать старый интерфейс
✳️ не выполняющийся код можно смело удалять

Про комментарии:
✳️ комментарий, который описывает дословно то, что происходит в коде, можно смело удалять
✳️ если вы читаете файл и уловили момент, когда начали понимать, что к чему в этом файле, это ключевой момент! Можно это место/понимание зафиксировать в комменте (иногда полезно оставлять такие комменты в «шапке» файла)

@web_platform | Поддержать канал 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥21
#Пульс_веб_платформы 10.01.2025

Новости
🔡 вышел отчёт 2024 JavaScript Rising Stars:
🔵 самый «быстрозвездеющий» проект года — shadcn/ui — не нуждается в представлении, второй — Excalidraw — инструмент для создания рисунков и диаграмм, тоже на слуху, третий — AFFiNE — опенсорсный Notion
🔵 htmx — больше всех набрал из фронтенд-фреймворков, даже перегнав React
🔵 из бэкенд/фулстек-фреймворков в топе по популярности Next.js, Hono и Astro
🔵 в тулингах чемпионы Biome, Bun, Vite — чувствуется, что обычному разработчику нужно, чтобы просто работало
🔵 среди state manager-ов победил Zustand, Jotai и XState (Valtio тоже в топе, Redux замыкает лист)
🔵 в CSS-либах топ заняли Tailwind, DaisyUI (либа под TW) и Bootstrap

Проекты
🔡 pixel-canvas — веб-компонент, применяющий блестящий фон на canvas к элементу
🔡 trimmiddle — либа, вырезающая текст из середины строки (недостающий метод строки вдовесок к trimStart() и trimEnd())

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

JS
🔡 Temporal API, ещё нигде в стабильных релизах браузеров не реализованный, хорошо интегрируется с другим полезным Internationalization API, который есть везде уже сейчас и может, например, перевести часы в секунды без доп вычислений с помощью Intl.DurationFormat или отобразить время относительно другого времени с Intl.RelativeTimeFormat (кроме того: у даты есть метод toLocaleString(), выдающий дату в строки в текущей локали, а локаль модно получить в navigator.language)
🔡 история команды, осознавшей, что борется с Next.js больше времени, чем кодит продукт, и перешедшей на обычный React: потеряли фулстек-подход, кеширование и пререндер, серверные компоненты и actions, приобрели быстрый билд и деплой и счастье команды
🔡 Daishi Kato, автор стейт-менеджеров Zustand, Jotai, Valtio поделился мыслями о будущем либ в эру React Compiler/React Server Components: возможно в будущем оптимизации RC сделают встроенные инструменты управления стейтом useState/useContext более эффективными в плане оптимизации необходимости перерендеров, а кеширование в RSC — сделают ненужными комплексные стейты, но тем не менее юзкейсы всех трёх подходов либ продолжают быть актуальными и скорее всего так и будет дальше
🔡 детали того, как работает TS в Node.js:
🔵 типы отбрасываются, работают для файлов с разрешениями .ts, .mts, .cts (.tsx не поддерживается)
🔵 пока что по умолчанию не поддерживаются фичи, требующие транспиляции (enum, decorators, namespaces)
🔵 сорсмапы не создаются, так как расположение кода остаётся тем же

CSS
🔡 необычный юзкейс свойства text-wrap: balance: решает проблему переноса на следующую строку иконки за текстом
🔡 селектор &:hover > *:not(:hover) применит стили по наведению ко всем элементам внутри контейнера, кроме текущего
🔡 интересный концепт безкейфреймовой «анимации»: объявляется кастомное свойство типа integer (значение — конечное в «анимации»), в @starting-style прописывается начальное значение в «анимации», создаётся довольно длинный transition для этого кастомного свойства, в процессе которого выполняется «анимация»

HTML
🔡 атрибут translate="no" выключит нежелательный перевод HTML-элемента в браузере
🔡 подборка, чтобы обновить представление, на что способен современный HTML: для себя нашёл атрибут hidden=until-found, скрывающий элемент до тех пор, пока текст внутри его не нашли поиском по странице, и вспомнил атрибут inert, делающий элемент недоступным для взаимодействия (мощнее, чем pointer-events: none)

@web_platform | Поддержать канал 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
👍134
Хорошей недели всем, кто считает, что своя собственная мясная нейросеть гораздо лучше силиконовой и упражняет мозг каждый день!

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

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

В общем, везде, где получается сиюминутный результат, есть долгоиграющий подвох 🧠

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
30👍5🤝4💯2❤‍🔥1🔥1💩1
#Пульс_веб_платформы 17.01.2025

Новости
🔡 вышел Chrome 132:
🔵 улучшены события и исправлены баги для элементов popover и dialog
🔵 заголовки Strict-Transport-Security (STS) теперь игнорятся для localhost
🔵 довыкатили Keyboard focusable scroll containers, которые раньше забаговали
🔵 File System Access API стало доступно на Android-девайсах и WebView

🔡 вышел Firefox 134.0:
🔵 поддержан Promise.try(), теперь он кроссбраузерный
🔵 экспериментально добавлена поддержка Intl.DurationFormat
🔵 поправлен баг с применением align-self и justify-self к абсолютно позиционированным элементам

🔡 в Node.js v22.13.0 стабилизирована фича Permission Model: это «ремень безопасности» для вашего кода, а не защита от чужого вредоносного кода; запуск файла с флагом node --permission index.js по умолчанию обрежет все права (чтение и запись в fs, порождение процессов…), а указание явных флагов типа --allow-fs-read и --allow-fs-write уже включит только нужное
🔡 в Bun v1.1.43 появился экспериментальный HTML Bundler: команда bun build --experimental-html --experimental-css ./index.html --outdir=dist склеит все js-, css-файлы и ассеты в один файл и подключит их в итоговом html-файле
🔡 WinterCG, группа разрабочиков Deno, слилась с Ecma International, сформировала новый комитет TC55 и выпустила первый черновик их стандарта Minimum Common Web Platform API, где собраны список базовых API для конситентности между разными JS-райнтаймами
🔡 в React-е (и Next-е) появится первое API про анимацию — компонент <ViewTransition> на основе View Transitions API (не поддерживается только в FF), обещают удобство в работе с Suspence, под капотом React будет в определённый момент назначать элементу view-transition-name и вызывать startViewTransition во время мутации DOM-а:

<ViewTransition>
<Suspense fallback={<Skeleton />}>
<Content />
</Suspense>
</ViewTransition>


Проекты
🔡 emojico — cli-тула для генерации набора favicon-ок из эмодзи: под капотом буднично открывается puppeteer и снимается скриншот со страницы с иконкой
🔡 @smoores/epub — оказывается формат электронных книг epub — открытый стандарт W3C, и это либа для работы с epub-файлами
🔡 react-focus-lock — «ловушка» фокуса при показе модалок

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

JS
🔡 спред объекта/массива в объекте не скопирует его, а создаст ссылку на него const state = { ...defaultState, prop: value } — это механизм Shallow Copy; если же нужно именно склонировать объект, то в современном JS для этого есть специальный метод structuredClone (поддерживается везде с 2022):

const state = structuredClone(defaultState);
state.prop = value;


🔡 доля ESM-only и dual (ESM + CJS) npm-пакетов медленно, но верно растёт: в ноябре 2024 у CJS 63%, у dual + ESM 25%
🔡 напоминание для реактоводов: рефы обрабатываются до useLayoutEffect и useEffect

CSS
🔡 псевдокласс :empty помогает скрыть элементы с пустым контентом (правда пока что в браузеры не доехало обновление спеки по этому поводу, то есть блок с пробелами скрыт не будет):

.list > div:empty {
display: none;
}


🔡 бонус использования нативного <dialog>его части легко стилизовать: подложка dialog::backdrop {}, убирание скролла body:has(dialog[open]) { overflow: hidden }

Платформа
🔡 в современных браузерах изменился подход к кешированию ресурсов: если раньше файл мог быть единожды закеширован по урлу и потом для другого сайта браться из общего кеша "https://cdn.example.com/jquery-3.6.0.min.js": resourceData, то теперь для защиты от отслеживания для каждого сайта кеш файла будет храниться отдельно { topLevelSite: "site-a.com", resource: "https://cdn.example.com/jquery-3.6.0.min.js" }: resourceData; как следствие — больше нет выгоды от CDN, дешевле селф-хостить на своём домене типа static.company.com/js/react.js
🔡 для базовой доступности достаточно использовать теги по назначению (кнопки, формы, лейблы + инпуты), не убирать стили фокуса, при открытой модалке ловить фокус и «выключать» контент под ней атрибутом inert, расширять область клика на интерактивных элементах

@web_platform | Поддержать канал 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
14👍11🔥5❤‍🔥1
Хорошей недели всем, кто считает, что не стоит слишком привязываться к инструментам, которыми вы делаете свою работу. А вот подробно изучать, как они работают — никогда не помешает.

Сегодня есть Grunt, завтра его нет. Сегодня есть Gulp, завтра его нет. Сегодня есть CommonJS, завтра его не будет. Сегодня есть Chrome, а завтра будет что-то другое. Сама платформа тоже медленно меняется, так медленно, что незаметно быстрому взгляду. И когда-то и она состарится, забудется и закончится, и это норм.

«У тебя не должно быть любимого оружия. Стать слишком близким с одним оружием – большая ошибка, чем недостаточное знание его. Не копируй других, действуй по ситуации. Плохо также для солдат и командиров испытывать к кому-то любовь или неприязнь. Тщательно изучи это.»
«Книга Пяти Колец», Миямото Мусаси 🥷

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
👍13🔥4😁43🍌1
#Лаборатория_веб_платформы

HAR-файл для выгрузки сетевой активности

Все вы знакомы со вкладкой Network в браузерах, где отображаются ушедшие запросы, пришедшие ответы с заголовками, куками и так далее. Так вот всё это богатство можно из браузера выгрузить в виде файла в формате HAR, во вкладке есть для этого кнопки со стрелками Import/Export HAR file: Export — сохраняет текущую историю сетевых запросов в файл, Import — открывает уже имеющийся файл в дев-тулзах.

Сам файл — это JSON с определённо именованными полями. И формат этот даже в каком-то виде стандартизирован, хоть и не окончательно: нашёлся черновик «HTTP Archive (HAR) format», в котором примерно описан формат, но при этом написано «не пользуйтесь этим черновиком»; а также удалось найти пре-спеку HAR Vocabulary Specification Draft 0.03, в котором тоже описан формат файла.

Помимо браузеров HAR-файлы понимают другие веб-сервисы: просмотрщики, тестовые и автоматизационные тулы.

Юзкейсы:
🔡 поделиться между разработчиками, QA или пользователями «записью состояния» приложения, как воспроизвести определённую ситуацию, когда подёргали в нужном порядке бэк-ручки, передали куки
🔡 предоставить сценарий для проведения нагрузочного тестирования, чтобы выполнить определённый набор запросов в нужном порядке и с нужными параметрами без UI
🔡 открыть файл с логами сетевого взаимодействия в текстовом редакторе для удобного редактирования

@web_platform | Поддержать канал 🤝
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥3👏31
#Пульс_веб_платформы 24.01.2025

Новости
🔡 вышла версия Tailwind 4.0: как уже писал раньше, TW впитывает фичи платформы (что хорошо), но по-прежнему запихивает всё в className, при этом есть и вариант с добавлением «миксинов» с помощью директив @apply, @variant (что в целом ни хорошо, ни плохо, а уже было в SASS)
🔡 поисковая страница Google теперь может требовать у пользователя включить JS, что само по себе ок мув, как и то, что сейчас SPA-страницы индексируются тоже уже ок на равне со статическими
🔡 вышла первая бета Rolldown — замены Rollup + esbuild для Vite: переписанный на Rust новый бандлер Rolldown помимо обратно-совместимого API будет иметь в будущем ещё и фичи, которые Rollup не поддерживает: аналог webpack-овского optimization.splitChunks, HMR, а так же Module Federation
🔡 выпущен Vitest 3.0:
🔵доработан вывод репортов в консоль (стало выглядеть приятнее)
🔵при наличии нескольких проектов, теперь удобно конфигурировать это в поле workspace в vitest.config
🔵добавлена поддержка конфигурации нескольких браузеров, чтобы использовать один сервер для прогона тестов сразу в нескольких браузерах
🔵запуск теста по номеру строки в файле, где он написан

🔡 в Chrome 133+ появится поддержка обновлённой функции attr(), которая раньше работала только внутри свойства content, а теперь сможет работать с любым свойством:

<div data-foo="blue">test</div>


div {
color: attr(data-foo type(<color>), red);
}


🔡 вышло январское обновление React Spectrum/Aria:
🔵в компоненте дейт-пикера и календаря добавлен проп firstDayOfWeek
🔵добавлены CSS-транзишны для оверлеев ModalPopover, Tooltip
🔵выпущена альфа-версия компонента Autocomplete и @react-aria/test-utils — либы с тест-утилитами для компонентов

Проекты
🔡 ohshitgit — набор кейсов, когда у вас случилось что-то нехорошее в git, и как это вернуть взад
🔡 fortune-sheet — либа React / Vue + immer на TS для создания Excel-like-таблиц
🔡 arktype — рантайм валидатор, инферит TS-типы, быстрый

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

JS
🔡 React Query — это не data-fetching-либа, а менеджер состояния, живущего на сервере; именно поэтому, если источник правды приложения сохраняется на бэке, то React Query убирает собой необходимость использования отдельного стейт-менеджера на клиенте
🔡 все либы для работы с хоткеями опираются на задепрекейченные поля, поэтому использовать их нужно осторожно; если ли работать с хоткеями без либ, то нужно использовать поле key, латинские буквы (A-Z) и арабские цифры (0-9), нормализовывать символ с помощью .toLowerCase() и .toUpperCase(), использовать Shift для модификации и не использовать для неё Alt
🔡 разложенный по косточкам tsconfig с вариациями: база, npm-пакет, Node.js, web, запуск ts напрямую (без js), только тайпчекинг
🔡 фишки динамических строковых литералов в TS:

// ключи
interface User {
customerKey: `cus_${string}`;
}

// версия
type Version = `v${number}.${number}.${number}`;

// расширение
type ImageExtension = `png` | `jp${`e` | ``}g` | `webp`;


CSS
🔡 ежегодная подборка свежих CSS-фич, которые можно уже использовать: всё, что касается <dialog> и popover, конечно, только для внутренних проектов сгодится, а вот применение @property и linear() для анимаций, которые не страшно, если отвалятся, уже прям маст-хэв
🔡 напоминание, что ссылки не только на #якорь, но и на определённый текстовый фрагмент на странице (а заодно и стилизация выделенного текста по ::target-text) уже работают по всех современных браузерах, для некритичных вещей точно можно тащить в прод
🔡 современные CSS-фичи типа @container(), @container style(), @supports дают возможность старгетироваться на конкретное устройство и это приводит к возможности злонамеренного отслеживания типа устройства, ОС, почтового клиента: решение — предзагружать все «условные» ассеты (картинки, шрифты) заранее, а не только те, которые «подходят» устройству

HTML
🔡 вместо использования role=button, role=link и остальных проще использовать соответствующий HTML-элемент

@web_platform | Поддержать канал 💙
Please open Telegram to view this post
VIEW IN TELEGRAM
👍17🔥5🤝43
Хорошей недели всем, кто считает, что легаси — наше всё!

Всё, с чем мы сталкиваемся каждый день с большей вероятностью сделано не нами и когда-то до нас (мы буквально культура мёртвых людей: книги, песни, искусство создано прошлыми поколениями). Собственно, то, что сейчас вы можете взять и написать письмо создателю интернета, ну или хотя бы создателям CSS и JS, и они даже вероятно вам что-то ответят — скорее курьёз, чем привычный порядок вещей (многие люди даже не задумываются, кто и когда придумал интернет: он просто есть и был до нас кем-то и когда-то создан, но это уже и не особо важно).

Конечно, одно легаси другому — рознь, но суть едина: это накопленное знание, неизбежно впитывающее противоречия окружающего мира, явлений природы и нас самих. И чем стариннее легаси, тем оно человечнее: ДНК, города, религии, книги, программы. Да та же самая ИИшка паразитирует на переработанном легаси (поглядите на статистику Stackoverflow).

Веб-платформа сама по себе тоже по своей сути легаси, причём изначально задуманное устойчивым. Искренне рад, что работаю в этой сфере!

Собственно говоря, подумал, что негоже писать про платформу и не иметь представительства в WWW, поэтому решил внести свой вклад в наследие и создал сайт webplatform.tech (оформление WIP), куда перенёс все посты, накопленные в канале. Также из-за специфики telegram (4096 символов на пост) написанное не всегда помещается в посты целиком. В вебе этого ограничения нет, поэтому там некоторые посты побольше, чем урезанные под telegram + есть RSS.

Back to the roots! 🥳

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥21👍74🍾1😎1
#Пульс_веб_платформы 31.01.2025

🖇️ Полностью в вебе

Новости
🔡 вышел Bun 1.2, наносящий конкурентный удар Deno (а также замахнувшийся на поляну Vite):
🔵 встроенная поддержка облачного хранилища S3, а также БД Postgres и вскоре MySQL
🔵 текстовый лок-файл взамен бинарного при установке npm-пакетов  bun install, также JSONC (JSON с комментами) для package.json
🔵 поддержан .npmrc
🔵 есть мониторинг версий пакетов bun outdated и публикация bun publish, а также патчинг пакетов bun patch (чтоб захаркодить что-то локально в пакете)
🔵 добавлен бандлинг HTML-файлов с собранными скриптами, стилями и ассетами

🔡 а пока Bun ещё не забрался в область форматирования и линтинга Biome опубликовали свои планы на 2025: добавить поддержку HTML, поддержка одних языков внутри других (например, CSS в JS), а также Markdown, взаимодействие с TS и JSDoc
🔡 и отчёт о работе ESLint в 2024: всего проект заработал 189k$ (74% из которых дали крупные компании)
🔡 Yeoman (помните такой?) воскресили, чтобы поддерживать стабильность в системах, всё ещё использующих его, и пока не выпускать новые фичи
🔡 в TypeScript 5.8 Beta появился флаг --erasableSyntaxOnly, который будет помечать ошибочными «расширяющие» конструкции языка, которые нельзя просто вырезать, а нужно компилировать (goodbye, Enum?)
🔡 CreateReactApp официально помечен deprecated, если вы его ещё используете, вот знак, чтобы этого больше не делать

Проекты
🔡 jsonquery — DSL для выборки нужных данных (для больших JSON-ов)
🔡 react-reverse-portal — либа, позволяющая перенести отрендеренную React-ноду из одного места в другое без перерендера (сгодится для отображения в разных местах тяжёлых компонентов)
🔡 is-my-node-vulnerablenpx is-my-node-vulnerable проверит версию Node на наличие уязвимостей (рекомендуется для включения в CI)

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

JS
🔡 способы искоренения any в коде: если флага noImplicitAny вам недостаточно (JSON.stringify и Function всё равно будут производить any), то будут полезны правила для линтинга: @typenoscript-eslint/no-explicit-any, @typenoscript-eslint/no-unsafe-function-type, а также либа ts-reset, которая заменяет any во встроенных типах на unknown
🔡 оказывается в try {} catch {} можно не указывать скобки и аргумент у catch, и всё будет работать в современных браузерах
🔡 Template literal types — мощнейшая штука, затрагивал пару примеров в прошлом выпуске, но тут прям много юзкейсов и примеров типа такого:

type ToString<
T extends string | number | bigint | boolean | null | undefined
> = `${T}`
;


CSS
🔡 юзкейсы для грядущего в ближайшем Chrome обновлении attr(): по сути это долгожданная связка HTML и CSS без использования JS, храним данные в разметке, используем в стилях:

<li color={props.colorVal} color-name={props.colorName}>


background-color: attr(color type(<color>));

🔡 накопление ошибок и противоречий в легаси неизбежно, не избежал этой участи и CSS: в списке приводятся плохие решения, с которыми мы живём, например, box-sizing по умолчанию не border-box, border-radius следовало быть corner-radius, составные селекторы должны разделяться по запятым, а не ломаться полностью при незнакомом синтаксисе
🔡 если вам не нравится хранить цвет и полупрозрачный цвет в двух разных переменных, то на помощь приходит функция color-mix(in srgb, var(--green), transparent 50%)
🔡 дефолтный системный шрифт font-family: system-ui, sans-serif
🔡 @counter-styleтема кастомного буллета в списках раскрыта полностью: префиксы, суффиксы и иконки
🔡 семейство свойств offset-* позволяет располагать элементы относительно какой-либо формы, в том числе произвольной, а если добавить transition, то и двигать относительно неё

HTML
🔡 просто страница, на которой используются всё HTML-теги
🔡 нативный <dialog> внезапно решает проблему, по которой появились portal-ы во фреймворках

Платформа
🔡 при задаче оптимизации сайта/приложения немаловажную роль играют заголовки Cache-Control Headers, которые у некоторых CDN-провайдеров имеют значения max-age=0 и must-revalidate по умолчанию для CSS и JS-файлов

@web_platform | Поддержать канал 🌟
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥18👍51
Хорошей недели всем, кто не боится совершать ошибки, а считает, что фейл — хороший инструмент обучения. Каждая ошибка, от непоставленной точки до выявленных архитектурных проблем, добавляет новый слой понимания в то, как устроена платформа и фронтенд-разработка.

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

Свои материалы хочу развивать в эту сферу. Прочитал новости или статью → ок, а что дальше? Посмотрел видос → ок, что с этим делать? Если просто посмотреть/прочитать, то, вероятно, изученное улетучится из головы через 5 минут. А если потыкать изученное палочкой, применить знание к решению задачи/проблемы, то уже наслоится знание, присвоится опыт.

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

Поэтому добавил новый раздел на сайт — Тренажёры. Задумал пока что 2 направления: архитектура (паттерны проектирования) и программирование (алгоритмы + структуры данных, оптимизация). В рамках них появится 4 тренажёра: «Паттерны проектирования в JS», «Паттерны проектирования в React», «Алгоритмы и структуры данных» и «Оптимизация кода».

Целиком готовить к выпуску тренажёр довольно долго и сложно (особенно когда есть ещё фултайм работа и блог 😂 + без обратной связи сдувается мотивация, отвлекаюсь на технические проблемы и новые идеи и тд), поэтому решил выпускать понемногу по готовности, условно, раз в неделю по 1-2 части в одном из тренажёров. По примерным прикидкам, если в тренажёре будет около 20 частей, то на каждый уйдёт примерно 3-4 месяца. То есть тему паттернов можно реально закрыть летом.

Звучит как план! Поддержите, если тема отзывается ❤️

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
50🔥15❤‍🔥3
#Пульс_веб_платформы 07.02.2025

🖇️ Полностью в вебе

Новости
🔡 Vercel поглощает компанию Tremor (опенсорсная UI-либа на React, TW, Radix), чтобы использовать дашборды/чарты у себя в админке и в генераторе интерфейсов v0
🔡 вышел Astro 5.2:
🔵поддержан TW 4 через плагин @tailwindcss/vite
🔵добавлен редирект с trailing-slash урлов: /about//about или даже /about///
🔵а также редиректы на http или https, прописываемые сразу в конфиге

🔡 вышел набор полифиллов ES Module Shims 2.0: помимо поддержки import maps в старых браузерах эти полифиллы открывают возможность запускать type-erasable-код на TS прямиком в браузере, без компиляции
🔡 обновился Turborepo 2.4:
🔵появились эксперименты: команда boundaries (проверяет реп на следование бестпрактисам для лучшего кеширования сборки) и кеширование в watch-режиме
🔵тула теперь даёт рекомендации по найденным кольцевым зависимостям в проекте
🔵 поддерживает новый тип конфига ESLint

🔡 выпущен Firefox 135.0:
🔵прекратилась поддержка нестандартного -moz-user-input
🔵появилась поддержка JSON.rawJSON() и JSON.isRawJSON()
🔵выкатили за флагом поддержку Temporal API (продвинутая работа с датами) и Prioritized Task Scheduling API (scheduler.yield() для «создания пауз» в работе эвент-лупа)

Проекты
🔡 bunchee — безконфиговый бандлер для JS/TS-пакетов (все нужные данные для конфига берутся из package.json)
🔡 jscanify — либа для сканирования бумажных документов из картинки или из потока камеры
🔡 shapecatcher — если нужно найти unicode-символ (в том числе эмодзи), то можно его коряво нарисовать руками и поиск выдаст похожие
🔡 node-modules-inspector — интерактивный интерфейс для изучения node_modules в проекте

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

JS
🔡 простейший подход к сервингу, который возможно вскоре будет работать и в Node (но уже сейчас поддерживается в Deno):

// server
const myApp = async (req: Request) => {
return new Response("Hello world!");
};

const response = await myApp(new Request("http://localhost/"));
const text = await response.text();

🔡 Cookie Store API — асинхронное API на смену document.cookie (только Хромиум, но есть в «ночных» версия Safari и FF):

await cookieStore.set()/get()/getAll()/delete()

// а также эвент на изменение
cookieStore.addEventListener("change")

🔡 хук useOptimistic из React 19 подходит для обработки кейсов «промежуточных» состояний интерфейса при асинхронном выполнением действий: ушёл запрос, ждём ответ, пока что оптимистично показали результат
🔡 принцип Open-Closed (sOlid) на примере React-компонентов и хуков: добавляем новую модификацию компонента/функции, не трогаем базовый, а дополняем в новом компоненте/функции

CSS
🔡 @starting-style можно применять в том числе для анимации показа/сокрытия <dialog> и подложки ::backdrop: чтобы они плавно показывались и скрывались без дополнительных телодвижений в коде (типа сменить туда-сюда opacity)
🔡 при выполнении View Transition-ов страница перестаёт быть интерактивной — это из-за псевдоэлемента ::view-transition, который показывается оверлеем над всем вьюпортом; поправить это можно, выключив pointer-events для него:

::view-transition {
pointer-events: none;
}

🔡 для кейса, когда происходит нежелательный перенос текста (например, в кнопке), уместнее использовать min-width: fit-content, который подтянет ширину под контент и справится с задачей переноса более аккуратно, чем text-wrap: nowrap
🔡 для послогового переноса слов используется hyphens: auto, но в дополнение есть ещё свойство hyphenate-limit-chars, ограничивающее количество символов, которые будут перенесены (только Хромиум)
🔡 стилизация HTML-элемента <meter> под «звёздный» рейтинг: ставим на фон SVG с прозрачной «маской», заполняем цветом
🔡 с clip-path: polygon() и transition можно сделать «скошенный» слайдер
🔡 если вы собираете стили с помощью Vite или обходитесь вообще без билд-тулы, то дополнительно можно использовать LightningCSS в качестве минификатора + «пост»-процессора стилей (новенькие CSS-фичи в коде будут фолбечиться до стабильных)

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥19👍54
Хорошей недели всем, кто перестал сражаться с перфекционизмом и подружился с ним. На самом деле стремление к качеству — это очень даже хорошо, а плохо именно стремление пройти весь путь за один шаг без ошибок (так это не работает).

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

С этой мыслью рад сообщить, что создал первые части в тренажёре «Паттерны проектирования в JS»:
✳️ Что такое паттерны проектирования и зачем они нужны
✳️ Паттерн Module (Модуль), теория
✳️ Паттерн Module (Модуль), практика: кэш с WeakMap

Следующий на очереди паттерн Singleton. Stay tuned!

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥276👍6
#Пульс_веб_платформы 14.02.2025

🖇️ Полностью в вебе

Новости
🔡 вышел Chrome 133:
🔵 поддержали обновление функции attr(), которая раньше работала только внутри свойства content, а теперь сможет работать с любым свойством
🔵 добавили псевдокласс :open для открытых <dialog><details>, <select> и <input>
🔵 поддержали семейство «подрезающих» свойств text-boxtext-box-trimtext-box-edge
🔵 у нод появился метод Node.prototype.moveBefore, позволяющий перемещать DOM-ноду в другое место без потери состояния (<iframe> не перезагружается, активный элемент остаётся в фокусе, анимации/транзишны продолжают проигрываться) (в React тоже собираются оперативно поддержать)
🔵 добавлена возможность включать несколько import maps в один документ, браузер смерджит их сам

🔡 вышли результаты опроса State of React:
🔵 многим доставляет боль использование forwardRef (видимо потому что в основном используют 18 версию React для SPA), указание зависимостей в useEffect, а также сложность Next.js и Server Components
🔵 самые популярные либы: Zustand, семейство TanStack, Astro, shadcn/ui, Radix, React Aria, Jotai; самые непопулярные: CRA, Redux, Gatsby, Reaact Bootstrap; для анимаций пользуются Motion, React-Spring, GSAP; для работы с формами React Hook Form, Formik; для тестов Jest и Testing Library; для валидации Zod, Yup; для аутентификации Auth0, Auth.js, Passport

Проекты
🔡 smartbundle — тула для сборки приложений без дополнительных конфигов: команда smartbundle сгенерит CJS- и ESM-сборки, автоматически трансформирует JSX, не забудет о сорсмапах
🔡 get-value — аналог lodash-евского _.get, чтобы достать значение объекта по строке a.b.c.d
🔡 sorted-colors — проект для тех, кто испытывает необъяснимую симпатию к именованным цветам в CSS, позволяет увидеть их все по оттенку

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

JS
🔡 про разбиение лонг-тасков в JS уже писал ранее, но тут автор собрал в одной статье почти все рецепты: setTimeout, async/await + Promise, scheduler.postTask(), scheduler.yield(), requestAnimationFrame() и даже экзотический MessageChannel() — если послать туда сообщение, то оно сразу же выполнится (разве что не упомянуто о queueMicrotask и requestIdleCallback)
🔡 сравнительная таблица текстовых редакторов, если вам нужно сделать этот выбор в 2025: фреймворкоориентированность, многопользовательский режим + комментарии (сразу предостережение — ProseMirror с React не дружит)
🔡 и в догонку сравнительная таблица web-to-desktop-фреймворков (Electron, Tauri…): язык, движок, зависимости, фичи, интеграция во фреймворки, поддержка ОС, размер приложений, расход памяти, время билда и старта
🔡 если вам приходится сознательно заглушать ошибки в TS, то лучше использовать @ts-expect-error, чем @ts-ignore, так вы явно заметите заглушенное место, когда ошибка перестанет происходить и сможете убрать заглушку
🔡 никогда не поздно вдруг понять, что npm ci это «clean install», а не «continuous integration»
🔡 оператор satisfies в TS может быть полезен для:
🔵 уточнения, что объект с неполным набором полей — это ок satisfies Partial<Record<key, val>>
🔵 типизации при преобразовании в JSON-строку JSON.stringify({ /*···*/ } satisfies SomeType)
🔵 типизации default-экспорта export default ((str) => str.toUpperCase()) satisfies StringCallback;

CSS
🔡 доехавший везде @property даёт возможность создать эффект «динамического фокуса» (всё в блюре, круглая область в «фокусе») с помощью mask-image: radial-gradient(... var(--focal-size) ...), к кастомному свойству внутри функции применяется транзишн
🔡 :focus-visible стилизует только фокусировку с клавиатуры, но есть ещё и дополнительная опция у метода .focus({focusVisible: false}) (Safari TP и FF)
🔡 ещё один юзкейс для селектора :has: показывать/скрывать дополнительный блок, когда выбран/не выбран чекбокс в списке: :has(:checked) {}, :not(:has(:checked)) {}, :not(:has(:focus-visible)) {}

Платформа
🔡 если вы хотите неиронично использовать GIF-ку в 2025, то лучше заместо использовать видео-формат AV1 (поддерживается во всех браузерах, кроме Safari, там нужен фолбек в mp4)

@web_platform | Поддержать канал 🌟
Please open Telegram to view this post
VIEW IN TELEGRAM
16👍9
Хорошей недели всем, кто понял, что разумней вкладывать силы в развитие преимуществ, чем в устранение несовершенств. Наличие недостатков вам простят, а отсутствие преимуществ — нет.

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

С этой мыслью рад сообщить, что добавил новые части в тренажёре «Паттерны проектирования в JS»:
✳️ Паттерн Singleton (Синглтон), теория
✳️ Паттерн Singleton (Синглтон), практика: одиночный API-client

А также из обновлений:
✳️ доработан интерфейс под мобилку (теперь тренажёр можно проходить с маленького экрана)
✳️ удобнее стало пользоваться диалоговым окном в практических заданиях (появилась кнопка «Начать» после текста с заданием, окно закрывается по клику извне на подложку)
✳️ бандлер перенесён на селфхост, поэтому тесты в практических заданиях теперь работают пошустрее

Следующий на очереди паттерн Proxy. Stay tuned!

@web_platform | Поддержать канал 🌟
Please open Telegram to view this post
VIEW IN TELEGRAM
21👍4🔥4
#Пульс_веб_платформы 21.02.2025

🖇️ Полностью в вебе

Новости
🔡 в стабильную Node.js 20 бэкпортирована фича require(esm) (импорт EMS-модулей через синтаксис CJS-require), а это значит, что в апреле 2025, когда закончится поддержка Node.js 18, CJS из сборок можно будет выпиливать
🔡 выработали фокус инициативы Interop на 2025 год, предположительно в этом году у нас появятся во всех браузерах: Anchor positioning, View transitions ,@scope, scrollend event, Core Web Vitals, а также исправятся баги с backdrop-filter, <details>, text-decoration
🔡 ESLint больше не EcmaScriptLint, а ExtremelySuperLint (шутка), а именно стал официально поддерживать линтинг CSS: встроенные в @eslint/css правила проверяют пустые блоки, дублирующиеся импорты, невалидные @-правила, а также способствуют использованию правил baseline и @-layer (не шутка)
🔡 CreateReactApp окончательно и бесповоротно задепрекейчен, так как нет мейнтейнера и плюшек внутри и вообще таки зачем вам голый React, давайте уже скорее устанавливайте метафреймворк

Проекты
🔡 create-tsrouter-app — банда TanStack поджидала момент, когда анонсируют депрекейт CRA, подсуетились и подготовили свою замену с поддержкой JS/TS, TW/CSS и конечно же TanStack Router
🔡 react-bits — React-компоненты с анимациями и красивыми свистелками (меня впечатлили splash-cursor и orb)
🔡 use-context-selector — селектор из React-контекста в стиле Zustand useContextSelector(context, (v) => v[0].count) (от создателя, внезапно, Zustand)

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

JS
🔡 Intl.DurationFormat, который вскоре доедет в оставшийся FF, даёт возможность в разном виде в зависимости от локали форматировать период даты-времени
🔡 если для вас в TS дженерики с тернарниками внутри выглядят устрашающе, не пугайтесь, они добрые: если тип с дженериком — это «функция с параметрами», то тернарник внутри — это просто единственный возможный в TS способ описать «условие», в зависимости от которого «функция» будет возвращать то или иное значение:

type Remove<T, R> = T extends R ? never : T;
// «функция» возвращает ничего, если T содержится в R, иначе - переданное значение

type AllColors = "Black" | "White" | "Orange";
type RealColors = Remove<AllColors, "Black" | "White">;
// type RealColors = "Orange"

🔡 если нужно реализовать одностороннюю отправку сообщения с сервера на клиент (а не двустороннее соединение), то можно использовать SSE вместо WebSockets: общение идёт по HTTP, нативно работает во всех браузерах через new EventSource()

CSS
🔡 чтобы создать выезжающие за пределы блока элементы, но при этом чтобы они были в потоке и занимали место, можно воспользоваться гридом с пустыми «рядами», размером auto, чтобы они растянулись на нужное «выпирающее» пространство grid-template-rows: auto [container-start] repeat(4, auto) [container-end] auto;
🔡 селекторы :has и :not не так просты:
🔵 .card:has(:not(img)) выберет .card, в котором внутри есть любой элемент, кроме img
🔵 .card:not(:has(img)) выберет .card, в котором вообще нет img

🔡 псевдокласс ::selection меняет фоновый цвет выделенного текста, но прикол в том, что цвет не обязательно делать один для всей страницы:

::selection { background-color: var(--brandColor); }

:nth-child(2n) { --brandColor: red; }

:nth-child(2n+1) { --brandColor: blue; }

🔡 свойство zoom делает похожую на scale операцию, но при этом «отскейленный» блок не влияет на лейаут (изменяется по сути композитный слой с «картинкой» блока), а «отзумленный» — влияет, то есть вызывает перестроение лейаута

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

@web_platform | Поддержать канал
Please open Telegram to view this post
VIEW IN TELEGRAM
👍124🔥3