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

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

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

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

Новости
- вышел Vite 5.0: прибрались, дропнули поддержку старых версий Node, задепрекейтили CommonJS-модули, обновили Rollup до 4
- Prettier 3.1 теперь умеет форматировать вложенные тернарники лесенкой
- вышел Firefox 121.0beta и там долгожданная поддержка :has без флага, а также менее долгожданные Lazy loading iframes и поддержка text-wrap: balance, ждём в стабильного релиза в качестве новогоднего подарка 🎁
- вышел redux-toolkit v2.0.0-rc.0, есть breaking changes
- вышел TypeScript 5.3, отличий по сравнению с RC-версией нет
- контрьбьюторам Node не понравилось выпиливание форматирования из ESLint и появилось предложение использовать Biome в качестве форматтера (это же была нативная реклама в PR, да?)
- State of JavaScript 2023 начался: как обычно мне больше всего интересна первая страница с примерами кода, но посмотреть на итоги голосования тоже будет интересно (чтоб узнать, всё ли React или ещё нет)

Проекты
- Loro — либа для реализации offline-first и CRDT-приложений
- React Datasheet Grid — либа для реализации редактируемых таблиц типа Notion и Airtable
- noscript-icons-cli — тулза для генерации SVG-спрайтов (тк использование SVG напрямую в бандлах удобно, но дорого и медленно)
- рекламный лендос возможностей веб-платформы (оч крутой) от разрабов Chrome
- обучалка основам веб-разработки (если у вас спросят, как стать разработчиком, это неплохой свежий гайд на английском)

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

JS
- Explicit Resource Management — изучение новой фичи TS и платформы using, которая может указывать движку, чтоб прибрал подвисшие в памяти процессы
- обзор легковесных JS-фремворков за пределами React-пузыря (да, там тоже есть жизнь)
- как собрать и использовать NPM-пакет вне Node, например, в браузере (олды сразу вспомнят browserify)
- инсайты разработчика аудио-приложения в браузере: интересный тейк — обработку iframe с разными доменами Chromium-браузеры могут выполнять не в основном потоке (такой Prioritized Task Scheduling API из айфреймов и палок)
- оказывается Next.js умеет обрабатывать md-файлы со встроенными React-компонентами (у меня до сих пор к этому подходу есть вопросики, намного лучше выглядит включение веб-компонентов в md)
- никогда не будет лишним прочитать гайд по именованию разных штук в JS-коде
- разные подходы на написания веб-компонентов на примерах: улучшающие код, дополняющие код и генерирующие код

CSS
- качественный гайд по CSS Nesting
- качественный гайд по CSS Grid
- качественный гайд по CSS Container queries
- и всё же, как лучше собирать CSS-файлы: в бандл, отдельными файлами или использовать @import внутри?
- возможности dev-tools для дебага разных CSS-вещей
- и почему же всё таки height в CSS так странно работает (не как width)?
👍32🔥2
#Лаборатория_веб_платформы

URL Pattern API

Это инструмент для сопоставления URL на основе шаблонов. Допустим, есть URL https://example.com/products/123. И нужно сопоставить его с шаблоном https://example.com/products/:id. Это можно сделать так:


const urlPattern = new URLPattern({pathname: '/products/:id'});
const url = new URL('https://example.com/products/123');
console.log(urlPattern.test(url)); // true

Кроме теста соответствия урла шаблону, можно ещё и извлечь соответствующие параметры:


const urlPattern = new URLPattern({pathname: '/products/:id'});
const url = new URL('https://example.com/products/123');
const result = urlPattern.exec(url);
console.log(result.pathname.groups.id); // "123"

Самый очевидный юзкейс URLPattern — клиентский роутер, который проверяет соответствие текущего урла паттерну, по которому показывается нужный контент. Пример в React:


<Router>
<Route path="/">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
<Route path="/messages/:id">
<Messages />
</Route>
</Router>



function Route({ path, children }) {
const baseURL = window.location.origin;
const pattern = new URLPattern({ pathname: path, baseURL });
const match = pattern.test(currentPath);

if (!match) {
return null;
}

return children;
}

Помимо pathname URLPattern умеет определять все остальные части урла: hash, hostname, password, port, protocol, search, username.

Работает пока что только в Chromium, но полифиллится.

---

Поставьте 👾, если нужно записать видос с написанием такого простенького роутера с использованием URLPattern целиком.
👾111👍1
#Пульс_веб_платформы 01.12.2023

Новости
- вышел Git 2.43 (да, такое тоже бывает): появилась возможность лучше прибираться с помощью git repack, клонировать репозитории в режиме tree-less, более гуманные сообщения при повторном revert-е, возможность отмены текущих запусков CI при новых push в CI-ветку и ещё немного ништяков
- в Node v20.10.0 (LTS) забэкпортили некоторые хорошие вещи: к примеру, режим работы с флагами --experimental-default-type, --experimental-wasm-modules и --experimental-websocket
- обновился шрифт Inter до версии 4.0: вариативность, переработанные и новые глифы (есть, в том числе, кириллица), доп OpenType-фичи (и это оперсорс и бесплатно, если что)

Проекты
- опенсорсная десктопная плиложуха для теста API bruno
- requestAnimationFrame как асинхронный итератор для любых сред исполнения JS
- крутое приложение для визуального создания анимаций Rive
- репозиторий для тренировки работы с промисами путём их имплементации

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

