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

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

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

🔗 juwain.github.io/web-platform-site
Download Telegram
#Пульс_веб_платформы 13.06.2025

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

Новости
🔡 обновился редактор Cursor 1.0:
🔵 главное — появилась настройка в 1 клик MCP-серверов
🔵 также из интересного появилась бета-фича Memories: редактор может запоминать факты из диалогов и ссылаться на них в будущем

🔡 последние обновления ES от TC39:
🔵 Array.fromAsync перешёл на Stage 4 (доступен везде)
🔵 Error.isError перешёл на Stage 4 (доступен везде)
🔵 using перешёл на Stage 4 (Chrome only)
🔵 Seeded Pseudo Random Numbers от Tab Atkins перешёл на Stage 2

🔡 обновился Astro 5.9:
🔵 появилась экспериментальная встроенная поддержка Content-Security-Policy посредством встраивания тега <meta> с нужными хэшами используемых файлов (также загружаемых динамически)

🔡 недавно анонсировали @platformatic/php-node — официальный модуль Node.js с возможностью процессить PHP внутри Node.js-рантайма; главный вопрос был «зочем?», и вот выпустили статью, где рассказали юзкейсы: миграция PHP-прил на Node.js, гибридные приложения (Node.js сервисы с кусочками PHP-процессинга)
🔡 React Router пообещали сделать стабильнее через перевод процесса разработки на процесс TC39 Process (проход по стейджам + публичные обсуждения)
🔡 команда Edge завезла в будущий Chrome 139 стилизацию gap-ов в гридах/флексбоксах посредством новых свойств column-rule-* и row-rule-*
🔡 релизнули первый стабильный Oxlint (линтер на Rust от Evan You сотоварищи):
🔵 за счёт мультипоточности быстрее ESLint в 50-100x
🔵 есть автомиграция flat-config-а ESLint в .oxlintrc.json
🔵 сразу включает > 500 правил из самого ESLint и популярных плагинов + собственные правила

🔡 анонсировали бету Safari 26, да, Safari 19 не будет, будет сразу 26, следуя за числом года (что будет после 2099 года видимо уже неважно):
🔵 наконец-то будут SVG-favicon-ки
🔵 тег <model> для показа 3d-моделей в браузере (с фолбеком в обычную картинку)
🔵 в CSS поддержаны Anchor Positioning, Scroll-driven Animations, contrast-color(), progress(), margin-trim
🔵 из API поддержаны URLPattern, scrollMargin в IntersectionObserver, File System WritableStream, Pattern Modifiers в RegExp

Проекты
🔡 canidev.tools — CanIUse для фич девтулзов в движках
🔡 odyc — забавная либа для создания простых нарративных игр прям из конфига, такие вайбы «языка» Scratch

Статьи, мнения, туториалы

JS/TS
🔡 с помощью document.currentScript можно пробросить через тег <noscript> внутрь скрипта data-атрибуты, чекать обычные атрибуты (типа, что скрипту обязательно проставлен defer) или же порядок следования скрипта в разметке (только в начале body или после определённого элемента)
🔡 Tanner Linsley убеждает, что URL как хранилище стейта недооценено из-за проблем с парсингом, типизацией и отсутствия связи с роутингом напрямую и рекомендует использовать TanStack Router, чтобы порешать все эти проблемы и наслаждаться рантайм-валидацией роутов с безопасным сохранением стейта в URL
🔡 в отличие от директив (типа use strict) магические комменты в начале файлов вроде /** @aPragma */ или //# aMagicComment, влияющие на процесс интерпретации и транспиляции JS-файлов, нестандартны и мало задокументированы

CSS
🔡 напоминание, что у вариативных шрифтов можно анимировать font-weight
🔡 ещё одно напоминание: вьюпорт-ориентированные динамические единицы измерения sv*lv*dv* с нами уже с 2022 года, то есть сейчас уже считаются широко распространёнными
🔡 анимация до не фиксированного, а динамического значения
🔡 1fr 1fr vs auto auto vs 50% 50%, что выбрать, если нужно разделить на две равные части: в итоге лучше будет воспользоваться гридовым minmax(0, 1fr) для возможности работы overflow при переполнении

Платформа
🔡 задумывались ли вы куда следует ставить фокус при открытии модалки: в инпут, на кнопку закрытия, на заголовок, на кнопку ключевого действия в модалке? Однозначного ответа на этот вопрос нет, зато есть набор вопросов, которые можно себе задать, чтобы выбрать подходящий вариант для вашего конкретного случая

@web_platform | Поддержать платформу 🌟
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍6😎1
#Пульс_веб_платформы 20.06.2025

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

