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

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

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

🔗 webplatform.tech
Download Telegram
#Пульс_веб_платформы 23.05.2025

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

Новости
🔡 команда TS выкатила превью нативного TS на Go, можно попробовать в терминале npm install -D @typenoscript/native-preview или в VS Code в виде расширения: оно живое (!) и по ощущениям LSP в VS Code шевелится побыстрее
🔡 Microsoft заопенсорсит расширение Copilot-чата, тем самым видимо планируя прикрыть зоопарк форков VS Code с AI-панельками; также Copilot Chat будет поддержан в вебе и существенно доработан
🔡 Stackoverflow стремительно теряет активных пользователей (и не потому что на все вопросы уже ответили, а потому что узнавать ответы стали в других местах), поэтому компания думает о ребрендинге и перефокусировке с только Q&A ещё на сообщество и построение карьеры; что ж, такие времена, или адаптируйся под AI, или умри
🔡 Mozilla просит суд не перекрывать «денежный» кислород от Google в антимонопольном деле; такой вот парадокс: чтобы поддержать хоть какую-то конкуренцию, нужно продолжать делать «нерыночные» вливания за поиск Google по умолчанию в FF
🔡 ESLint в добавок к JSON, md и CSS, теперь умеет линтить HTML с помощью плагина html-eslint; как и в прошлых случаях из коробки сразу идут многие базовые правила, которые не надо дополнительно настраивать
🔡 вышли ES Module Shims 2.5:
🔵 позволяют использовать нативные импорты CSS- и JSON-модулей: import style from './style.css' with { type: 'css' };
🔵 нативный TS теперь просто работает, без доп настроек
🔵 появилась возможность замутить «нативный» hot reload через import.meta.hot

🔡 в семействе Rs- вышла новая либа для создателей либ — Rslib: внутри уже предустановленные конфиги для беспроблемной сборки (в том числе стилей) и публикации либ в разных форматах (ESM, CJS, UMD, Module Federation)
🔡 а в семействе TanStack вышла клиентская БД/стор — db, которая держит данные на клиенте, позволяет делать выборки (query) из этой БД и синкается с любым бэком

Проекты
🔡 crosspost — JS-либа для кросспостов в соц сети; тут хочется подсветить не фичи либы, а её API — чистый паттерн Strategy (о котором рассказывал в тренажёре), зацените

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

JS/TS
🔡 для работы с буфером обмена можно использовать методы navigator.clipboard.writeText() для обычного текста или navigator.clipboard.write() для всех остальных форматов типа картинок, текстового контента и HTML; а проверить браузер на умение вставлять определённый формат (без выброса исключения) можно с помощью ClipboardItem.supports()
🔡 юзкейсы генераторов в JS обычно довольно специфические, но если свести к сути, то они подходят для любой условно «бесконечной» серии действий: перебора элементов, генерации наборов, обработки асинхронных сообщений; неочевидный пример:


function* getElements(tagName = "div") {
while (true) yield document.createElement(tagName);
}