JS
- как создать одно приложение с использованием нескольких фреймворков (а точнее как использовать веб-компоненты для уменьшения связности, которую несут JS-фреймворки)
- обзор, как работает Web Push (оказалось, что очень завязанно на браузерных вендоров)
- как добавить немного AI для расшифровки результатов выполнения тестов
- как опубликовать реакт-компонент как ESM+CJS библиотеку с типами, а также два интересных инструмента: Are The Types Wrong? для проверки типов в опубликованной библиотеке и publint для проверки корректности package.json

CSS
- ещё один трюк плавного перехода для height с 0 до auto (tldr, на гридах с 0fr до 1fr)
- много мелких, но приятных CSS-полезностей, которые так и ждут, чтобы их использовали
- hanging-punctuation — или как вынести висящие знаки препинания за пределы строки
- как сделать текст прозрачным внутри (с помощью небольшой -webkit-магии)
- как вытащить элемент из stacking context-а без задания ему transform, filter или opacity
- лок скролла с помощью overscroll-behavior

HTML
- пора ли уже переходить на формат изображений AVIF? Если сжимаете картинки сильно, и не нужна поддержка в Edge — да!
- бургер-менюшка без JS на Popover API
- пост для фронтендеров «кому за…» со сборником ностальгических хаков (даже есть упоминание спеки JSSS, которая однажды проиграла в браузерных войнах, и где мы сейчас?)
- красивая статья-размышление о многомерном пространстве в сайтах
🔥4👍1
#Пульс_веб_платформы 08.12.2023

Новости
- вышел Electron 28.0.0: добавлена поддержка ES-модулей и там всё оч интересно: главный процесс Electron-а запускается в ноде и соответственно использует имплементацию ESM ноды, а рендерится всё в хромиуме и там уже другая имплементация, Electron выбирает, как быть, в зависимости от контекста
- вышла библиотека StyleX от фб: из плюсов — типизация, генерация в билд-тайме, из минусов — непонятно зачем это нужно сейчас кому-то, кроме фб
- Remix запланировал реализацию React Server Components (видимо, вынужденно)
- вышел Vitest v1.0.0: кажется уже устаканилось настолько, чтобы внедрять (1.0.0 внушает доверие)
- вышел новый HTML5 Boilerplate (да, это не шутка! внимание, может вызвать ностальгические чувства)

Проекты
- как вам стейт-менеджер веб-приложений в виде SQL-бд (чудны дела твои, эволюция)? такое есть в SQLSync (а для выборки из стора можно пользовать SQL, yay)
- симпатичная либа компонентов на тейлвинде floatui (проект настолько свежий, что не успели ещё поправить ридми)
- tsdiagram сгенерит для вас на лету красивую диаграмму из хитросплетений типов
- just another либа для манипуляций с цветом culori
- тул для сбора перфоманс-метрик (в том числе Web Vitals) на пользовательских устройствах и отсыла их обратно через google-аналитику либо другие аналитические тулы (главное чтобы браузеры не блочили аналитические тулы)

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

JS
- как улучшить перфоманс-метрику INP: предсказуемые способы разгрузить основной поток setTimeout, requestAnimationFrame, requestIdleCallback, а также неведомый scheduler.yield()
- как плохой INP может уронить бизнес-метрики
- ещё одна попытка заинтересовать в веб-компонентах: в них можно бесплатно инкапсулировать логику, есть встроенные колбеки на добавление и удаление из DOM-а и изменение «пропсов»
- как заменить npm, yarn и nvm на pnpm (правда не очень понятно зачем)
- сборник рецептов для Puppeteer (от простого волшебства к сложным заклинаниям)
- как сделать скриншот фрагмента страницы с помощью Playwright
- old but gold: что такое и с чем едят JavaScript Import maps
- паттерны проектирования реакт-компонентов: as и asChild (is this a полиморфизм?)
- история того, как в JS появилось именно такое ООП, какое есть сейчас (читать с кофе, в кресле, укрывшись пледом)
- реактивный JS-фреймворк на коленке, откуда можно узнать: юзкейс для Proxy, незаслуженно неизвестное API queueMicrotask, ликбез по tagged template literals
- хитрая магия, чтобы делать «подтипы» в TS (после использования сжечь проект!)

CSS
- тулза для генерации CSS для подключения шрифтов
- дешёвый и сердитый способ сделать инпут для one-time-пароля (без JS!)

HTML
- примеры классного дизайна… URL (от stackoverflow, slack, github, npm и unpkg)
🔥3👍1👏1
Веб-платформа
#Пульс_веб_платформы Фреймворки фремворками, а махина CSS медленно, но верно движется вперёд. Вчера были опубликованы две новых версии черновиков CSS Box Alignment Module Level 3 и CSS Positioned Layout Module Level 3. В Position 3 с прошлой публикации:…
#Пульс_веб_платформы

Финально в этом году обновился CSS Snapshot 2023! 🥁

В финальной редакции спека CSS View Transitions Module Level 1 перешла в FairlyStable-раздел. Это значит, что основная работа над спекой завершена и полученный результат довольно стабилен.

Поддержка View Transitions API пока что есть только в Хромиуме. Но вангую, что переход спеки в стабильный раздел должен дать сигнал в Мозиллу и Эпл, чтобы поддержка побыстрее появилась и в Firefox с Safari. Ждём в 2024. 🤞
👍2
#Пульс_веб_платформы 15.12.2023