Новости
🔡 вышел релиз pnpm 10.12.1: выкатили экспериментальную поддержку global virtual stores — теперь в node_modules хранятся не сами пакеты, а только симлинки на центральное хранилище в файловой системе, которое может переиспользоваться сразу всеми проектам; поэтому теперь установка пакетов может быть очень быстрой за счёт установленных ранее и закешированных в хранилище пакетов
🔡 Node.js 18 уже достигла End-Of-Life, и мигрировать рекомендуется сразу на текущую активную 22 версию, чтобы в следующий раз нескоро переезжать (апрель 2027)
🔡 выпущен Jest 30:
🔵 поддерживает .mts и .cts файлы по умолчанию
🔵 удалили алиасы expect, для миграции добавили eslint-плагин с автофиксером
🔵 обновили поддержку jsdom, дропнули поддержку Node 14, 16, 19 и 21, TS < 5.4
🔵 так как Гугл задепрекейтил домен goo.gl, который использовался для хранения снепшотов, то придётся их все переделать

🔡 для v0 сделали режим Design Mode, чтобы править параметры в UI без залезания в код (пока поддерживается Tailwind и shadcn/ui)
🔡 в Chromium 138, Firefox 140 и Safari 26 Beta изменится принцип декодирования символов < и > в атрибутах элемента с помощью методов innerHTML и outerHTML (раньше было <div data-content="<u>hello</u>"></div>, теперь будет <div data-content="&lt;u&gt;hello&lt;/u&gt;"></div>)
🔡 вышел Biome v2:
🔵 линтинг типов теперь не завязан на tsc
🔵 поддержаны вложенные конфиги
🔵 выпущен специальный сканер файлов, который находит вложенные конфиги и индексирует файлы
🔵 появилась первая ограниченная поддержка плагинов и HTML-форматтер

🔡 в редакторе Zed появился встроенный Debugger (имплементирован Debug Adapter Protocol (DAP))

Проекты
🔡 eslint-plugin-eslint-comments — плагин для ESLint, который линтит комменты ESLint, чтобы, например, запретить выключение правил линтинга

Статьи, мнения, туториалы

JS/TS
🔡 как сейчас дела в React и экосистеме билд-тулов и фреймворков: по скачиваниям Vite-плагин растёт и догоняет Next, а CRA после депрейката расти перестал; среди остальных React-специфичных фреймворков больше всего скачиваний у React Router, а Astro, Expo и Gatsby существенно отстают
🔡 import-maps изначально не позволяли загружать любые модули до загрузки самого import-map-а, а также всего на страницу мог быть только один import-map: это ограничение усложнило применение технологии у инженеров Shopify и они совместно с вендорами браузеров проработали изменение в спецификации и внедрили в Chromium и WebKit; теперь import-map-ов может быть несколько, и они мерджатся в один, а также любой модуль может загружаться до или после загрузки самого map-а
🔡 утилитарный тип Prettify, которого пока нет в стандартной поставке TS, улучшает читаемость «сборных» типов:


type Prettify<T> = {
[K in keyof T]: T[K];
} & {};


🔡 юзкейсы top-level await в браузере и Node.js:
🔵 запрос конфига на старте приложения const config = await fetch('/config.json')
🔵 динамический импорт другого модуля const dbDriver = await import('./drivers/postgres.js')
🔵 ожидание инициализации (в момент выполнения top-level await выполнение модуля становится на паузу)

CSS
🔡 пока встроенная функция нахождения контрастного цвета текста contrast-color() ещё нигде не работает, можно использовать математическую магию
🔡 в комбинированных анимациях, где используются scale и translate одновременно, важен порядок написания свойств: если scale писать перед translate, то тогда translate будет выполняться неравномерно, так как scale будет «умножать» значения translate
🔡 есть такая функция filter() (не путать со свойством filter), которая позволяет создать комбинированный фильтр, например, из градиента и SVG; всё бы хорошо, но она работает только в Safari, а если хочется кроссбраузерно сделать на градиентной картинке, к примеру, зернёный фильтр, то нужно отдельно задать всему блоку свойство filter и градиент наслоить на зерно

HTML
🔡 чеклист для проверки правильности синтаксиса респонсив-изображений (srcset, sizes) с примерами правильно/неправильно

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

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

Новости
🔡 вышел Chrome 138:
🔵появились функции sibling-index() и sibling-count(), которые возвращают индекс элемента среди собратьев и общее число детей
🔵значение stretch (префиксная версия `-webkit-fill-available`)
🔵математические функции abs(), sign(), progress()
🔵группа встроенных AI-API: Translator API, Language Detector API, Summarizer API
🔵эскейп символов < и > в значениях атрибутов DOM-нод

