F
Frontender's notes [ru]
21.07.2026 17:07 · 👁 545
Эмиграция в США после 30: от грузчика на складе до Apple и собственной школы
Виктор Богуцкий рванул в Штаты в 2016-м. Сначала таскал коробки, облизывался на отказы, но в итоге дополз до Apple и eBay, а теперь ещё и свою школу программирования замутил — PASV называется.
В разговоре с Сашей из канала «Shulepov Code» Виктор рассказал, что в эмиграции упёртость важнее таланта, как в айтишном найме в США всё устроено, почему лям в месяц — ещё не гарантия накоплений, и зачем каждому разработчику становиться дирижёром-архитектором.
Тыкай сюда: https://habr.com/ru/articles/1060868/
👉 Frontender's notes
F
Frontender's notes [ru]
20.07.2026 15:07 · 👁 1.5K
В июле снова видно, как digital и IT окончательно уходят от «просто контента» к системе, где решают скорость, ИИ и нормальная упаковка смысла. Кто раньше выстраивает понятную подачу и сильную экспертность, тот и забирает внимание рынка.
Если вы работаете в digital или IT, сейчас особенно важно не писать «как все» а говорить так, чтобы вас хотелось читать, сохранять и передавать дальше. Мы как раз собрали в этой папке материалы, которые помогают делать это без лишней воды.
Здесь готовим большое SMM исследование в сфере промышленности, где покажем, как меняется работа с контентом, в какую сторону идти, и что прямо сейчас в ТОПе.
Отдельно здесь про управление ИТ и цифровой трансформацией.
Папка подойдет тем, кто:
• продвигает digital- и IT-проекты;
• собирает сильную упаковку для экспертов и компаний;
• хочет говорить с аудиторией современно и по-человечески.
Сохранить папку себе 🗂
F
Frontender's notes [ru]
19.07.2026 17:07 · 👁 1.8K
Как вытащить типы из Strapi-популейта на уровне компилятора
В Strapi есть засада: ответ от запроса меняет форму в зависимости от того, что ты в него сунул. Дергаешь статью без populate — получаешь только плоские поля. Кидаешь populate: { category: true } — категория уже внутри. А если еще и fields: ['name'] туда добавить, то категория придет урезанной. Итог: один эндпоинт выдает кучу разных вариантов, и статический TypeScript-интерфейс это никак не разрулит. Он либо нагло врет — обещает поля, которых в реальности нет, либо тупо сливается в any.
В статье показывают, как забить на эту проблему с помощью кодогенерации: вытаскиваешь схему из живого Strapi, генеришь по ней TypeScript-клиент, и самое мясо — заставляешь систему типов выводить ответ прямо из аргумента populate еще до компиляции. Типа как в Prisma: какой тип вернется, зависит от того, что ты передал в метод. Все на TypeScript, клиент open-source под MIT, ссылка внизу.
Почитать на Habr
👉 Frontender's notes
F
Frontender's notes [ru]
19.07.2026 09:07 · 👁 1.8K
Как React-магазину не обрасти левыми зависимостями?
Вот классика: засунули карту банковской карты в entities/card/ui — туда попали маска номера, баланс и статус. Прошло два спринта, и в карточку влепили «заблокировать карту» и «изменить лимит». В итоге entity начала тащить features/block-card, features/change-card-limit, а ещё проверку прав мимо public API. Когда эту карточку воткнули в выбор счёта списания, с ней припёрлись лишние зависимости и проверки ролей. Никто не пострадал, но на фикс ушло время.
В entity оставили только чистый CardPreview, сценарии подняли уровнем выше, композицию дашборда переложили в widgets/card-summary, потом заново прогнали ролевые тесты. На ревью до названия папки дошли только в конце. Сначала обсуждали другое: какие будущие изменения эта граница позволит оставить без выноса за пределы.
В FSD 2.1 советуют начинать со страниц и вытаскивать код ниже, когда появляется переиспользование. Это норм дефолт, хотя, если рядом есть второй похожий потребитель, границу иногда можно резать раньше. Детали тут: https://habr.com/ru/articles/1060256/
👉 Frontender's notes
F
Frontender's notes [ru]
18.07.2026 17:07 · 👁 1.8K
Гугл тебя кормит, гугл тебя поит. Даже целую аналитическую систему можно соорудить, не вынимая кошелька
Собираешь ответы через формы, вешаешь визуализацию на сайт — и, как только набирается нужная цифра, автоматом улетает письмо. Авторы в качестве демки обкатали это на исследовании туристических предпочтений. Жми, всё расписано.
Читать далее
👉 Frontender's notes
F
Frontender's notes [ru]
18.07.2026 13:07 · 👁 1.7K
Типизация и детерминированная обработка состояния скролла при виртуализации списков с IntersectionObserver и кастомным Suspense в React 19
IntersectionObserver на бесконечных списках часто порождает гонки: элемент пересек границу, запрос ушел, а пользователь улетел скроллом дальше. Результат — повторные вызовы API и пустые мертвые зоны в рендере. В React 19 это решается через Suspense и хук use, делая обработку скролла детерминированной.
Замкнутое состояние скролла
Вместо разрозненных useState для startIndex и endIndex используем явный интерфейс ScrollState. Он обновляется атомарно — нельзя изменить один индекс без другого. Это исключает рассинхрон и гарантирует, что стейт всегда консистентен при передаче в Suspense-зависимый компонент.
interface ScrollState {
startIndex: number;
endIndex: number;
}
Синхронизация через Suspense и use
Когда IntersectionObserver срабатывает, мы сетим новый ScrollState. Компонент ItemsLoader внутри Suspense использует use(fetchItems(scrollState)) — это приостанавливает рендер до разрешения промиса. Наблюдатель пересоздается только в useEffect, который зависит от state.endIndex, то есть после того, как предыдущий диапазон гарантированно зафиксирован в DOM.
Типичная ошибка и trade-off
Ошибка: пытаться блокировать скролл флагами isFetching или отключать observer вручную. Это ломает UX и не решает проблему гонок, так как флаг может быть false до завершения ререндера. Минус подхода — он ломает классический поток «эффект -> стейт -> ререндер», требуя отказа от кастомных useEffect-решений. Но плюс — полная детерминированность: новые данные грузятся только после рендера старых.
Практический совет
Для production убедись, что fetchItems внутри use возвращает не просто массив, а структуру с totalCount или hasMore — это позволяет корректно остановить наблюдение при достижении конца списка. Иначе observer будет срабатывать на последнем sentinel-элементе бесконечно.
Вывод: Замыкание скролл-состояния в атомарный interface и ожидание рендера через Suspense устраняет гонки IntersectionObserver без костылей, делая поведение списка полностью предсказуемым для пользователя и инженера.
F
Frontender's notes [ru]
18.07.2026 09:07 · 👁 1.5K
Pete Hunt снова в деле — теперь будет рулить Next.js
Гильермо Раух запостил в X: Vercel подтянул Пита Ханта и Ника Шрока (того самого, что придумал GraphQL). Пит — один из тех старых волков, что стояли у истоков React, теперь он возглавит Next.js. Ещё Vercel наконец-то вводит регулярный ежемесячный график security-релизов для Next.js — первый такой выйдет уже через пару дней.
→ Читать подробнее
Cloudflare переписал блог на EmDash
Cloudflare взял и перекроил свой блог целиком на EmDash — это их «духовный наследник WordPress» на Astro. Анонсировали они это, кстати, 1 апреля, но без шуток.
Linaria: создатель объясняет, зачем городил новое
«Runtime CSS-in-JS — всё, приплыли», — заявляет мейнтейнер Linaria. Теперь он наваял dx-styles, zero-runtime альтернативу, которая всё жует на этапе сборки. Гайд по миграции с Linaria уже есть.
ReactBench: кодинг-агентов проверяют на React-коде
Команда React Scan и Million.js запилила eval для coding-агентов на «реалистичной React-работе». Задача — отсеять модели, которые блистают в других бенчмарках, но тупят на нормальном React-коде. Пока лидирует GPT 5.6 Sol.
→ Подробнее
React Native Skia 2.9 — выкатили
Вышла свежая версия библиотеки для 2D-графики под React Native.
shadcn/typeset: полная типографика для HTML
Готовая типографская система для обработанного HTML (ну, там вывод Markdown) — один CSS-файл и один класс-обёртка. Настраивается парой CSS-переменных. Есть конструктор, если хочешь заморочиться.
И ещё:
— EmDash — опенсорс от Cloudflare
— shadcn/typeset на GitHub
— Preact 11.0 Beta 2 — «одна из последних бет»
— react-dropzone 17.0
— React Mosaic 7.0
— TanStack: график популярности npm-пакетов
👉 Frontender's notes
F
Frontender's notes [ru]
17.07.2026 17:07 · 👁 1.7K
Как скрестить Symfony 8 с Angular 22?
Ровно с этого вопроса я и стартанул, когда полез разбираться во всю эту кашу. Но после того как разгреб, могу смело заявить: норм тема, рабочая, и поддерживать такую архитектуру без геморроя вполне реально.
В посте — детальное описание того, как замутить веб‑приложение с удобной обвязкой из Docker контейнеров. CI/CD тут даже не упоминается — всё чисто про дев-сторону процесса разработки.
Автор пилит это всё в PHPStorm 2026.1.4 от Jetbrains, но вообще IDE — до лампочки. Теоретически можно даже в блокноте наваять приличный код.
Читать далее
👉 Frontender's notes
F
Frontender's notes [ru]
17.07.2026 13:07 · 👁 1.6K
Типизация и детерминированная обработка race condition при конкурентной записи в WebSocket через AbortController и AsyncQueue в React 19
Race condition в WebSocket-соединениях — не просто теоретическая проблема. В production она возникает, когда несколько компонентов одновременно пытаются отправить данные: два сабмита формы, два useEffect с разными контекстами. Сообщения перемешиваются, теряются, или соединение падает с нечитаемым traceback. Стандартный WebSocket не гарантирует порядок, если не управлять очередью вручную.
Почему это важно для React 19
React 19 не предоставляет магического решения для WebSocket. useCallback и AbortController — стандартные API, работающие с React 16, но в 19-й версии они стабильны, и связка с очередью чувствует себя уверенно. Однако race condition остаётся: два вызова send из разных компонентов без синхронизации приводят к хаосу.
Решение: AsyncQueue и AbortController
Берём самописный AsyncQueue с FIFO и AbortController для отмены устаревших задач. Очередь гарантирует, что следующее сообщение отправится только после получения ответа на предыдущее. AbortSignal позволяет скипать задачу, если компонент размонтировался или пользователь передумал. Вот типизированный пример:
type SendTask = {
data: unknown;
signal: AbortSignal;
};
class AsyncQueue {
private queue: SendTask[] = [];
private processing = false;
async enqueue(task: SendTask): Promise<void> {
this.queue.push(task);
if (!this.processing) {
this.processing = true;
while (this.queue.length > 0) {
const current = this.queue.shift()!;
if (current.signal.aborted) continue;
await this.sendToWS(current.data);
}
this.processing = false;
}
}
private async sendToWS(data: unknown): Promise<void> {
await new Promise<void>((resolve, reject) => {
const timeout = setTimeout(() => reject(new Error('Timeout')), 5000);
ws.send(JSON.stringify(data));
ws.once('message', () => {
clearTimeout(timeout);
resolve();
});
});
}
}
const useSafeWS = () => {
const queueRef = useRef(new AsyncQueue());
const send = useCallback((data: unknown, signal?: AbortSignal) => {
const controller = new AbortController();
const effectiveSignal = signal || controller.signal;
queueRef.current.enqueue({ data, signal: effectiveSignal });
if (!signal) controller.abort();
}, []);
return { send };
};
Типичная ошибка: игнорирование таймаутов и очистки
Главный подводный камень — если сокет завис на ожидании ответа, вся очередь блокируется. В production добавьте fallback на переподключение: при таймауте разрывайте соединение, очищайте очередь и инициируйте reconnect. Без этого компоненты будут ждать вечно, а состояние интерфейса застынет.
Trade-off: самописное vs библиотечное решение
Самописная очередь требует тестирования edge cases: таймауты, параллельные подключения, отмена задач. Библиотеки вроде ws-queue решают это из коробки, но добавляют зависимость и скрывают логику. Я выбираю своё — прозрачность дебага и ноль зависимостей. Минус: нужно покрыть тестами сценарии с зависанием и переподключением.
Вывод: Race condition в WebSocket решается через FIFO-очередь с AbortController, но не забывайте про таймауты и fallback на reconnect, иначе детерминизм превратится в блокировку.
F
Frontender's notes [ru]
17.07.2026 09:07 · 👁 1.8K
Ты не шаришь в CSS: вопросы и ответы, апдейт 2026
Автор канала продолжает свою рубрику и наваял новый пост про CSS. До этого похожий текст про HTML залетел в топ и стал одним из самых популярных за последнее время.
Задача этого опроса — просто развлечь народ. Вопросы заточены под реальную работу, но сходу на них ответит не каждый. Не знаешь половину — пофиг, ничего страшного.
Почитать
👉 Frontender's notes