Новости
- вышел Safari 17.2, много мелких и классных обновлений в уходящий год, чтобы подбить статистику Interop 2023: аккордеон на <details> + <summary>, onetimecode для инпутов, «расслабленный» CSS-nesting, обновления CSS Motion Path, функция linear() для создания «нелинейных» анимаций, математические функции rem(), mod(), round() в CSS, display: list-item, mask-border без префиксов, Custom Highlights API, <link rel="preload"> с атрибутами imagesrcset и imagesizes для подгрузки адаптивных изображений, import attributes в JS, fetchpriority для загрузки ресурсов, улучшение нативной валидации форм и ещё много других плюшек
- анонсирован выход Million 3.0 — альтернативного VDOM для Реакта (подробно о его работе): вкратце, он берёт для реконсиляции только динамически заполняемые DOM-ноды, а на статические не обращает внимания, а затем сравнивает не сами DOM-ноды, а их состояние (что существенно быстрее); годится для случаев, когда в приложении не слишком много динамических кусков, и часть приложения в ходе работы остаётся неизменной (значит её не нужно учитывать в пересчёте)
- вышел SVGO v3.1.0, улучшено всё, без маркетиноговых уловок сообщаю, что это просто классный проект, cli-тулза для чистки SVG от мусора
- Storybook с 8.0 версии будет поддерживать React Server Components: минус — Next.js съест и Storybook, плюс — Storybook не будет медленно рендериться на клиенте

Проекты
- Primer React — библиотека Реакт-компонентов Гитхаба: круто, что такие проекты выкладываются в opensource, поэтому можно почитать исходники: из интересного, у них используются styled-components и чтобы компоненты писать вот так красиво <Header.Item> делается Object.assign(Header, {Link: HeaderLink, Item: HeaderItem}) (реф)
- eruda — эмулятор браузерной консоли и девтулзов для мобильных браузеров
- Fuse.js — фреймворк для создания типобезопасного слоя данных между бэком и фронтом, работает поверх Ноды и gql
- простой и честный респонсив компонент пагинации для Реакта — React Responsive Pagination
- GQL (Git Query Language) — а как вам такое: можно делать выборки по истории гита с помощью SQL!
- enhance — HTML-first full-stack веб-фреймворк на веб-компонентах, выглядит очень симпатично, так и тянутся руки глотнуть свежего воздуха

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

JS
- интересная детективная история, которая начинается с того, что при изменении содержимого инпута курсор переносится в конец строки, а заканчивается кишками событийной модели Реакта и методом flushSync
- статья о том, чем isNaN отличается от Number.isNaN(), а также почему typeof NaN это 'number'
- как устроен React Suspense: tldr, Реакт под капотом использует новый компонент Offscreen, который как бы есть, но его как бы нет, то есть туда можно заблаговременно рендерить контент, но его не будет сразу видно (он условно скрыт style="display: none !important;")
- подборка текущих актуальных стейт-менеджеров: построенные на редьюсинге, атомах либо мутации, а также их плюсы, минусы и подводные камни (хотя в 90% случаев можно было бы обойтись простой useReducer + контекст)
- хитрости в работе с Реактом от автора Wouter: патчим компоненты с cloneElement; useState, который никогда не обновляется const [value] = useState(() => { /* initializer */ }); неизменная ссылка на функцию с помощью useEvent и кое-что ещё
- статья от Дэна Абрамова от том, как обрабатывается JSX (feels like мемуары о тех временах, когда деревья были большие и зелёные, а рендеринг был только клиентский)
- супер-гигантская и супер-полезная статья про всё, что вам может понадобиться при работе с IndexedDB
- использование кастомных Server-Timing HTTP-заголовков
6👍2🔥2
Веб-платформа
#Пульс_веб_платформы 15.12.2023 Новости - вышел Safari 17.2, много мелких и классных обновлений в уходящий год, чтобы подбить статистику Interop 2023: аккордеон на <details> + <summary>, onetimecode для инпутов, «расслабленный» CSS-nesting, обновления CSS…
Продолжение

CSS
- кодим SVG-спиннер голыми руками без сторонней помощи (и без страховки)
- что из CSS зарелизилось в браузерах в 2023 (огромное количество класных фич, на 2024 уже даже столько интересного не осталось): тригонометрические функции, микросинтаксис селекторов An+B, scope, nesting, subgrid, initial-letter, text-wrap, color-mix(), relative color syntax, @container и @container style(), :has(), новые возможности медиа-выражений, View Transitions API, linear(), событие scrollend, скролл-анимации с ViewTimeline, анимация дискретных свойств типа display: none, @starting-style, Popover API, <hr> в <select>, псевдоклассы :user-valid и :user-invalid, аккордеон на <details>
- минималистическая сборка CSS с помощью Lightning CSS (немного свело олдскулы)
- будущие нативные функции и миксины в CSS
- SVG-адвент-календарь

HTML
- использование респонсив <video> (аля <picture>) теперь кроссбраузерно (а также зачем-то респонсив <audio>)
- инспекция дерева доступности страницы теперь доступно в Хроме

Платформа
- разбор HTTP/2 по байтам: очень дотошно, душно и исчерпывающе
- исследование Яндекса о частоте использования тех или иных фич доступности на смартфонах: оказывается очень много людей используют системное увеличение шрифта и тёмную тему
- подготовка к мониторингу метрики INP: в целом, рекомендации те же — не допускать долгих блокирующих тасок всеми возможными способами
5👍2🔥2
#Пульс_веб_платформы

Короч, FF 121 вышел, селектор :has() доехал везде, теперь можно! 💫


<body>
<div class="one"></div>
<div class="two"></div>
</body>



.one {
background-color: green;
}

.two {
background-color: orange;
}

body:has(.two:hover) .one {
background-color: red;
}


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