🔡 выпущен Firefox 140:
🔵в браузере появились вертикальные табы на боковой панели (также можно вручную выгружать табы из памяти)
🔵поддержан CookieStore API и Custom Highlight API, теперь есть во всех браузерах!
🔵вслед за Chrome тоже теперь эскейпируют символы < и > в атрибутах и применяют сквозные стили по умолчанию к h1

🔡 в Astro 5.10:
🔵появились live-контентные коллекции, которые извлекаются в рантайме вместо билд-тайма
🔵стабилизированы встроенные респонсив-картинки

🔡 в Prettier 3.6:
🔵под флагом вышел новый CLI
🔵зарелижены плагины @prettier/plugin-oxc и @prettier/plugin-hermes

🔡 вышел Vite 7.0, в котором дропнута поддержка Node.js 18 и изменены дефолтные таргет-версии браузеров
🔡 выпустили SVGO v4.0.0:
🔵дропнули поддержку Node.js 14
🔵появились новые дефолтные плагины
🔵теперь поставляется в виде dual-пакета: ESM + CJS

Проекты
🔡 syntax-highlight-element — а вот подъехал и веб-компонент для подсветки синтаксиса на свежеподдержаном Custom Highlight API
🔡 sonda — универсальный визуализатор и анализатор JS и CSS-бандлов, совместимый с основными сборщиками и фреймворками
🔡 kelp — новый CSS-фреймворк в 2025 наверное звучит уже иронично, использовать его вы вряд ли будете, но покопать для нахождения интересных фишек никогда нелишне, например, селектор :where(:root) или слоистая структура отдельных модулей CSS

Статьи, мнения, туториалы

JS/TS
🔡 очередная история про уменьшение раздутого бандла; если вы сталкиваетесь с такой же проблемой:
🔵проверьте, хорошо ли работает тришейкинг: возможно придётся убрать barrel-импорты, где-то вручную добавить магический коммент /* #__PURE__ */ и настроить секцию sideEffects в package.json
🔵смените таргет-версию ES хотя бы до es2022
🔵обновите зависимости

🔡 наверняка вы сталкивались с ситуацией в TS, когда из-за ветки проверки ключей Map или индексов массивов в тип значения добавляется undefined, например, undefined | string, из-за этого приходится дополнительно явно проверять значение на undefined либо ещё вариант пропатчить тип метода has() у Map или же просто проставить ! там, где вы точно уверены в результате
🔡 комитет одобрил ES2025, что нового появилось в языке:
🔵Import attributes with { type: 'json' }
🔵Iterator helper methods (filter, map, find…)
🔵новые методы Set()
🔵RegExp.escape()
🔵Promise.try()

CSS
🔡 каскадные слои в CSS — хорошая тема, даже если вы используете подход с атомарными стилями; особенно может быть полезно на больших проектах со старой кодовой базой или внешними стилями, а также если планируется долго развивать комплексное приложение
🔡 скролл-анимации хоть ещё и поддерживаются только chromium-браузерах, но уже появились в превью-версиях Safari и за флагом в FF, так что для каких-то простеньких и не влияющих сильно на UX интерфейсных решений, вполне применимы (например, анимированный индикатор скролла страницы)

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

@web_platform | Поддержать платформу 💕
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102🔥1👏1
Привет! Сегодня новостей не будет. Не то, что бы их нет. Но я в отпуск. Всем чилл! 🌟
Please open Telegram to view this post
VIEW IN TELEGRAM
46🍾17👍11😁6🎉4🔥3😎3😭1
⚡️ Внезапно врываюсь

Всем привет! С момента прошлого поста прошло 111 дней. Думаю, пора расчехляться.

Не то, чтобы всё это время отдыхал. Скорее наоборот: после небольшого отпуска я прям много работал основную работу. Так что на блог как-то сил и времени не оставалось.

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

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

Так вот, к началу осени нужно было сделать бомбически много задач на работе. Поэтому пришлось волей-неволей освоить этих ваших агентов (deepseek, qwen, glm), чтобы раскачать продуктивность в плане скорости доставки задач до прода. Побочный эффект: по сравнению с фронт-задачами бэк-задачи перестали казаться тёмным лесом. С нейросетками получается гораздо быстрее воткнуться в проект, чтобы что-то там начать править в нужную сторону. В двух словах: когда знаешь, в какую сторону должно получиться решение, то проще его сгенерить; а если не знаешь, то можно получить варианты на выбор для валидации разумом.

