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

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

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

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

Новости
- из MS Edge будут выпилилены свойства -ms-high-contrast media и -ms-high-contrast-adjust в угоду стандартным медиа-фичам forced-colors и prefers-color-scheme, а также свойству forced-color-adjust
- вышел React v18.3.0: добавились ворнинги на задепрекейченые фичи в React и React DOM
- анонсирован GitHub Copilot Workspace: (утопичная) идея сделать некую среду, в которой можно будет на натуральном языке планировать, обсуждать, писать, отлаживать и тестировать программы
- у Bun вышло обновление с новым crash reporter-ом, из интересного: идея в один 150-байтный URL запихнуть платформу, хэш коммита, стэк трейсы, сообщение и тип ошибки: малочитаемо, но зато очень коротко
- вышел TypeScript 5.5 Beta: TS научился выводить тайпгарды самостоятельно, появился импорт типов JSDoc в js-файлах и встроенная проверка регулярок, упрощен импорт es-модулей из пакета typenoscript для Ноды, опция isolatedDeclarations для изолированной компиляции d.ts, задепрекечена часть вещей
- обновился кит React Spectrum и Aria: добавлены компоненты вложенного меню, дропзоны, инпут-файла, а также компоненты для работы с цветом (пикер, ареа, слайдер, колесо)
- вышел release candidate Svelte 5: для тех, кто использует Svelte 4, всё будет будет работать быстрее, а для тех, кто использует Svelte 3, сначала рекомендуют обновиться до Svelte 4

Проекты
- extension — либа для разработки браузерных расширений, достаточно простая, чтобы запустить своё расширение командой npx extension create <your-extension-name>
- react-spring-visualizer — визуализатор анимации либы react-spring
- tagify — компонент тегов в инпуте и текстарии, умеет в поиск, сортировку, кастомизацию

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

JS
- как улучшить читаемость кода, вынеся подробности имплементации API в отдельный архитектурный слой: было — apiClient.get<UserResponse>(`/user/${handle}`), стало — UserApi.getUser(handle)
- туториал по новым фичам нового Реакта: особо хорошо выглядит use
- когда использовать Bun вместо Node: если важен перф; когда нужен швейцарский нож (раннер, пакетный менеджер, тест-раннер и бандлер в одном); когда не хочется заморачиваться с импортами, а хочется, чтобы просто работало; когда нудна встроенная БД SQLite
- объяснена тайна века, как же всё таки работает array.sort((a, b) => b - a): функция нужна, чтобы понять куда уйдёт a на числовой прямой, вправо и влево
- как собрать на коленке свой шаблонизатор на HTML и .sh, «потому что могу»

CSS
- респонсив размеры шрифта с помощью clamp(): хорошо — clamp(1rem, 2.5vw, 3rem), ещё лучше — clamp(1rem, calc(2.5vw + 1rem), 3rem)
- реализация боковых отступов в древовидном компоненте: проще всего добавить пустой элемент-спейсер с динамической шириной --spacer-col: max(8px, var(--level) * 8px)
- отрисовка нот в гридовой сетке: SVG с data-атрибутами вписывается и раскладывается по рядам и колонкам
- вендорные префиксы для каких свойств ещё остались актуальны (можно пересчитать на пальцах рук)
- оказывается можно управлять порядком отрисовки fill и stroke с помощью свойства paint-order: stroke fill (по умолчанию рисуется fill → stroke)

HTML
- официальное разрешение от Гугла: использовать popover API теперь можно!

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

@web_platform | Поддержать канал 🤝
🔥11👍65🤷‍♂1
Собрал для вас в одну папку авторов, ведущих блоги по фронтенду, веб-разработке и вокруг неё.

🔗 https://news.1rj.ru/str/addlist/Z6Efi4jXwe9lODcy

Специально отобрал именно ламповые авторские блоги, а не перепосты ссылок, документации или тексты не про код.

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

Надеюсь, будет полезно ✌️

@web_platform | Поддержать канал 🤝
🔥19👍157
#Пульс_веб_платформы 10.05.2024

Новости
- выпущена Node v22.1.0: появилась поддержка NODE_COMPILE_CACHE для включения режима кеширования V8 (если граф модулей не меняется, то повторная пересборка становится быстрее за счёт кэша)
- только недавно в Next.js решили не патчить fetch, как в React решили патчить Date: «мы по-тихому, никому мешать не будем, со стандартами будет совместимо, вы же полифиллы используете, вот и дату норм пропатчить»; вроде так, но есть нюанс: в случае полифиллов добавляются костыли для воссоздания недостающих стандартных возможностей платформы, а фича-патчи добавляют проприетарные костыли, что уже не то же самое