Новости
- появился новый линтер oxlint: написан на Rust; можно не настраивать (convention over configuration); плагинов пока нет, но обещают, что можно будет писать их без использования JS или Rust; быстр, но в том числе потому что проверяемых правил мало
- вышел SvelteKit 2: Vite 5 под капотом, подготовка к будущему Svelte 5, shallow routing; tldr: Svetle продолжает прорастать в экосистему
- Vue 2 станет deprecated 31 декабря 2023
- вышел Firefox 121: главное поддержан :has()!
- вышла библиотека date-fns v3: теперь 100% типизирована, уменьшен размер бандла, функции экспортируются через named exports и кое-что ещё
- обновился Tailwind CSS v3.4: динамические viewport units, поддержка :has(), text-wrap: balance, субгриды и многое другое

Проекты
- waku — минималистичный React-фреймворк с поддержкой ServerComponents: включает клиент, сервер и роутер
- constate: библиотека для решения проблемы плодящихся контекстов в Реакте
- simple-web-server: простая декстопная аппка для настройки и запуска дев-сервера

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

JS
- список всех известных (и неизвестных) JS рантаймов и движков на все случаи жизни (даже чтобы выполнять JS в с/с++)
- если промис ушёл и не вернулся, он попал в чёрную дыру: чтобы это исправить нужно отказаться от асинхронных функций в угоду генераторов
- профилируя приложение для локализации автор пришёл к тому, что node --prof и инструмент speedscope — хорошая отправная точка для анализа перфоманса
- члены tc39 устали отвечать на одни и те же вопросы в ишью, и создали faq, в котором можно узнать, почему JSX не появится в ES, почему JSON никогда не поменяется, а также почему числа в JS такие странные
- в конкурсе на самый быстрый способ проброса состояния с сервера на клиент победил <noscript type="mime/invalid" id="myState">{"foo":"bar"}</noscript> window.__STATE__ = JSON.parse(window.myState.innerHTML)
- темы для холиваров в вашей команде, если вы работатете с Реактом: как писать экспорты, как называть файлы и пропсы, нужны ли стрелочные функции, а также тернарники vs early return
- TS-фичи «следующего» уровня: satisfies, infer, exhaustive type checking
- эволюция синхронного рекурсивного обхода папок в ноде достигла вершины — await fs.readdir(dir, { recursive: true })
- всё про Unicode для разработчиков: символы, их объединение, эскейп в JS, сравнение строк и регекспы

CSS
- смена стилей в зависимости от количества элементов с помощью element:has(> :nth-child(10))
- лок скролла из глубины DOM-а с помощью body:has(.lock-scroll) { overflow: hidden} <dialog class="lock-scroll">
- четыре способа создать анимированные градиентные рамки
- свойство animation-composition, позволяет начать анимацию с нуля либо с того значения свойства, которое уже задано на момент начала анимации (удивительно, но поддерживается везде!)

HTML
- в каких случаях подходит использование <link rel=preconnect>
- при использовании атрибута sizes="auto" у img нужно указывать также width и height
- создание шумной текстуры в SVG (секрет в применении SVG-фильтров)
- древнее знание: атрибут form у кнопки позволяет сабмитить форму, даже если кнопка снаружи неё
👍4🔥2
#Лаборатория_веб_платформы

Таймер без фриза с помощью Web Worker

Если в JS запустить таймер с помощью setInterval, который срабатывает довольно часто, например, раз в 100мс, а затем уйти из таба на некоторое время, то окажется, что браузер остановит таймер на время «неактивности» таба. «Фриз» таймера в неактивном табе можно посмотреть тут https://codesandbox.io/p/sandbox/dreamy-bartik-vkkmjr.

Это не баг, а фича: с целью экономии ресурсов браузеры троттлят фоновую активность тех табов, которые сейчас не открыты.

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

Вот пример таймера в отдельном файле воркера, к примеру, timerWorker.ts :



let timerId: number | null = null;

self.onmessage = (event: MessageEvent) => {
const { data } = event;

switch (data) {
case "start":
timerId = self.setInterval(() => {
self.postMessage("tick");
}, 100);
break;
case "stop":
if (timerId) {
clearInterval(timerId);
timerId = null;
}
break;
}
};


В воркере нет объекта window, но есть self, местный аналог https://developer.mozilla.org/en-US/docs/Web/API/WorkerGlobalScope/self. С основным приложением воркер общается с помощью команды postMessage. При этом из приложения также можно дёргать postMessage воркера и подписываться на событие onmessage:



function App() {
const [time, setTime] = useState<number>(0);
const workerRef = useRef<Worker | null>(null);

useEffect(() => {
workerRef.current = new Worker("/timerWorker.ts");

workerRef.current.postMessage("start");

workerRef.current.onmessage = (event) => {
if (event.data === "tick") {
setTime((prevTime) => prevTime + 1);
}
};

return () => {
workerRef.current?.postMessage("stop");
};
}, []);

return <div>{time}</div>;
}


В воркере, к сожалению, нет доступа к DOM-у, но зато доступны разные API, например, Fetch или Canvas, так что выгружать в воркер что-то тяжёлое или важное — вполне себе рабочая тема, о которой не стоит забывать.
👍81
#Пульс_веб_платформы 05.01.2024

Новости
- вышел TenStack Router — полностью типизированный (не только на TS, но и сами роуты защищены от ошибок типами) роутер от известного в узких кругах разработчика
- подведены итоги 2023 года в экосистеме JS по версии Rising Stars: победители — shadcn/ui, Bun и Excalidraw