CSS
🔡 для нативных <input type="date"> и <input type="time"> в некоторых хромиум-браузерах показываются иконки часов и календаря, для их стилизации подходит псевдокласс ::-webkit-calendar-picker-indicator
🔡 новую функцию shape() можно использовать не только в связке с clip-path() для рисования фигур, но и с offset-path для задания формы движения: вместо offset-path: path("") более читаемый offset-path: shape()
🔡 некоторые CSS-сниппеты разной степени полезности: точно подтвержу, что если делаете какой-то общий компонент со стилизацией, которая может внезапно стать «глобальной» (стилизация по тегам p, body`…), то её точно полезно завернуть в `@layer {}, чтобы у потребителя не возникло необходимости переопределять ваши «глобальные» стили, так как они будут применяться раньше по каскаду
🔡 неинтуитивные решения для лейаута, например, по умолчанию минимальная ширина grid- и flex-детей — auto, что не всегда удобно, и её можно сбросить

HTML
🔡 тег <datalist> можно использовать не только для «выпадашки» текстовых значений, таргет-элементом листа может быть, например, <input type="color">, а элементами листа, соответственно, цвета

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

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

Новости
🔡 закрывается браузер Arc: создатели переключились на другой браузер (с AI) Dia, под капотом тоже Chromium и проприетарная платформа для создания браузеров, которую опенсорсить не собираются
🔡 также закрывается проект Glitch (браузерный редактор веб-приложений + хостинг) после 10 лет работы
🔡 в ESLint провели ретроспективу выкатки flat-config-а с 2019 по 2024, выявили основные ошибки: слишком много ломающий изменений за раз, слишком много документации и отсутствие тулинга автомиграции, медленное впитывание новой версии экосистемой, отказ от двойных конфигов (надо было поддержать, востребовано авторами плагинов)
🔡 господа из React Router поддержали в RR React Server Components, а также решили воскресить Remix (в лучших традициях рестлинга) да не просто так, а сделать его полностью независимым, даже от React (внутри будет форк Preact): теперь стало понятно, что этот проект — экспериментальная площадка, чтобы проверять крейзи-фичи и затем интегрировать их в «стабильный» RR
🔡 вышел Chrome 137:
🔵 поддержали функцию if() в CSS: background-color: if(style(--color: white): black; else: white)
🔵 заработала функция shape() для указания направления в свойстве offset-path
🔵 добавили значение view-transition-name: match-element, чтобы автогенерировать название вью-транзишна вместо хардкода или задания из JS

🔡 вышел Firefox 139.0:
🔵 из коробки работает Temporal proposal (прикол в том, что для движка SpiderMonkey поддержку реализовал один чел, опенсорсный контрибьютор, который не работает в Mozilla)
🔵 поддержали атрибут hidden=until-found
🔵 в экспериментальных фигах за флагом приехали: View Transition API, scheduler.yield()

🔡 вышла новая версия Bun v1.2.14:
🔵 позаимствовали фичу catalogs: из pnpm для создания алиасов для группы зависимостей
🔵 добавили флаг bun init --react для быстрого разворачивания шаблона React-проекта и дев-сервером на Bun

🔡 вышла новая версия JSPM 4.0 (import map package manager): внутри команды для безконфиговой сборки и сервинга проекта, поддержка нативного TS «со стриппингом», импортмапы средствами браузера — звучит знакомо? да, потому что контрибьютор JSPM и ES Module Shims — один и тот же человек, Guy Bedford

Проекты
🔡 snapdom — либа для снятие скриншота с DOM-ноды, как в дев-тулзах, только отдельной либой (и без папеттира внутри)
🔡 enum-converter — пример работы  TypeScript Transform API — конвертер Enum в type alias

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

JS/TS
🔡 реактовский useSyncExternalStore можно использовать не только для хранения каких-то бизнес-данных (типичный стор), но и для «UI»-информации, например, данных о window.matchMedia: подписываемся на 'change' состояния экрана, записываем в «стор», в React-компоненте юзаем этот стор
🔡 как избегать проблемы циклических импортов между компонентами с помощью здравого смысла, а также инверсии зависимостей (меняем прямое использование на пропы) на примере методологии FSD
🔡 в связи с начавшейся раскаткой Temporal в браузерах (FF — первый) пора знакомиться, если ещё не, тем более, есть полифилл
🔡 краткая история JS с уклоном в Райана Даля, Node и Deno: в 2025 JS исполнилось 30 лет, JSDoc — 26 лет, JSON — 24, Safari — 22, MDN — 20, jQuery — 19, Chrome — 17, Node.js, CoffeeScript — 16, npm, Backbone — 15, TypeScript — 13, React — 12, ES6 — 10, Next.js — 9, Bun — 2

CSS
🔡 помимо именования view-transions с ними есть ещё одна проблема: так как транзишн применяется к document, одновременно может выполняться только один транзишн + есть проблема с z-index, когда транзишнящийся элемент перекрывает всё вокруг; решение — будущий Scoped View Transitions, то есть возможность запуска транзишна на конкретном элементе element.startViewTransition()
🔡 эффект «фонарика в темноте»: что прикольно, так это, что можно задавать любую форму светлому участку благодаря filter или mix-blend-mode, например, «решётка» из градиентов сильно смазанная и переконтращенная filter: blur(1em) contrast(100) становится движущейся «кляксой»

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

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

Новости
🔡 в Chrome 138 (сейчас уже в бете) будут доступны CSS-функции sibling-index() и sibling-count(), которые отдают интежер с позицией элемента среди собратьев и общее число детей, будет работать внутри calc():


li {
animation-delay: calc(0.1s * sibling-index());
}


🔡 выпущен tech preview «растифицированного» Vite — Rolldown-Vite: под капотом заменили связку Rollup + esbuild на собственные Rolldown + Oxc, чем существенно ускорили сборку по времени и памяти; заодно решили, что раз оно теперь работает быстро, то можно и для дев-сервера сделать не лёгкую ESM-сборку, а полноценную, и в будущем в Vite будет доступен режим full-bundle mode
🔡 обновился Vitest до версии 3.2:
🔵 задепрекейтили настройку workspace в пользу projects
🔵 добавили аннотации в выполнение тестов, которые будут выводиться в консоль, и кастомные цвета для projects
🔵 добавили возможность раcширения встроенных locators собственными методами

Проекты
🔡 livestore — решение для стораджа данных на клиенте в SQLite c реал-тайм-синхронизацией всех клиентов и бэка
🔡 udm14 — если добавить параметр &udm=14 к поисковой строке гугла, то он внезапно откроется без AI-обвеса, суммаризаторов и тд
🔡 small — минимально возможные синтаксически валидные файлы на всех языках (например, в JSON-файлах — минимальное содержимое 0)

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

JS/TS
🔡 природа языка JS такова, что при «кидании» в throw можно бросить не только объект ошибки Error, но и строку, число, объект, и это создаёт проблемы с тем, что и в каком формате ожидать в catch; TypeScript тут особо не помогает, исключения в TS не тайпчекаются, поэтому рекомендуется при обработке исключения проверять его тип


export const parseError = (error: unknown) => {
if (typeof error === 'string') {
return error;
}

if (error instanceof Error) {
return error.message;
}

return 'An error occurred';
};


🔡 если вы приводите строку к дате new Date('2025-05-28') и new Date('2025/05/28'), то результаты могут быть разные: в первом случае браузер воспринимает строку как неполный формат записи даты-времени ISO 8601 и дополняет её на своё усмотрение (так, что может даже открутить часами дату до предыдущего дня, если устройство находится в удачной таймзоне)
🔡 flushSync — метод в React, который позволяет минуя батчинг императивно и синхронно запустить обновление UI в нужный момент, например, чтоб корректно установить фокус в инпут, который только что показался с помощью сеттера из useState
🔡 есть такой тип данных Uint8Array, который как обычный массив, но каждый элемент в нём гарантировано размером 1 байт; так вот, в V8 на больших размерах массивов (> 150) Uint8Array занимает меньше места в памяти, чем обычный массив
🔡 дежурное напоминание: в свойстве firstChild может оказаться не нужный DOM-элемент (тег), а текстовая нода с переносом строки "\n " (зависит от форматирования HTML-кода), поэтому лучше использовать .children[0]

CSS
🔡 у нативного элемента dialog есть браузерный элемент подложки, который стилизуется через ::backdrop, обычно его делают полупрозрачным (и сам он по умолчанию тоже полупрозрачный); так вот, к нему можно при желании применить фоновое изображение, чтобы сделать подложку непрозрачной и модалку перекрывающей нижний слой
🔡 полностью CSS-ный редактор в стиле Майнкрафт:
🔵 все блоки уже заранее построены, но скрыты и показываются благодаря старому трюку с чекбоксами/радиокнопками и соответствующими лейблами
🔵 анимации тоже заранее запущены, но поставлены на паузу, а нажатие контролов (:active) их снимает с паузы

Платформа
🔡 мрачноватый рисунок образа будущего: Chrome превращается в новый IE6, так как Google с одной стороны заставляют его продать, с другой — с приходом LLM поиск, а следом и веб-браузинг как таковой, а следом и процесс развития стандартов существенно меняется
🔡 разработка ПО породила собственную субкультуру с чисто разработческим жаргоном: Yoda Conditions, Stringly Typed, Rubber Ducking, Jenga Code и другие знакомые по разработческим будням явления

@web_platform | Поддержать платформу 🌀
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥11👍73
#Пульс_веб_платформы 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
👍16🔥98
Проблемы во фронтовых проектах и их решения

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

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

Решения:
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
👍10🤮83🥱2👌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
12👍7🔥6