Проекты
- react-tracked — представьте, что у вас есть useState/useReducer, которые триггерят ререндеры не всегда, когда стейт перезадался, а когда он именно изменился, стал другим (под капотом Proxy, работает для вложенных уровней стейта тоже)
- pragmatic-drag-and-drop — многообещающая либа для драг-н-дропа (для травмированных React DnD)

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

JS
- почему таки плохо патчить globals: автоматом создаёт техдолг, нестандартные фичи работают непредсказуемо в разных средах, скрывают магию внутри, лочат на вендора и в целом тормозят прогресс в долгую
- Bun может ускорить не только локальную разработку, но и сборку и деплой на CI, так как, например, заменяет yarn и Vitest
- (не совсем JS, но это не так важно) как разложить одно нечитаемое условное выражение на несколько мелких или же вынести в отдельную функцию
- чтоб не оборачивать new URL(urlstring) в try catch для обработки невалидных урлов, можно использовать URL.canParse(urlstring), а также скоро можно будет URL.parse (начиная с Chrome 126 и Firefox 126)
- React хорош для организации UI-компонентов, но когда речь заходит про дата-фетчинг, то всё что предлагает React из коробки — это выйти в окно; и в этом случае на помощь приходит React Query, который позаботится о кэшировании, оффлайне, восстановлении скролла и тд, чтобы вы спокойно могли с чистой совестью выключить компьютер в конце рабочего дня
- лучший способ гарантировано отправить неблокирующий запрос при закрытии страницы — на событии visibilitychange выполнить navigator.sendBeacon()
- возможно для управления версиями Node стоит попробовать альтернативы nvm: самой перспективной выглядит Volta, которая не требует доп файлов (конфиг в package.json), кроссплатформенна, автопереключает версию при смене проекта, а заодно может переключать версию yarn

CSS
- как-то незаметно в повседневной разработке мы перестали думать про минификацию стилей, тк эту функцию взяли на себя фреймворки, хотя [олдфаг mode on] раньше было почему-то важно считать сколько десятков килобайт умеет сэкономить твой минификатор [олдфаг mode off]
- мифы про специфичность: 1) специфичность — это не целое число, а набор из трёх чисел a, b, c 2) добавление атрибута style не добавляет специфичности 3) !important не добавляет специфичности, а уносит объявление в другой origin
- в мире победившего color-mix()-а серые палитры создаются с помощью полутона между чёрным и белым color-mix(in oklch, black 20%, white)
- border-color: transparent — это ок, если, например, на hover задавать видимый цвет, чтобы при задании рамки не изменялись размеры элемента
- :has() — это не только «родительский» селектор, но и полноценный условный оператор для элементов интерфейса, например, для select (красим select в зависимости от выбранного значения) или же для всего интерфейса (красим весь сайт в зависимости от выбранного значения (сомнительно))
- субгриды в помощь для контроля за переполнением дочерних ячеек грида на примере нумерации в упорядоченных списках
- Popover API для создания тултипов, якорящихся на элемент-триггер (сложно, но возможно)

Платформа
- разработчики React Aria поделились, как сделать человеческое выпадающее субменю, чтобы оно случайно не закрывалось во время движения курсора: строится визуальный треугольник, в рамках которого считается, что подменю не должно быть скрыто + по скорости движения предполагается, куда пользователь собрался двигать курсор

@web_platform | Поддержать канал 🤝
🔥15👍112
#Фикшн_веб_платформы

А это React и TypeScript моей молодости, внучок! 👨‍🦳

Если серьёзно (и выкинуть всякую xml-требуху), то смотрите:
- типы есть;
- всё декларативненько;
- импорты «нативные»;
- UI-лейаут флекс-подобный резиновый был;
- логика отделена от UI, но собрано в одном файле;
- реактивность в каком-то виде, кажется, тоже была;
- ООП, вроде как, тоже было.

Правда загнулось вместе с флешом, но даже сейчас вызывает любопытство.

@web_platform | Поддержать канал 🤝
🔥13👍9😁5🥴1👻1
#Пульс_веб_платформы 17.05.2024