Проекты
- refractror — хайлайтер синтаксиса, основанный на Prism, но отдающий на выходе не строку HTML, а объекты AST
- observable-membrane — создание обсервабл-объектов на основе Proxy
- tokenami — ещё одна CSS-in-JS либа на Тейлвинде + custom properties, типизация из коробки
- catalyst — первая демка UI-кита для Реакта на Тейлвинде, от создателей Тейлвинда
- devicenoscript — среда в VS Code, эмулятор и компилятор TS для программирования IoT-девайсов, контроллеров и прочего хардверного стафа
- оживление текста анимациями «ручных» обводок и подчёркиваний

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

JS
- оказывается цикл forEach всё таки можно остановить (но вряд ли нужно) с помощью throw внутри try с переходом в catch
- в каких случаях нужен flushSync в Реакте: по умолчанию изменения UI батчатся и затем применяются асинхронно, что не всегда подходит (Реакт иногда обновляет UI позже, чем нужно); если нужно гарантировано обновить UI «здесь и сейчас», то flushSync — подходящй инструмент (например, чтобы корректно установить фокус или позицию скролла)
- гайд по паттернам проектирования в JS с простыми примерами
- все JS и TS фичи за последние 3 года: чтиво на ночь для лёгкого засыпания либо для постновогоднего рефлексивного настроения
- кодогенерация и парсинг TS с помощью TS (конкурс на лучший юзкейс объявляется открытым!)
- если для работы с датами не хочется тащить библиотеку, то можно воспользоваться встроенным Intl.DateTimeFormat, который довольно много умеет сам по себе

CSS
- свойство align-content выравнивает элементы не только внутри флексбокса, но также и display: table-cell и list-item
- как происходит загрузка «невидимых» картинок: картинки без loading="lazy" грузятся всегда (даже в скрытом виде), а вот с loading="lazy" грузятся внутри visibility: hidden и не грузятся внутри display: none или <details>
- как выполнить невозможное calc(100vw / 5px) с помощью тригонометрических функций

HTML, SVG
- интерактивный гайд по path (залипательный)

База
- абсолютный минимум о Unicode, который должен знать каждый уважающий себя разработчик в 2023 (и 2024, всё ещё никаких отговорок!)
- сложность алгоритмов. Разбор Big O: для освежения в памяти после новогодних каникул
👍7🔥4👨‍💻1
Телеграм-перестрелка с каналом Евгения Черкасова «Записки тимлида»

Евгений ведёт свой блог давно и по истории канала видно, что он прошёл путь от «фронтенд бати» к роли тимлида в большой компании (вот саммари). Я люблю изучать такие истории людей: в них можно найти что-то близкое по душе или почерпнуть что-то новое из житейской мудрости.

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

2. Сейчас канал Евгения — это рефлексия о жизни и работе, но разработческие и фронтовые темы тоже иногда проскакивают. Например, за ссыль на conventional commits моё увожение (там есть ещё пара постов про коммит-мессаджи, 1 и 2). Или вот напоминашка про свежие единицы измерения в CSS. Из найденных тимлидовых интересностей и жизненных тем: пост про небольшие изменения, к которым люди постепенно привыкают, пост про обнуление бэклога и годный пост про размытие коллективной ответственности. Также есть душевные истории из жизни: про первого ученика или про балет.

3. Что не понравилось.

Картинки к постам, сгенерённые нейросетками. Это смотрелось прикольно месяц-другой, когда только появилось. Но теперь смотрится унылыми заглушками и дальше будет смотреться ещё хуже. Евгений, нужно больше аутентичности в победившем пластмассовом мире!

«Блогеские» темы и призывы к действиям. Налейтай, подпишись, бусты, лайки. Это уже и так везде и всюду, кажется, что это уже не работает, надо по-другому (см предыдущий тейк про аутентичность).

4. Самое ценное, что есть в постах Евгения — его жизненный опыт и живой взгляд на мир. Хочется пожелать ему писать больше годноты в эту сторону, так как чувствуется, что ему есть что сказать. И не терять жизненность историй, это располагает к доверию ❤️

В общем, рекомендую подписаться на @frontend_lead_mentor. А я пойду почитаю разнос разбор моего канала у Евгения 😅
3
#Лаборатория_веб_платформы

Proxy и мемоизация функции

Есть такая платформенная штука — Proxy. Это когда берёшь обычный объект в JS, создаёшь для него прокси и получаешь возможность перехватывать и переопределять основные операции, которые с объектом можно совершить: get, set, delete… Внутри перехватчиков можно, например, логировать, валидировать или дополнять значения. Например:




const target = {
message1: "hello",
message2: "everyone",
};

const handler = {
get(target, prop, receiver) {
console.log(`Свойство ${prop} считалось`);
return target[prop];
},
set(target, prop, value) {
console.log(`Свойству ${prop} задано значение ${value}`);
target[prop] = value;
return true;
},
};

const proxiedObj = new Proxy(target, handler);

proxiedObj.message1
// log: Свойство message1 считалось

proxiedObj.message2 = 'nobody'
// log: Свойству message2 задано значение nobody


Так вот, проксировать можно не только объекты, но и функции. В случае функций через прокси можно перехватывать момент вызова функции (перехватчик apply) и, например, манипулировать аргументами до вызова.




const a = () => {
// функция
}

const b = new Proxy(a, {
apply: (target, thisArg, argumentsList) => {
// перехватчик вызова
}
})


До вызова функции мы получаем референс на саму функцию, контекст и массив агрументов и можем с ними делать что угодно перед тем, как непосредственно вызвать (или даже не вызвать) функцию. К примеру, можно организовать кэш, чтобы по переданному набору аргументов запомнить вычисленное значение и при повторном вызове брать его из кэша.