Но, чтоб вы не подумали, что очередной чел испоганился, и будет теперь шитпостить нейроконтентом, моя песня совсем не о том. А вот о чём: силы и время, потраченные в работу не привели к увеличению профита или сколь либо ощутимым бенефитам, увы. Более того, эта самая работа закончилась. Вкратце: попал под волну лейоффов, которая сейчас вероятно будет шатать всех на рыночке.

Но что ж, в закрывающемся проекте я оказываюсь не впервые, это не беда, это жиза, так работает индустрия. Я не печалюсь, не пребываю в шоках или унынии, даже наоборот, появились силы и интерес залететь в новый проект. Ведь по сути я в душе всё тот же челик из 2002 года, который узнал, что есть такие веб-странички, HTML-теги. Тогда я был просто в диком восторге, когда увидел в первый раз вебсайт с чатом, куда писали какие-то люди. Подозреваю сейчас, что это был айфрейм, который обновлялся по таймеру раз в 5 сек, в котором подгружался фид с сервера на PHP. Меня тогда это всё крайне заинтересовало, и вот я тут в итоге и оказался спустя десятки проектов, сотни реализованных идей и километры написанных букв. Для меня большая радость делать так, чтобы работало. Всё так же верю в веб-платформу и хочу двигать эту историю дальше.

В связи с этим всем у меня есть объявление.

🔽🔽🔽
Please open Telegram to view this post
VIEW IN TELEGRAM
27🔥7
🌟🌟🌟

Ищу работу в роли frontend-разработчика (лид/сеньор).

16 лет в коммерческой frontend-разработке, 12 лет в эдтехе. Последние 2 года — лид продуктовой команды разработки в эдтех-проекте VK (uchi.ru): выстраивал процессы, продумывал архитектуру, активно кодил руками, не просто задачи в джире толкал. Резюме отправлю по запросу.

Если у вас есть на примете дельные вакансии, знакомые hr или просто советы/предложения, то буду крайне рад, если поможете распространить мой запрос Вселенной в нужную сторону.

Контакт: @zyuzin_vitaly

🅰️
Please open Telegram to view this post
VIEW IN TELEGRAM
25👍8🤣8🔥3🙏1
🌀 Так, в общем понял пару вещей про ведение канала.

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

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

И ещё добавлю пункт, который понял ещё раньше. Что блог — норм такая площадка для прокачки внутренней силы, помимо внешней из пунктов 1 и 2. То есть страдаешь, изучаешь что-то, формулируешь, пишешь пост ➡️ растёшь над собой. Приятный бонус — общественное одобрение.

То есть, хоть блог и не приносит прямых материальных доходов и при этом забирает временнЫе ресурсы, он добавляет 1) рандомные бонусы от общества и 2) повышает репутацию. И ещё это приятно в итоге, хоть и бывает трудно в процессе.

В общем, это я к чему. Зря забросил канал, надо продолжать вести, буду вкатываться обратно потихонечку. Вот, кстати, и новый пост.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍169🔥9
Проблемы во фронтовых проектах и их решения

Подсобрал список типовых проблем и их решений, с которыми неизбежно сталкиваются разросшиеся фронтовые монорепы или семейства проектов, если заранее не позаботиться о решениях.

⚠️ Неудобная локальная разработка, зоопарк технологий/подходов, сложно вкатываться в существующие проекты

Решения:
0️⃣ Переход на единую типовую сборку (Vite, Webpack…) с общим конфигом, общий инструментарий для монореп (workspaces, turbo, lerna…).
1️⃣ Создание единого шаблона для старта нового приложения.
2️⃣ Выработка единообразного стека:
🔡 система: node/bun, TS, фреймворк (React, Vue, Next…)
🔡 зависимости:
🔵пакетный менеджер (yarn/npm/pnpm, для консистентности лок-файлов)
🔵стейт-менеджер (или его отсутствие => Tanstack Query)
🔵роутер
🔵инструменты для работы с формами (хуки, валидация, маски для инпутов…) и валидатор схем
🔵стилизация (CSS Modules, SASS, Styled-подобные, ваниль), использование единообразного UI-kit (Storybook)
🔵утилиты (работа с датами, общие либы типа lodash)

3️⃣ Процесс регулярных обновлений зависимостей.
4️⃣ Единообразная структура проекта/проектов, приведение к единому виду (FSD…).
5️⃣ Архитектурные соглашения по выносу шаренных кусочков в микрофронты, связь между «отдельными кусочками» приложений в рамках общих приложений.
6️⃣ Общий/стандартизированный CI/CD.
7️⃣ Общий подход к проксированию запросов на бэк, к развёртыванию проекта локально.
8️⃣ Общий код-стайл и линтинг (ESLint, Prettier, Biome…).
9️⃣ Общий подход к логированию аналитики.