Новости
- вышел Astro 4.8: добавлена экспериментальная поддержка actions — возможность объявить методы, запускающиеся на бэкенде, и вызывать их напрямую из JS. Что сразу же мне напомнило аналогичную возможность из ASP.NET образца 2008 года под названием PageMethods: это было очень удобно, а главное просто и понятно, тк серверные методы вызываются из JS напрямую, туда наглядно прокидываются нужные данные. Также добавлена экспериментальная возможность в «мидлваре» перехватывать и перенаправлять запрос на другой адрес
- вышел Safari 17.5 (третий большой апдейт в 2024): появились text-wrap: balance, color-scheme: light dark и light-dark(), @starting-style, @import <url> supports(<feature>)
- ситуация с неготовностью экосистемы ESLint к новой версии ESLint 9 привела к созданию особого пакета @eslint/compat, функцией fixupPluginRules из которого можно обернуть старые плагины и обещают, что они заработают внутри 9 версии
- вышел React Compiler, призванный избавить от ручного использования useMemo, useCallback и memo(), но он как героически побеждает проблемы React, так и превносит новые проблемы с тем, что работает только в Strict-mode, несовместим с mobx, несёт чёрную магию на борту
- обновления Chrome 125: поддержан CSS Anchor Positioning, добавлены CSS-функции round(), mod(), and rem(), а также Compute Pressure API
- Screen Wake Lock API поддерживается во всех браузерах: можно указать программно не гасить экран

Проекты
- hugeicons — большая коллекция компонентов иконок: кастомизируются размер, цвет, скругление и иногда вариативность
- eslint-plugin-regexp — плагин ESLint для нахождения ошибок в регекспах
- fuzzysort — быстрый и лёгкий fuzzy-поиск на JS
- Web Platform Dashboard — таблица с данными о поддержке фич платформы в браузерах

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

JS
- принципы SOLID на примере Реакт-компонентов: даже если не называть это какими-то буквами, а руководствоваться принципами здравого смысла, то примеры здравые: не замешивать несвязаные друг с другом вещи, а связанные — наоборот держать вместе, не хардкодить, писать единообразно, просто, не усложнять логику
- и ещё советы по вынесению ответов API, обработки выходных или входных данных в отдельный API-слой приложения
- если вы дизайнер и напрямую не кодите, но при этом хотите вживую «править» сайты, то вот список, чему научиться: выбирать элементы, переключать классы, подписываться на эвенты, менять HTML, собирать данные с форм (бонус дизайн-режим document.designMode = "on")
- если вы пишете либу, даже небольшую, неплохая идея — написать JSDoc для подсветки в IDE, пакетном менеджере, ридми: внутри можно писать текст, типы, теги @param и @returns для описания функций, примеры кода в md, теги @link , @linkcode, @linkplain для ссылок
- один из недооцененных хуков — useDefferedValue — откладывает рендер компонента до более подходящего момента, чтобы, например, если компонент «тяжёлый», улучшить перфоманс или же показать лоадер
- у элементов форм есть полезные методы из коробки: form.elements.namedItem, form.elements.group для радио-групп, app.elements.firstname.defaultValue для получения дефолтного значения инпута

CSS
- range syntax медиа-выражений width >= 48em, width < 48em лучше тем, что не вынуждает писать разные числа min-width: 48em, max-width: 47.99em с возможными «мёртвыми» зонами между разрешениями
- гайд по созданию форм на CSS: сейчас всё в большинстве случае сводится к SVG или же к clip-path: polygon() и mask + gradient
- если взять кастомное свойство типа <integer> и инкрементить его раз в миллисекунду, то у нас есть централизованный счётчик для создания «анимаций» по типу rotate: calc(var(--t) * .001turn); вся соль в том, что с наличием такого счётчика можно синхронизировать несколько анимаций без JS
- фейд-градиент поверх картинки и под текстом border-image: fill 0 linear-gradient(#003, #000)
- Chrome пушит Anchor Positioning API: штука для позиционирования элементов относительно других элементов; вангую, через 1-2 года заработает везде, а пока есть полифилл

@web_platform | Поддержать канал 🤝
👍24🔥64
#Лаборатория_веб_платформы

Частичный stage файлов в git

Приходилось ли вам работать с длинными JSON-ами в git-е?

Мне вот приходилось, когда в проект внедрялись дизайн-токены. Схема такая: есть «источник правды» в виде хранилища значений разных элементов интерфейса (цвета, размеры шрифтов, параметры теней и тд) в виде плагина к Figma. Из этого хранилища дизайнеры применяют значения в макетах, а для разработки выгружается JSON-файл. Затем файл процессится и из него генерятся кастомные свойства аля --ui-element-background-color-default, которые уже используются в стилях.

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

Руками копировать правки — так себе идея. Тут пригодится возможность git-а делать добавление частичных правок файла в stage.

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

Для этого в VSCode нужно перейти в файл, выделить интересующие текстовые правки и выполнить команду cmd(ctrl)+shift+P > Git: Stage Selected Ranges и в stage уйдут только частичные правки файла, остальные правки останутся в изменённом файле.

Похожим образом можно также частично откатывать изменения в файлах. Например, что бы подчистить временные логи. Для этого нужно выбрать файл, так же выделить текстовые правки и выполнить команду cmd(ctrl)+shift+P > Git: Revert Selected Ranges. Либо в окошке с диффами тыкнуть на дифф и выбрать Revert this change.

Из консольного git-а такое частичное добавление в stage также работает. Для этого есть команда git add -p. Если, к примеру, была правка в двух местах файла, то появится такое сообщение (1/2) Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]?. Выбор y — правка стейджится, n — не стейджится, ? — помощь по остальным вариантам команд.