function memoize(target) {
const cache = new Map();

return new Proxy(target, {
apply: (target, thisArg, argumentsList) => {
const key = JSON.stringify(argumentsList);
if (cache.has(key)) {
console.log(
`Результат для ${argumentsList} взят из кэша`,
);
return cache.get(key);
} else {
const result = target.apply(thisArg, argumentsList);
cache.set(key, result);
return result;
}
},
});

const add = (a, b) => a + b;
const memoizedAdd = memoize(add);

memoizedAdd(3, 7); // Вычисляет и записывает в кэш
memoizedAdd(3, 7); // Берёт результат из кэша
}


Аргументами функции, то есть и ключами в кэше могут быть не только примитивы, но и объекты, за счёт того, что ключ формируется с помощью JSON.stringify.

Таким образом, с помощью Proxy можно на коленке собрать «мидлвари» для объектов, массивов и функций, в общем-то, с любыми целями.
👍9🔥7
#Пульс_веб_платформы 12.01.2024

Новости
- вышел Vue 3.4: переписан парсер шаблонов на htmlparser2 (стало 2x быстрее), улучшена система реактивности и добавлен шортхэнд для дублирующих значений атрибутов (<img :id="id" :src="src" :alt="alt"> 👉 <img :id :src :alt>)
- круг замкнулся: в Remix появится классический SPA-режим работы, с возможностью опционально включить SSR (сейчас в Remix приложениях вся загрузка данных происходит на сервере)
- в Chrome начали выпиливать сторонние (3-party) куки (у 1% пользователей)
- в React появятся API для прелоадинга ресурсов: preload, preconnect и другие

Проекты
- PWA-приложение, показывающее все возможности PWA-приложений
- zed — быстрый мультиплеерный редактор кода (почему, зачем, за что?)
- fontsource — опенсорсные шрифты в npm-пакете (для установки шрифтов как контроллируемых зависимостей вместо гугл-фонтс)
- fsx — либа для работы с файловой системой в ноде, дено и памяти (в том числе браузерах) от создателя eslint

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

JS
- напоминание, что во всех браузерах доступны немутирующие аналоги reverse(), splice(), sort() – toReversed(), toSplice(), toSorted() и with()
- в JS-движке JavaScriptCore (в Safari), в отличие от V8 (в Chrome) реализован механизм оптимизации хвостовой рекурсии (Tail Call Optimization), позволяющий вызывать рекурсивно функцию сколько угодно раз без переполнения стека и код можно сделать таким же быстрым, как и в цикле for
- разбор классических «странностей JS»: 0.2 + 0.1 = 0.300000001., преобразование типов, автодобавление ;
- история, как создали npm-пакет everything, который включает ВСЕ пакеты npm, включая себя; из-за политики, что нельзя снять с публикации пакет, от которого зависит любой другой пакет, стало невозможно убрать из npm ВСЕ пакеты
- туториал по стейт-менеджеру Jotai, состоящему из атомов
- в Next.js теперь можно будет запускать проект на https локально с помощью next dev --experimental-https
- здравый смысл восторжествовал и в Next.js не будут больше патчить fetch
- document.getAnimations() возвращает в виде промисов все текущие CSS-анимации
- анатомия shadcn/ui: безголовые компоненты с отдельным слоем стилей, для установки разных состояний используется cva
- гайд по микрофронтендам на single-spa: такие штуки кажутся с первого взгляда сложными, но стоит попасть в ситуацию больших проектов, когда нужно шарить данные между разными приложениями, и уже становится понятно, зачем вся эта сложность
- чтоб не заморачиваться с выводом типа события TS в React, можно воспользоваться общим «доставатором» типа React.ComponentProps<"input">["onChange"]
- особенности использования enum в TS: например, const enum Name {} полностью удалит этот фрагмент из скомпилированного кода, но есть нюансы

CSS
- гайд по container queries (с живыми примерами)
- как написать круглый индикатор прогресса со скролл-анимацией
- в Chome 120 появилось @media (noscripting: none) для определения выключенных скриптов
- директива @property: создание, дебаг, юзкейсы
- кликабельную область вокруг интерактивных элементов лучше увеличить (удобно для мобилок), как это лучше сделать
- трюки и находки при создании нового сайта vercel: SVG-лучи, пиксельные логотипы на гридах, CSS-счётчики, круговая анимация

HTML, SVG
- топ-10 ошибок в доступности на сайтах в 2023: пустые ссылки, некорректный tabindex, отсутствие alt и другое

Платформа
- победители в народном голосовании за фичи в Interop 2024: JPEG XL image format, View Transitions Level 1, Scroll-driven Animations
9🔥5👍3
#Фикшн_веб_платформы

Сейчас уже нет Настоящего Айкидо. В наше время айкидо называется, когда два чудака лупят друг друга пятками в челюсть или ломают друг другу суставы, или не знаю, чем они там ещё занимаются, не видел никогда.

А Настоящее Айкидо — оно было совсем другое. Оно заключалось в том, чтобы победить Неприятеля так, чтобы самому не сильно напрягаться. Для этого даже не обязательно с этим Неприятелем встречаться.


Вот скажем принесли вам в разработку макеты с Неведомой Фичей. Как её сделать — хз, нет понимания.

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

Вроде бы вы и победили, но гаденько как-то, нет этого приятного ощущения, ради которого вы когда-то давно вообще этим всем начали заниматься. Это не Настоящее Айкидо.

Либо же вы ищете похожую задачу на Стэковерфлоу или спрашиваете у Чат-бота. И таким образом вы находите «Либу, которая решит все ваши проблемы». Правда помимо вашей задачи она решает ещё и парочку других проблем по пути, ну и тянет набор зависимостей на 500кб. Но это ладно, думаете вы, фичу-то надо сделать ещё вчера. «Ок, для временного решения сойдёт», — решаете вы и используете либу.