⚠️ Долгая разработка, необходимость частых ресерчей

Решения:
0️⃣ Централизованное внедрение AI-инструментов для помощи в написании кода (выбор единых агентов, генерация вспомогательных артефактов типа claude.md)
1️⃣ Создание бойлерплейта для документации и внедрение AI-генерации документации. Хранение документации в самих проектах и регулярная перегенерация.

⚠️ Дублирования кода, велосипеды

Решение:
Вынос повторяющихся пакетов в шареное хранилище переиспользуемых решений, хостинг в приватном npm-реестре, поддержка.

⚠️ Большое количество багов, уязвимостей и неконтролируемый/плохой перф и UX

Решения:
0️⃣ Внедрение мониторинга ошибок (Sentry), настройка алертов в чаты/дашбордов на ошибки (Grafana).
1️⃣ Подключение измерения метрик перфа в рантайме у пользователей (Vitals, TTVC и подобные), а также на CI/CD («бюджет» на перф в пулреквестах).
2️⃣ Интеграция в CI/CD инструментов для поиска уязвимостей в коде.
3️⃣ Процесс регулярного пополнения и разгребания бэклога техдолга (баги, уязвимости, оптимизации).
4️⃣ Внедрение среды для тестов/автотестов, написание/генерация юнит-тестов и e2e-тестов, регрессионное тестирование, запуск на CI/CD.
5️⃣ Выработка плавил работы со статикой (картинки на CDN, автоматизированное сжатие, ленивая загрузка).

⚠️ Несогласованная командная работа

Решения:
0️⃣ Использование контрактов (Open API) на бэке/фронте, кодогенерации типов и API-клиентов, клиент-серверных фреймворков (trpc).
1️⃣ Внедрение автоматизации в код-ревью (автоназначение ревьюеров, выработка правил мерджа в master, AI-генерация описаний пулреквестов и ревью).
2️⃣ Договорённости в единообразном именовании коммитов (conventional commits), веток, пулреквестов; единые подходы к организации дев/стейдж/релиз-веток; семантическое версионирование релизов.

#Лаборатория_веб_платформы

@web_platform | Поддержать платформу 💕
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12🤮83🥱2👎1👌1
Про микрофронты на коленке. Iframe

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

Как это работает: по определённому адресу хостится мини-приложение, например, по урлу example.com/header грузится общее приложение хедера для всех возможных хост-сред. Во все хост-приложения хедер встраивается через iframe:

<iframe src="/header"></iframe>


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

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

window.parent.postMessage — отправляет сообщение изнутри фрейма наружу, в родителя.

iframe.contentWindow.postMessage — отправляет сообщение снаружи, от родителя, внутрь фрейма.

Получаются отправленные события подпиской на message (как изнутри iframe, так и в родительском приложении снаружи):

parent.html:

<iframe id="myFrame" src="/child"></iframe>

<noscript>
const iframe = document.getElementById('myFrame');

// Отправка сообщения во фрейм
iframe.addEventListener('load', () => {
iframe.contentWindow.postMessage({ type: 'fromParent', payload: 'Привет!' }, '*');
});

// Получение сообщения от фрейма
window.addEventListener('message', (event) => {
if (event.data.type === 'fromChild') {
console.log('Получено от фрейма:', event.data.payload);
}
});
</noscript>


child.html:

<noscript>
// Отправка сообщения родителю
window.parent.postMessage({ type: 'fromChild', payload: 'Ответ!' }, '*');

// Получение сообщения от родителя
window.addEventListener('message', (event) => {
if (event.data.type === 'fromParent') {
console.log('Получено от родителя:', event.data.payload);
}
});
</noscript>


Эту идею можно раскрутить и дальше. Например, если одни и те же данные с сервера нужны в нескольких микрофронтах, то это может привести к дублированию запросов. Один из выходов — перенести этот дублирующийся запрос в хост-приложение и шарить его с фреймами. Ещё один вариант — сделать отдельный iframe, в котором визуально ничего нет (его можно даже скрыть), но есть данные. Данные этот стор-iframe может шарить наружу всем желающим, тоже через postMessage.

Также помимо общения через postMessage шаринг данных между контекстами можно построить на Broadcast Channel API или Channel Messaging API.

Broadcast Channel обеспечивает широковещательную связь между всеми контекстами одного origin, а Channel Messaging создает секьюрный двусторонний канал связи между двумя конкретными контекстами.

То есть этот самый «стор с шаренными данными» при получении данных может в зависимости от цели пулять данные или на всех, или точечно в конкретное место. Работают оба способа тоже на похожих postMessage.