Для частичного реверта нужна команда git restore -p, которая вызовет такой же интерактивный диалог только с другим вопросом: Discard this hunk from worktree?.

@web_platform | Поддержать канал 🤝
👍23🔥6
#Пульс_веб_платформы 24.05.2024

Новости
- Vercel привлек 250 миллионов $ финансирования, а это значит, что ещё больше «нетехнических» клиентов будет в один клик пользоваться облаком, генерировать компоненты на v0.dev и также заливать их в облако, а потом платить деньги фиксикам, чтобы это всё работало
- (вдогонку к прошлой новости) появилась экспериментальная поддержка React Compiler в Next.js, что гладко укладывается в концепт «дев сложный, заплати и мы сделаем проще» (а кто сделал его сложным, КТО?!)
- в Chrome 126 собираются встроить мини-LLM, чтобы пользователь мог выполнять простые задачи на сайтах и в веб-приложениях с помощью ИИ напрямую из браузера (пахнет вендор-локом, но концепт прикольный, вангую ИИ-«помощники» появятся во всех браузерах, чтобы помогать пользоваться сайтами)
- а в 125 версию Chrome в девтулзы уже добавили ИИ-фичу в консоль (объяснение ошибки, чтоб в гуглол не ходить), также завезли отладку anchor positioning, улучшили информацию об ошибках в Sources, а в Network добавили инспект заголовков Early Hints headers, в Performance теперь показывается инфа по скорости CSS-селекторов и ещё обновился Lighthouse
- Bug 33654, Opened 25 years ago, Closed 2 days ago: то чувство, когда сын закрыл баг отца

Проекты
- littlezipper — создание zip файлов в браузере и в node/deno c CompressionStream API (доступно во всех средах)
- xlsxtable — создание .xlsx файлов на клиенте и сервере
- noscriptviewer — поисковик и просмотрщик SVG-изображений с возможностью экспорта в виде растровой картинки, data URI или react-компонента

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

JS
- новый статический метод const { promise, resolve, reject } = Promise.withResolvers() позволяет управлять промисами извне конструкции new Promise((res, rej) => {})
- про предикаты типов (`function isType(arg: any): arg is Type`): в целом полезны, из минусов добавляют нагрузку в рантайм и дублируют логику самих типов
- как создать свой минималистичный стор-менеджер в React без использования контекста, а с useSyncExternalStore, который к тому же из коробки подцепит типы
- и если вы всё таки предпочтёте пользоваться контекстом, как избежать множественных вложенных друг в друга контекстов через <Providers providers={[providersList]}>
- официально представлена альфа-версия Pigment CSS — новая CSS-in-JS-либа от MUI, которая мимикрирует по синтаксис Styled Components, но при этом работает в билд-тайме (и поэтому не использует контекст, что важно для серверных компонентов)
- даже если вы используете React, то всё равно вы пишете JS, то есть сталкиваетесь с контекстом выполнения и замыканиями, и как следствие можете в замыкание мемоизированной функции затянуть какой-нибудь большой объект, который не будет подчищаться garbage collector-ом
- реализация идеального Deep Equal сравнения объектов в JS, а также вариант Shallow Equal, который используется в React