А потом, спустя год-другой нужно вам зависимости проекта обновить и вы находите эту либу, вспоминаете что к чему, хотите версию этой либы заодно поднять. Но либа уже заброшена владельцем и вообще новым Реактом не поддерживается. «Что поделать, надо выпиливать», — думаете вы и снова оказываетесь в самом начале.

Это не победа, Неприятель вас обхитрил, притворился побеждённым и вам снова нужно с ним сражаться. Это тоже не путь Настоящего Айкидо.

А как бы поступил Мастер Настоящего Айкидо? Он бы сел, подумал и вспомнил, что Браузер, для которого он пишет программу, уже и сам умеет в нужную фичу. И вот Мастер на митинге скажет «Это умеет Платформа», а потом возьмёт и напишет несколько строк кода, чтобы дёрнуть нужный браузерный API, закроет задачу и пойдёт пить чай. И его решение никогда не протухнет, ведь Платформа всегда обратно совместима.

Мастер Настоящего Айкидо прилагает большего всего сил, чтобы освоить базу, и затем стремится к применению усвоенных принципов. А когда ему приходит мысль, что ему всё ясно, то он говорит себе: «Этого недостаточно», и идёт дальше копать Базу. 🥷
👍7🔥7🤡4😐21🤔1
#Пульс_веб_платформы 19.01.2024