В случае с Broadcast Channel надо как-то пошарить между потребителями созданный объект самого канала:

const bc = new BroadcastChannel("test_channel");

bc.postMessage("This is a test message.");

bc.onmessage = (event) => {
console.log(event);
};


В случае с Channel Messaging параметры для связи двух контекстов передаются в доп параметрах postMessage:

const channel = new MessageChannel();

const port1 = channel.port1;

port1.onmessage = onMessage;

port1.postMessage("value");


Бонус: у iframe есть атрибут loading=lazy, чтобы не подгружать те фреймы, которые находятся вне вьюпорта.

И ещё: в хромиум-браузерах все iframe на одном домене будут обрабатываться в одном потоке, то есть могут потенциально блокировать друг друга, даже если не блокируют родителя (лайфхак: если нет нужды держать их на одном домене, то выносом на другой домен можно «распараллелить потоки»).

#Лаборатория_веб_платформы

@web_platform | Поддержать платформу 🌟
Please open Telegram to view this post
VIEW IN TELEGRAM
15👍8🔥6
А вы заметили, что со всеми этими ии-движухами как-то морально проще стало экспериментировать с новым софтом и подходами в работе. Раньше ну узнаешь, что какая-то там либа вышла, ну подумаешь, что надо когда-нибудь попробовать, и всё на том. Ну максимум на свежем проекте или новом компе что-то свежее ставишь, пробуешь.

А теперь как-то реально попроще со всем этим стало: узнаёшь, сразу пробуешь, профит (наверное это можно назвать таблеткой от FOMO, правда хоть это и купирует приступы, но провоцирует повторные 😁).

Возможно на такой волне стоит присмотреться и к остальной экосистеме. Например, вот в pnpm подвели итоги прошлого года. В v10 много всего интересного.

Самое важное — pnpm перестал доверять всем пакетам. Раньше pnpm install давал любому пакету в дереве зависимостей запускать произвольный код (preinstall, postinstall). Это само собой создавало вектор атак через supply chain.

В v10 lifecycle noscripts блокируются по умолчанию. Никакого preinstall/postinstall без явного разрешения.


allowBuilds:
esbuild: true
nx@21.6.4: true


Ещё одна фишка pnpm — content-addressable store (дедупликация файлов). В v10.12 сделали ещё шаг дальше — глобальное виртуальное хранилище.


pnpm-workspace.yaml
enableGlobalVirtualStore: true


Раньше каждый проект имел свой node_modules. Теперь общие зависимости линкуются один раз глобально. А это:
1. Экономия диска — одинаковые графы зависимостей шарятся между проектами.
2. Быстрые установки — если 10 проектов используют react@19, pnpm линкует его один раз из глобального хранилища на машине.

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

Конфиги зависимостей устанавливаются в node_modules/.pnpm-config до основного графа зависимостей.


# pnpm-workspace.yaml
configDependencies:
pnpm-plugin-my-company: "1.0.0+sha512-..."


Это помогает шарить .pnpmfile.cjs хуки между репозиториями, централизовать патчи для patchedDependencies, поддерживать список пакетов, которым разрешено запускать build скрипты.

Кроме того, pnpm давно умеет переключать версию Node.js для рантайма (не нужен nvm). В 2025 добавили Deno и Bun.


// package.json
{
"devEngines": {
"runtime": {
"name": "node",
"version": "24.6.0"
}
}
}


Pnpm сам скачает и будет использовать указанную версию для скриптов.

Поддержка JSR — тоже прикольно, но пока что не особо актуально, как я вижу.

Кроме того, ещё от себя добавлю, что в pnpm есть catalogs-алиасы (чтобы один раз в конфиге объявить набор зависимостей), workspaces (для организации монореп), возможность патчить зависимости (pnpm patch) и проверять их на актуальность (pnpm outdated)

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

@web_platform | Поддержать платформу 🌀
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥7❤‍🔥1💯1
react-best-practices

Тут Vercel подогнали мозгов для ваших frontend-агентов набор бестпрактисов и антипаттернов по React, можно установить в виде скиллов в ваш любимый агент или просто почитать. Темы, рассматриваемые внутри: устранение вотерфоллов, оптимизация размера бандла, SSR, дата-фетчинг на клиенте (жаль, что без tanstack, а только swr), оптимизация ререндеров, перфоманс рендеринга и JS, а также ещё немного мелочей.

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

@web_platform | Поддержать платформу 🌀
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥27🤔21💩1🍌1💅1🗿1
Что нового Baseline Widely Available, часть 1