CSS
- медиа-выражения для определения размеров вьюпорта больше не нужны? Флексбокс, грид, контейнер-выражения (а также `:has()`) решают задачи лучше медиа-выражений, так как специально для этого предназначены и могут стилизовать респонсив-компоненты независимо от вьюпорта, но зато учитывая окружающий контекст. А медиа-выражения теперь для определение фич и настроек девайса (тема, контраст, анимации)
- пока функция color-contrast() не доехала до браузеров, задачу подбора контрастного цвета можно решить с помощью relative color syntax
- CSS-фич стало настолько много, что пора расчехлять старый-добрый w3c-маркетинг и сделать отсечки CSS4, CSS5 и CSS6 (а что, в ECMA-движухе же получилось)

HTML
- в результатах опроса State of HTML 2023 каждый найдёт новенькое для себя: у нескольких <details> с одинаковыми name открыт может быть только один (аккордеон), <noscript async blocking="render"> блокирует рендер, <input type="file" accept="video/*" capture> сделает запись с пользовательской камеры

@web_platform | Поддержать канал 🤝
👍29🔥14
#Лаборатория_веб_платформы

Сортировка и поиск с localeCompare

С задачей обычной сортировки, если речь про английский язык или числа, норм справляется sort() или sort((a, b) => a - b).

Но вот когда сортируются «неанглийские» строки, то тогда пригодится метод localeCompare у строк: sort((a, b) => a.localeCompare(b)), который сравнивает сроки учитывая действующую локаль пользовательской системы. Грубо говоря, где в текущей локали один Unicode-символ находится по сравнению с другим символом – перед ним или после него?

Что интересно, базовый метод появился в браузерах ещё практически с начала существования Chrome, Firefox и Safari. Но позже в него была добавлена поддержка дополнительных параметров, уточняющих как именно нужно сравнивать строки. Причём под капотом localeCompare будет вызывать Intl.Collator API, в браузерах его поддерживающих.

Настройка caseFirst — первыми идёт нижний регистр или верхний:


['Е', 'а', 'е', 'А'].sort((a, b) => a.localeCompare(b, 'ru'))
// по умолчанию сначала нижний регистр
// ["а","А","е","Е"]

['Е', 'а', 'е', 'А'].sort((a, b) => a.localeCompare(b, 'ru', { caseFirst: 'upper' }))
// теперь сначала идёт верхний регистр
// ["А","а","Е","е"]


Это актуально и для английских текстов тоже.

Настройка sensitivity — учитывать ли при сравнении регистр и вспомогательные символы вокруг буквы (a и á, е и ё):


'лёд'.localeCompare('ЛЕД', 'ru', { sensitivity: 'variant' }) === 0
// л ≠ д, е ≠ ё, л ≠ Л
// false

'лед'.localeCompare('лёд', 'ru', { sensitivity: 'case' }) === 0
// л ≠ д, е = ё, л ≠ Л.
// true

'Лёд'.localeCompare('лёд', 'ru', { sensitivity: 'accent' }) === 0
// л ≠ д, е ≠ ё, л = Л
// true

'лёд'.localeCompare('ЛЕД', 'ru', { sensitivity: 'base' }) === 0
// л ≠ д, е = ё, л = Л
// true


То есть если пользователь вводит в поиск ЛЕД, можно однозначно определить, что это лёд прямо в браузере.

Настройка numeric — для корректной сортировки строк с числами:


['09', '1', '2', '01', '10'].sort((a, b) => a.localeCompare(b))
// по умолчанию сортируется по символам
// ["01","09","1","10","2"]

['09', '1', '2', '01', '10'].sort((a, b) => a.localeCompare(b, 'ru', { numeric: true }))
// теперь строки учитываются как числа
// ["1","01","2","09","10"]


Так можно отсортировать строки с числами без явного приведения к числам.

Что радует, все возможные доп настройки доступны с Chrome 87, FF 85, Safari 14.1, Node 15.

Демо тут

@web_platform | Поддержать канал 🤝
👍37🔥134🥰1
#Пульс_веб_платформы 31.05.2024