Новости
- в Safari TP 186 допиливают @scope, добавили align-content для табличных ячеек и сделали анимируемым свойство content-visibility
- обновилась Node v20.11.0 (LTS): появились esm import.meta.dirname и import.meta.filename на замену CommonJS __filename и __dirname
- вышел Prettier 3.2: поддержан формат файлов jsonc (если вы, также как и я не знали, что это такое, — это творение Microsoft, json с комментами // и /**/)
- вышел Next.js 14.1 — ускорен стартап и Turbopack, улучшен вывод ошибок, добавлена поддержка нативных window.history.pushState и window.history.replaceState, логирование использования кэша, расширены возможности работы с картинками
- в TS 5.4 появится новый тип NoInfer<T>, чтобы блокировать инфер пришедшего типа

Проекты
- The AHA Stack — всем панкрок! или Astro, htmx и Alpine.js объединились в банду, шатают SPA-мир и хотят вернуть веб-разработке простые ментальные модели и воркфлоу (интересно, доколе ещё ждать наступления прекрасного будущего?!)
- remote-storage — localStorage с сохранением на удалённый сервер (даже бесплатный, чтобы вы туда насохраняли инфы, а потом душили жабку за подписку, которая вскоре появится)
- templ — серверный рендеринг HTML на Go (внутри можно редерить и React-компоненты)
- worker-timers — таймеры, которые не фризятся при неактивном окне за счёт выноса в worker
- dep-tree — 3d визуализация внутренних связей проекта
- symbiotejs — а что если вы завтра проснётесь и React окажется дурным сном, а все приложения вокруг будут написаны близко к нативным API, без прятания за абстракциями и «магических ящиков»

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

JS
- новомодные написанные на Rust линтеры (oxlint, biome…) быстры в том числе потому, что не интегрированы с TS type checking API, которое, увы, довольно медленное, но зато фичёвое
- ещё одно напоминание, что в Google Chrome во второй половине 2024 будут отключены сторонние (3d-party) куки, что поломает Google же Analytics, Google Pixel, инструменты ретаргетинга…, но в целом останутся ещё другие безкукисовые инструменты, чтобы показать вам баннер с рекламой кредитной карты — опыт команды Sentry
- React Server Components не требует наличия сервера или Анонс курса Дэна Абрамова «Нейминг от бога» (а Astro, кстати, требует)
- с помощью Clipboad API можно копипастить не только текст, но и картинки в PNG, гайд как это сделать на React
- как с помощью современных JS-рантаймов (bun, deno, node) собрать самодостаточный выполняемый файл
- золотое правило написания тестов: «Тест должен не проходить, тогда и только тогда, когда цель системы не выполнена.», то есть в тесте не стоит вдаваться в детали имплементации, а сфокусировать один тест только на одной цели
- сравнение либ типизированной проверки данных: Zod vs Valibot
- querySelector отличается от getElementById тем, что не признаёт id начинающиеся с цифры

CSS
- набор молодого интернационалиста: margin-inline, dir, :lang() и writing-mode
- на что способно свойство border-image: полупрозрачный фейд, скошенный фон на весь экран, градиентные бордеры
- ещё один способ центровки контента без обёртки — max-width: max-content; margin-inline: auto
- юзкейсы скролл-анимации с помощью animation-timeline (пока только в Chrome)
- способы описания кастомных easing-функций в JS для Web Animations API: предвычисление массива keyframes, новая функция linear(), а также предложение добавить встроенную функцию document.registerTimingFunction

HTML
- чтобы убрать элемент от показа в описании сайта в гугл-поиске нужно добавить тегу атрибут data-nosnippet

Платформа
- прошедший год у npm: 184 миллиарда скачиваний пакетов в месяц; март самый активный месяц по публикации версий пакетов; топ зависимостей — TS, react, eslint, @types/node, react-dom, jest, prettier; самое длинное возможное название пакета из 214 символов
- как выводить в консоль браузера анимированные 3D-SVG картинки и стилизованный текст, а также бонусом либа для определения открытости консоли и факт, что console.table(['foo']) растягивается на всю ширину консоли
🔥4👍21👏1
#Лаборатория_веб_платформы

Окей, когда что-то нужно перестроить в интерфейсе при изменении разрешения экрана, используется media query в CSS.

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

Первая мысль, как поступить в этой ситуации — подписаться на resize окна и смотреть в хендлере, нужная сейчас ширина окна или нет.



function handleResize() {
if (window.innerWidth >= width) {
// setIsGreaterThanOrEqual whatever
}
}

window.addEventListener('resize', handleResize);


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

Триггерить только срабатывание определённого условия ширины можно… теми же mediaQuery, только в JS. Для этого существет API window.matchMedia https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia, который принимает строку с медиавыражением и возвращает объект MediaQueryList, содержащий информацию о медиавыражении, применённом к документу.



const matchQueryList = window.matchMedia("(max-width: 600px)")


Для разовой проверки соответствия используется свойство matches:



matchQueryList.matches // true or false


А для постоянного отслеживания соответствия, есть подписка на событие change:



function handleChange(e) {
// e.matches whatever
}

matchQueryList.addEventListener("change", handleChange)


Для Реакта всё это заворачивается в хук и получается удобное отслеживание медиавыражений в JS:



function App() {
const isMobile = useMatchMedia("(max-width: 768px)");

return <h1>Browsing with {isMobile ? "mobile" : "desktop"}</h1>;
}


Код тут https://codesandbox.io/p/devbox/frosty-mcclintock-93ghzg
🔥11👍8
#Пульс_веб_платформы 26.01.2024

Новости
- состоялось заседание рабочей группы по веб-компонентам W3C, результаты: Declarative Shadow DOM появится в Firefox 123 в конце февраля (эта фича, позволяющая использовать Shadow DOM напрямую в HTML без вызова attachShadow() из JS); начнёт разрабатываться Scoped Element Registries, позволяющий создавать элементы с одинаковым именем в рамках одной страницы; Container Style Queries быть во всех движках в ближайшем будущем 🎉
- грядущие нововведения в «клиентском» Реакте: use(Promise) — саспендинг на клиенте; use(Context) — такой же, как useContext, но можно вызывать в условиях; хуки и апи для работы с формами Form Actions, useFormState, useFormStatus; а также useOptimistic — специальный хук, чтобы смотреть на «классический» Реакт с оптимизмом
- обновления в Chrome 121: появились свойства scrollbar-color и scrollbar-width (раньше работало только в FF, так что если у вас были стили только для FF в Хроме тоже внезапно включится!); font-palette для управления цветовыми шрифтами; псевдоэлементы ::spelling-error и ::grammar-error для стилизации ошибок; Speculation Rules API для программного префетча и пререндера страниц в классических MPA; showPicker() для программного выпадения <select> (кажется, я когда-то ждал этого, но так давно, что уже забыл)
- вышел Safari 17.3: пофикшен @supports и цвет каретки на iOS, закольцовывание медиа с нулевой длиной и другие мелочи

Проекты
- bun shell — возможность запускать shell-скрипты в JS (с помощью и во славу Bun)
- workerpool — централизованный способ выгрузить воркеры (если у вас их много разных) в отдельный пул с очередью выполнения
- partytown — запуск 3d-party скриптов в воркере (для выгрузки Google Tag Manager, Google Analytics, Amplitude из основного потока)

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

JS
- как отделить 0 от null и undefined: напоминание про разницу операторов || и ??
- c AbortController.abort() удаляет разом несколько обработчиков событий (не нужно писать множество removeListener, yay!)
- если вы захотите обновиться на 18 Реакт, возможно вам тоже придётся сделать что-то из того, что уже сделали в команде SonarQube
- Реакт-стартеры в 2024: Vite, Next или Astro?
- возможная замена проп-дриллингу — {children}
- туториал по Next.js App Router от мейнтейнера Node.js и webpack: минималистично и интерактивно
- как уменьшить размер бандла — рецепты с разных сторон: мониторинг через Lighhouse, Sentry; анализ с помощью Webpack Bundle Analyzer, Statoscope, bundlephobia; распространённые приёмы — отключить сорсмапы, оптимизировать импорты библиотек типа lodash, выделение чанков, динамические импорты и фреймворкоспецифичные подходы типа React.lazy

CSS
- частичный фейд текста с помощью градиентов (именно текста, а не покрывающий слой!): способы с mask-image и background-clip: text
- сборник мелких, точных (и злых) «CSS-однострочников», которые уже можно заносить в проекты (и за это не придётся оправдываться): aspect-ratio, object-fit, margin-inline, text-underline-offset…
- ещё одна подборка юзкесов селектора :has(): делаем выборку родителя, предыдущего сиблинга, по количеству элементов, в любом месте или всё, кроме меня
- в догонку к предыдущему пункту демка с плавным переходом между радио-кнопками, которая стала возможна в CSS благодаря :has()
- в 123 Chrome появится свойство field-sizing, авторасширяющее инпуты и текстареа при вводе длинного текста (неужели это когда-нибудь свершится, боже)

HTML,
SVG
- эффект движущейся линии по скроллу на SVG элементах <linearGradient>, <path> и <clip-path>
- чтобы улучшить метрику CLS достаточно просто один раз в день… задавать размеры <img> в атрибутах width и height (и без px)
- aria-hidden в жизни: для сокрытия визуальных декоративных элементов, скрывает интерактивные элементы не всегда, aria-hidden !== aria-hidden="true"

Платформа
- рецепты как выключить браузерное кеширование в серверных заголовках, HTML, htaccess, PHP и других бэкендах
- каталог известных (и не очень) дизайн-систем на случай, если вам понадобится впечатлить коллег проведённым обширным ресёрчем
🔥83