В прошлом году (+ в январе 2026) довольно много платформенных фич достигли статуса Baseline Widely Available — это значит, что они поддерживаются во всех основных браузерах уже 30 месяцев! А это повод бескомпромиссно тащить их в прод проверить аналитику по пользовательским устройствам и браузерам в вашем проекте (скорее всего ваши пользователи уже обзавелись браузером, которые эти фичи поддерживают).

Собрал списком все фичи с кратким описанием и моими комментами к их использованию.

CSS

Container Queries — применение стилей на основе размеров родительского контейнера, а не viewport. Позволяет создавать адаптивные компоненты, которые реагируют на свой контейнер.


.card {
container-type: inline-size;
}

@container (min-width: 300px) {
.card { background-color: lightblue; }
}


Мнение: 5 из 5, но требует перестроить майндсет в целом при работе с UI (то есть не только вам как разработчику, но ещё из продукту и дизайнеру, часто думающим "мобилками"). Хорошо ложится на UI-киты и разработку изолированных компонентов.



Individual Transform Properties — отдельные свойства translate, scale, rotate вместо одного transform. Упрощает анимации и улучшает читаемость кода.


.element {
translate: 20px 10px;
scale: 0.8;
rotate: 90deg;
}


Мнение: 3 из 5, приятный сахар, помогает сократить повторящийся код при написании трансформов, легко внедрить.



Motion Path — анимация элементов вдоль заданного пути с помощью offset-path.


.element {
offset-path: path('M10 10 L 100 100');
animation: move 2s linear infinite;
}


Мнение: 2 из 5, специфичная, но прикольная фича, но если появится подходящая задача и вовремя вспомнить, можно избежать использования JS для анимации движения элемента по траектории.



Grid Animation — анимация свойств grid-template-columns и grid-template-rows.


.grid {
display: grid;
grid-template-columns: 1fr 1fr;
transition: grid-template-columns 0.3s;
}
.grid:hover {
grid-template-columns: 1fr 2fr;
}


Мнение: 2 из 5, в целом прикольная фича для разъезжающихся динамических лейаутов, но применимость нечастая.



animation-composition — выбор способа комбинирования анимаций, влияющих на одно свойство.


.element {
animation-composition: add; /* replace, add, accumulate */
}


Мнение: 2 из 5, если делаете руками CSS-анимации, может пригодиться, иначе не будет полезно.



color-mix() — смешивание двух цветов в заданном цветовом пространстве. Полезно для создания светлых/тёмных оттенков.


.element {
background: color-mix(in srgb, red 50%, white 50%);
}


Мнение: 4 из 5, чрезвычайно мощная штука, если настраиваете собственную дизайн-систему, стайлгайд или UI-кит в проекте.



color() — выбор цвета из указанного цветового пространства. Поддерживает wide-gamut пространства вроде display-p3 для более насыщенных цветов.


.element {
color: color(display-p3 0.5 0.2 0.8);
}


Мнение: 4 из 5, аналогично мнению про color-mix().



Lab и LCH — цветовые пространства с перцептивной равномерностью. Lab использует прямоугольные координаты, LCH — полярные.

Oklab и OkLCh — цветовые пространства, разработанные для лучшего соответствия человеческому восприятию цвета. OkLCh — полярный вариант Oklab.


.element {
color: lab(50% 20 -30);
background: lch(60% 50 150);
color: oklab(0.5 0.2 -0.1);
background: oklch(0.6 0.5 120);
}


Мнение: 4 из 5, формат oklch может также пригодиться для гибкой настройки цветовой палитры и её производных в проекте.



Small, Large, Dynamic Viewport Units — единицы dvh, svh, lvh для учёта UI мобильных браузеров. sv* — минимальный размер, lv* — максимальный, dv* — динамический.


.element {
height: 100svh; /* 100% минимального viewport height */
width: 100dvw; /* 100% динамического viewport width */
}


Мнение: 4 из 5, если вы когда-нибудь боролись с fullscreen-высотой в вёрстке на мобилках, то в следующий раз присмотритесь к этим значениям.

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

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

@web_platform | Поддержать платформу ⭐️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍18🔥11🎉3💯1
Что нового Baseline Widely Available, часть 2

...продолжение

CSS

Two-value display property — свойство display теперь принимает два значения для явного указания внешнего и внутреннего режима layouts. Например, inline flex или block flow.


.card {
display: inline flex;
}
.container {
display: block flow;
}


Мнение: 2 из 5, любопытно, но не более.



overflow: clip — обрезка содержимого без создания скроллов, с возможностью обрезки только по одной стороне


.nav-bar {
overflow-x: clip;
overflow-y: visible;
}