Новости
- на волне новостей о React Compiler анонсирован выпуск Million Lint 1.0-rc: в отличие от компайлера, который пребилдит реакт-код, Million Lint втыкает в код точечно замеры производительности и уже на их основе выдаёт рекомендации в редакторе кода и подсвечивает проблемы с производительностью
- на той же волне анонсирован Next.js 15 RC: поддерживает React 19 RC, React Compiler, произошёл отказ от кеширования по умолчанию в fetch, GET Route Handlers и роутере, постепенно выкатывается реактовская система частичного пререндера Partial Prerendering (PPR) и after() API для отложенного запуска второстепенных тасков после выполнения основного запроса
- и снова на той же самой волне вышел SolidStart v1.0.0, метафреймворк на основе Solid, встроенного роутера, а также Vite, Nitro и другого опенсорса; конечно, не перестаю удивляться современной индустрии, которую люди из опенсорса натурально тащат вперёд на энтузиазме и за счёт синергии составляют конкуренцию корпорациям

Проекты
- Responsive Viewer — если много верстаете или тестируете на разных разрешениях, это плагин для браузера, чтобы одновременно на одном экране открыть несколько «девайсов» с синхронизацией скролла и кликов
- matcha.css — CSS-либа для стилизации чистой семантической разметки + небольшой набор классов хелперов для стилизации лейаута, цветов и подсветки синтаксиса (внутри нет !important-ов, то есть всё переопределяется пользовательскими стилями)
- open-props — коробка с CSS-переменными на все случаи жизни (цвета, размеры, шрифты, тени, скругления)
- react-google-maps — реакт-компоненты и хуки для Google Maps JavaScript API
- tsx — запускальщик ts-файлов в Node (одной строкой и без конфигов, бонусом есть вотчер)
- clack — либа для создания красивых и удобных cli-промптов

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

JS
- иногда для повышения читаемости можно сделать код более «композируемым», но повторяющимся (на примере реакт-компонентов), лишним if или switch кашу не испортишь
- Solid мимикрирует под реактовский JSX, но под капотом компонент в React — это функция, которая вызывается каждый раз при рендере, а в Solid — один раз и возвращает DOM-элемент; вместо useState используется createSignal, который тоже похож внешне и возвращает массив с функцией доступа к состоянию и сеттер, но на деле не вызовет ререндера компонента, а только изменит контент в DOM-ноде; также в Solid есть createEffect (похож на useEffect), в который в простейшем случае не нужно передавать зависимости, что может привести к неочевидным багам
- (я из 2012 понимает всю боль) реактивность — это прежде всего способ избежать связанности (coupling) кода

CSS
- ещё одно напоминание, что каскадные слои можно использовать для организации типов стилей, например, отдельно объявлять @layer reset, theme, layout, причём подключаться они будут в таком порядке независимо от порядка подключения в коде; также описан концепт, как через «ручки» (кастомные свойства) управлять параметрами лейаута страницы
- рецепт popover + @starting-style, на самом деле сгодится для любых «модалок» и появляшек: @starting-style привносит в этот паттерн недостающую декларативность, чтобы не приходилось вручную манипулировать классами/эвент-хэндлерами
- да и вообще, почему бы просто не добавить @starting-style ко всему
* { transition: opacity .5s ease-in; @starting-style { opacity: 0 } }?

HTML
- статья по мотивам недавнего опроса State of HTML 2023: людям нравится datalist (вывод: время адопта среднего HTML-элемента — 5 лет), не нравятся формы (стилизация, инпуты, валидация, кроссбраузерность), люди помнят о существовании веб-компонентов (и немного используют), людям не хватает нативных элементов datatable, tabs, switch/toggle
- в 2023 людям не хватало switch, а в 2024 он уже появился (пока правда только в Safari 17.4, но тем не менее), <input type="checkbox" switch /> можно стилизовать через ::thumb, ::track, но при этом он в отличие от чекбокса не может быть в indeterminate-состоянии и может быть required (в общем, ждём 5 лет и можно использовать)

@web_platform | Поддержать канал 🤝
👍23🔥96
Заметки первобытного разраба

Груг не так умён, но кодит много лет и чему-то научиться

Большеголовых разрабов много, и много кто думает он большеголовый разраб, сделать кислую мину, когда читать эту заметку

Сложность — плохо

Очень плохо, лучше груг сражаться с тиранозавром, он хотя бы его видит

Большеголовые разрабы и менеджеры впускают демон сложности в кодовую базу, они не боятся его или даже не знают

Сегодня груг работает с кодом и понимает, всё хорошо

Завтра невозможно: демон сложности вошёл в код и теперь очень опасно!

Груг не видит демон сложности, но чует его в коде. Демон дразнит, измени тут, сломается где-то там. Дубина не спасать от демон сложности, а бить самого груга

Магическое оружие против демона сложности — слово «нет». Нет, груг не делать эту фичу. Нет, груг не строить эту абстракцию.

Это хороший инженерный совет, но плохой карьерный совет. «Да», магическое слово чтобы получить больше блестящих камней или стать вождём племени разрабов

Грустно, говори «да», а потом вини других гругов, когда вышел фейл, идеальный карьерный совет

Но иногда всё таки блестящие камни нужны, нет мясо динозавров, жена говорить груг дети нужна крыша и еда. Тогда груг говорить «лады». Лады, груг сделать эту фичу

Груг делать 80/20 решение, не со всеми свистелками, что хотеть менеджер, но делать свою работу, и демон сложности уходить

Факторинг кода

Это сложно правильно разбивать кодовую базу. Но груг понял, не разбивай кодовую базу слишком рано

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

Пройдёт время, система примет форму, и появятся линии для разреза

Хорошая линия для разреза иметь узкий интерфейс с системой. Мало число функций и абстракций заточают демона сложности в кристалл

Большеголовый разраб не такой, часто придумывать абстракции на старте проекта. Груг тянется к дубинке и хотеть кричать: «большеголовый не поддерживать код, а уходить в другой проект, груг поддерживать код!»

Рабочее демо хороший трюк, груг требовать от большеголового разраба демо завтра

У большеголовый большой мозг! Нужно его ограничивать для добра, не помогать демону сложности

Назови рабочее демо «прототип», менеджер будет приятно

Тесты

Груг любит и ненавидит тесты. Печально, но есть шаманы тестов. Делать из тестов идол, писать тесты до того как груг взялся за код и не понимать рабочую область

Легко не писать тест, оно работает на машине груга. Очень плохо, нет гарантии что работать где-то ещё или на машине груга в будущем

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

Рефакторинг

Рефакторинг хорошая идея попозже, когда код стабильный

Груг заметил, большой рефакторинг большая опасность провала. Поэтому делать маленький и не отплывать далеко от берегов. Идеально система работает всё время, шаги друг за другом

Много старый груг научился не ломать код бездумно, даже если он страшный

Опасность тут, мир страшный и уродливый часто и поэтому такой же и код

Смирение не всегда есть, груг говорит «не нравится, исправлю» и это много часов боли и система только хуже

Груг говорить надо улучшать система, но надо время понять её целиком и уважать работающий неидеальный код

Груг раньше писать код минимального размера, но это часто сложно читать и отлаживать

Груг думать DRY хороший совет, но иногда лучше скопировать код с небольшими вариациями чем делать новый агрумент

Груг считать принцип SoC не ок. Лучше весь код штуки будет в самой штуке, не надо искать файлы где что лежит

Фронтенд

Демон сложности овладел целая индустрия!

Создавать меньше сложности, не смотри на facebook или google. Реакт хорошо для карьера и некоторых приложений, но груг становиться служителем демона сложности

Груг видит много моды в разработке. Груг не боится показаться тупым говоря это слишком сложно и смущает груга!

Груг чувствует много синдром самозванца. Груг часто не понимает что происходит, боится сделать ошибку и разочаровать других гругов, самозванец!

Само программирование такое: никто не самозванец, если все самозванец

grugbrain.dev
28😁8👍6👀3🤗1
#Пульс_веб_платформы 07.06.2024

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

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍12🔥65
#Лаборатория_веб_платформы

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

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

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

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


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


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


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


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

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

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

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

@web_platform | Поддержать канал 🤝
20👍9
#Пульс_веб_платформы 14.06.2024

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍20🔥84
#Пульс_веб_платформы 21.06.2024

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

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

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

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍14🔥21
#Пульс_веб_платформы 28.06.2024

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

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

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
17🔥8👍3
#Пульс_веб_платформы 05.07.2024

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
🔥13👍124
#Пульс_веб_платформы 12.07.2024

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍22🔥5
#Пульс_веб_платформы 19.07.2024

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

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍18
#Пульс_веб_платформы 26.07.2024

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍27🔥103
#Пульс_веб_платформы 02.08.2024

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍18🔥64🤝1
#Пульс_веб_платформы 09.08.2024

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

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

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

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

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

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

@web_platform | Поддержать канал 🤝
👍215🔥5👏2🙈1