Мнение: 4 из 5, полезно, если нужно включить скролл по одной стороне + также это значение overflow, в котором не создаётся новый formatting context.



overscroll-behavior — управление поведением при прокрутке за границы.


.container {
overscroll-behavior: contain;
}


Мнение: 3 из 5, очень узкоспециализированная фича, но может быть крайне полезна для управлением мульти-скроллом.



outline — свойства для стилизации линии вокруг элемента вне border, не влияющие на layout.


.element {
outline: 2px dashed red;
outline-offset: 5px;
}


Мнение: 3 из 5, фича-то старая, но был баг в Safari, который починили в 03.2023.



:nth-child() of <selector> — более точный выбор элементов с фильтром по селектору.


li:nth-child(odd of .active) {
background: yellow;
}


Мнение: 4 из 5, прикольная штука для условной стилизации, полезно вспомнить перед решением реализовать такое на JS.



Media Query Range Syntax — новый синтаксис для медиавыражений с диапазонами.


@media (400px <= width <= 800px) {
/* стили */
}


Мнение: 4 из 5, синтаксический сахар, нравится, что наконец не нужно каждый раз вспоминать и перебирать варианты min/max-width.



Resolution Media Query — медиавыражение для применения стилей на основе плотности пикселей устройства.


@media (min-resolution: 2dppx) {
/* стили для high-DPI экранов */
}


Мнение: 2 из 5, узкоспециализированная фича, но может пригодиться для детальной стилизации для разных мобильных устройств.



Trigonometric Functionssin(), cos(), tan() в CSS для математических вычислений.


.element {
transform: rotate(calc(sin(45deg) * 1turn));
}


Мнение: 2 из 5, любопытно, но слишком хардкорно, малоприменимо в реальной жизни.



calc() Keywords — математические константы e, pi, infinity, NaN в CSS math функциях.


.element {
font-size: calc(var(--base-size) * pi);
height: calc(100vh * sin(pi / 2));
}


Мнение: 1 из 5, не могу придумать, где это применить.



font-palette — выбор цветовой палитры из шрифта, с возможностью переопределения отдельных цветов через @font-palette-values.


.element {
font-palette: alternate;
}


Мнение: 1 из 5, малополезная фича, применимая только для "цветных" шрифтов, не стоит внимания



Style Containment и Inline-size Containment — изоляция стилей элемента. style ограничивает расчёт счётчиков и кавычек внутри элемента, а inline-size предотвращает установку inline-размеров элемента его содержимым, ускоряя рендеринг.


.widget {
contain: style;
}

.container {
contain: inline-size;
}


Мнение: 3 из 5, мелкие малополезные фичи, style может пригодиться разве что в нестандартных нумерованных списках; inline-size, могу только в теории представить, что может быть полезно в разного рода wysiwyg-ах (за исключением контейнерных запросов, которые без этой шутки не заработают).



HTML / DOM

inert — атрибут для отключения элементов от взаимодействия и accessibility tree. Элементы не получают фокус и не реагируют на клики.


<div inert>
<button>Неактивная кнопка</button>
</div>


Мнение: 4 из 5, мощная и простая фича, хороший юзкейс для ограничения пределов фокуса при показе модальных окон: модалка работает, body под ней за inert-ом.

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

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

@web_platform | Поддержать платформу ⭐️
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥16
playwright-cli

Тут вышел https://github.com/microsoft/playwright-cli, более эргономичный, чем MCP, способ запускать ботом безголового playwright для выполнения действий в браузере.

Да, собственно, не обязательно ботом, можно просто в рамках CLI-API написать скрипт для автоматизации действия в браузере:


playwright-cli open https://demo.playwright.dev/todomvc/ --headed
playwright-cli type "Buy groceries"
playwright-cli press Enter
playwright-cli type "Water flowers"
playwright-cli press Enter
playwright-cli check e21
playwright-cli check e35
playwright-cli screenshot


Вот эти вот e21 и e35 — это наименования DOM-нод в открытом сайте. Командой open сайт открывается и записывается его снепшот в виде yaml-файла. Каждая нода помечается своим айдишником.

По необходимости можно вызывать playwright "с головой":

playwright-cli open https://playwright.dev --headed


Для ботов прописаны доки для выполнения рутинных задач:
- Request mocking — перехват и мок запросов
- Running Playwright code — выполнение playwright-скриптов
- Browser session management — управление браузерными сессиями
- Storage state (cookies, localStorage) — запись и чтение из браузерного хранилища
- Test generation — генерация тестов после взаимодействия с сайтом
- Tracing — запись трейсов
- Video recording — запись видео
🔥13