Frontend | Иван Усынин
118 subscribers
46 photos
6 videos
27 links
👨🏻‍💻 TechLead Frontend в Альфа-Банк. Запускал проекты в production до того, как это стало мейнстримом.

💡 На канале: рабочие заметки, решение возникающих проблем, полезные материалы про Frontend

Связаться: @usyninis
Download Telegram
A?.Frontend B-Day Meetup

🎉 Уже завтра - 29 октября в Санкт-Петербурге пройдет frontend-meetup, где будем праздновать день рождения комьюнити A?.Frontend.

Приглашаю всех на событие: участвовать можно как офлайн, так и онлайн 🧑‍💻 .

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

Зарегистрироваться и ознакомиться с полной программой мероприятия можно по ссылке:
https://digital.alfabank.ru/events/frontend-b-day-meetup
Please open Telegram to view this post
VIEW IN TELEGRAM
🤩4❤1👍1
Выступил на A?.Frontend B-Day Meetup

Вчера прошел очень душевный митап, посвященный дню рождения сообщества разработчиков A?.Frontend 🎂

Уютный зал, полностью заполненный гостями, диджей с отличной музыкой , вкусные угощения, крутые и полезные доклады - все это оставило приятные впечатления. Рекорд регистраций был побит 🏆

Я выступал первым - запись выступления можно найти тут:
⚡️ YouTube
⚡️ VK

Спасибо нашей отличной команде организаторов 😎

#frontend #js #meetup
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥9👍3
🧑‍💻 Инкапсуляция контекста

На досуге решил поизучать как устроен Fastify - фреймворк для Node.js. Если вы еще не знакомы с ним - советую присмотреться повнимательнее: он обещает высокую производительность и гибкость благодаря минимальному оверхеду и продуманномой архитектуре.

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

🤔 Что такое инкапсуляция контекста?

Это способ организации кода таким образом, чтобы каждый хук/декоратор/плагин имел доступ лишь к нужным объектам данных, т.е. к нужному контексту (см. картинку). Это помогает избежать проблем с глобальными обработчиками, сплетением хуков/обработчиков/переменных внутри проекта. Фактически, это значит, что ваш код становится чище и проще в поддержке.

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

Fastify документация:
https://fastify.dev/

Про инкапсуляцию:
https://fastify.dev/docs/latest/Reference/Encapsulation/

#fastify #nodejs #javascript #typescript #js #ts #frontend #webdev #context
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Приглашаю в Сетку - соц сеть для нетворкинга от hh.ru ⭐️

Пробил 500 подписчиков в сетке, а так же получил мерч за участие в новогоднем конкурсе! 🎁

Подписывайся, давай нетворкаться вместе )
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥3❤1
С Новым годом 🎉

Пусть в 2026 ваш код работал без багов, тесты покрывали все сценарии, пайплайны не падали, поставки были в срок, сервера выдерживали нагрузку, память не текла, соблюдались SLA, перевыполнялись планы и KPI, выполнялись все поставленные задачи, юзер стори и цели 🎯

Ну и по классике: счастья! Здоровья! Ура! 🎄 🎉🎅
❤2🎉2☃1🍾1
Sourcecraft - сайт из репозитория за один клик

Поизучал Sourcecraft — платформу для разработки приложений от Яндекса. Основные возможности: хранение и аудит кода с помощью ИИ, полноценные CI/CD инструменты, интеграция с Yandex Cloud ☁️, анализ уязвимостей и плагины для популярных IDE.

Заметили, что Code Assistant из Sourcecraft уже встроен прямо в статьи на Хабре? Теперь можно попросить ассистента объяснить сложные участки кода из текста — удобно! 😎

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

А ещё есть Sourcecraft Sites — бесплатный хостинг статических сайтов прямо из репозитория за один клик! Вот эту штуку точно надо попробовать 👀.

А вам как Sourcecraft? Уже пробовали? 🤔
🔥1
Впуклые углы заказывали?

https://habr.com/ru/articles/987944/

#note@usyninis_dev
🤓1
Навайбкодился

В январе решил плотно повайбкодить в Cursor — генерил отдельные UI формы, тапалки, различные фабрики с поддержкой типизации - результаты реально впечатляют ✨👍

Но есть нюанс: лимит токенов закончился довольно быстро (подписка pro). Следующий шаг — разобраться, как именно расходуются токены 🤔: что съедает больше всего (промты/файлы в контексте), и как набить руку так, чтобы профит от использования остался высоким, а лимиты не сгорали за пару сеансов.

Если у кого-то уже есть практический опыт оптимизации расхода токенов — делитесь лайфхаками, будет интересно узнать 👀
🔥3😁1
TanStack Query — польза инструмента на практике

Более 2 лет назад мы стартанули с нуля разработку нашего платформенного проекта, много времени уделив анализу и подбору подходящих и актуальных библиотек и инструментов.

Для взаимодействия с серверными данными был выбран TanStack Query (ранее известный как react-query). Вот несколько практических примеров в реальных задачах 👇

1️⃣ Гибкая система инвалидации кэша

Есть у нас UI который рисует граф (дерево) сущностей. При обновлении одной точки или связей надо перерисовать точку и дочерние ветки. При правильном указании queryKey и запуске в нужный момент invalidateQueries ваш UI автоматически перерисуется в нужных местах.

// получаем данные
useQuery({
queryKey: [‘schema’, itemKey]
})

// инвалидируем после обновления
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [‘schema’, itemKey] });
},


💡 Еще лучше — когда ключи генерируются в одном месте (утилитой/фабрикой), чтобы со временем ключи не разъехались.

2️⃣ Не простой refetchInterval

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

useQuery({
queryFn: // получение данных
refetchInterval: (query) => {
if (query.state.data?.statusCode === STATUS_CODE.WAITING) {
return REFETCH_WAITING_INTERVAL;
}

return false;
},
})


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

3️⃣ Всевозможные статусные состояния и refetch

useQuery и useMutation возвращает различные флаги: isLoading, isFetching, isError и т.д. Все это позволяет с точностью отображать загрузки/ошибки в нужном вам дизайне. В нашем случае таблица сперва загружается со скелетоном, а следующих апдейтах скелетон отображается только в строках таблицы. При ошибках загрузки остается только навешать refetch в нужную кнопку на UI.

👨‍💻 После реализации множества наших микрофронтов я бы сказал, что являюсь фанатом этой библиотеки :)

А ведь у TanStack есть еще router, store и прочие инструменты. А вы используете что-нибудь от TanStack?
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
React.lazy — еще один полезный сценарий 🚀

Одни из самых популярных кейсов использования React.lazy + Suspense — динамическая загрузка отдельных страниц или тяжелых библиотек:

// code splitting по роутам
const Dashboard = lazy(() => import('./Dashboard'));

<Route path="/dashboard" element={<Suspense fallback={<Loader />}><Dashboard /></Suspense>} />

// code splitting для тяжелых библиотек
const ImageEditor = lazy(() => import('./ImageEditor'));

<Suspense fallback={<Loader />}><ImageEditor /></Suspense>


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

👨‍💻 Для подобных сценариев можно собрать компонент-контейнер с Suspense+ErrorBoundary, который будет показывать процесс загрузки и отлавливать ошибки независимо от уровня вложенности remote-модулей. Итоговая структура выглядит так:

// контейнер для remote-модулей 
const ModulesContainer = ({ loadingView, errorView, children }) => (
<Suspense loadingView={loadingView}>
<ErrorBoundary errorView={errorView}>
{children}
</ErrorBoundary>
</Suspense>
);

// используем модули на любом уровне с одним лоадером:
<ModulesContainer
loadingView={<CustomLoader />}
errorView={<CustomError />}
>
<ComponentHeader>
<ComponentBody>
<RemoteModule2 value="a" />
</ComponentBody>
</ComponentHeader>
<RemoteModule1 value="b" />
</ModulesContainer>


P.S.: Не забываем логировать ошибки в ErrorBoundary! 📊

#react #microfrontends #lazy #js #javascript #typescript #frontend #фронтенд #разработка #dev #webdev #react #nodejs
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥4
Поздравляю прекрасных дам с 8 Марта!

Пусть весна цветет не только на улице, но и в душе!

Ну а чтобы сделать такой градиент+ascii-арт или прокачать ваши cli-скрипты прикладываю набор полезных npm-пакетов, в том числе, которые использую в работе:

1. Это база - различные утилиты для цветного текста в консоли:
https://www.npmjs.com/package/chalk

2. Для написания текста через ascii символы:
https://www.npmjs.com/package/figlet

3. Для окрашивания градиентом результатов вызова в консоль:
https://www.npmjs.com/package/gradient-string

4. Обводка текста рамкой (блоком):
https://www.npmjs.com/package/boxen

5. Готовая уведомлялка в консоль про выход новой версии вашего npm-пакета:
https://www.npmjs.com/package/update-notifier

6. Готовый лоадер в консоли для ваших скриптов с поддержкой смены статусов и текста:
https://www.npmjs.com/package/ora

7. Отображение красивых шрифтов в консоли:
https://www.npmjs.com/package/cfonts

8. Готовые шаблоны для вывода уведомлений об успехе, ошибках или предупреждениях:
https://www.npmjs.com/package/cli-alerts

👨‍💻 Ну и на последок - фреймворки для интерактивного взаимодействия вашего скрипта с пользователем через консоль:
https://www.npmjs.com/package/commander
https://www.npmjs.com/package/inquirer
https://www.npmjs.com/package/@clack/core
https://www.npmjs.com/package/@oclif/core

#js #javascript #typescript #frontend #фронтенд #разработка #dev #webdev #react #nodejs
Please open Telegram to view this post
VIEW IN TELEGRAM
❤6🔥1
Выступил с лекцией в ITHub

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

Я выступил c лекцией о том, какой путь ждет студентов-разработчиков выходящих на рынок труда и поделился практическими советами для развития компетенции frontend.

Спасибо ITHub за приглашение! Каждый визит сюда - это погружение в атмосферу студенчества в сочетании с ИТ-технологиями!
🔥8
This media is not supported in your browser
VIEW IN TELEGRAM
Remotion: make videos programmatically 📹

Remotion — это программный фреймворк, который позволяет создавать видеоролики и моушен-графику с помощью кода, используя веб-технологии: React, HTML, CSS и JavaScript. Вместо традиционного монтажа вы описываете видео компонентами, а затем компилируете их в MP4 или GIF.

Говорят что аудитория инструмента — front-разработчики и команды, занимающиеся автоматизацией видеоконтента. Если вы уже умеете писать на React, кривая обучения получается почти нулевой: анимации задаются пропсами и хуками, а не перетаскиванием слоёв мышкой.

Немного поигрался в Remotion — скормил свой профиль в сетке через ИИ, вот что получилось ☝️
🔥3
RBAC и permission-based проверки на frontend: как мы управляем доступом на проекте 🔐

В больших системах требуется гибкая и масштабируемая модель прав. Классическая проверка доступа строится вокруг ролей: пользователь получает одну или несколько ролей (например, admin, manager, viewer), и каждая роль содержит набор разрешений.

Однако при использовании такого подхода появляются проблемы:
- Роли начинают разрастаться и дублировать друг друга.
- Возникают “почти одинаковые” роли с минимальными отличиями.
- Сложно управлять точечными исключениями: если одному пользователю нужно дать доступ только к одной дополнительной кнопке, добавлять новую роль становится избыточно.

Чтобы решить эту задачу и избежать подобных проблем мы используем комбинацию RBAC (Role-Based Access Control) и permission-based подхода ⚙️

У нас есть два уровня:

1 уровень — группы пользователей (можно назвать их ролями: admin, manager, top-manager и т.д).

Это верхнеуровневая агрегация прав. Группа содержит набор доступных для неё permissions.

2 уровень — permissions (разрешение на выполнение действия)

Это атомарные флаги, которые описывают конкретное действие:
- user.edit
- order.create
- order.cancel
- feature.toggleX

Конечный пользователь в итоге получает список доступных permissions через включение его в группы + индивидуальные permissions.

Как это выглядит на frontend

После аутентификации backend возвращает список permissions пользователя. Frontend не работает напрямую с кодами групп/ролей — только с уже “развернутыми” permissions.

const canEdit = usePermission('user.edit');

return <Plate>{canEdit && <EditButton />}</Plate>;


Такой подход даёт баланс между управляемостью и гибкостью: роли упрощают администрирование, permissions позволяют точно контролировать поведение интерфейса, а изменение прав пользователей осуществляется без доработок front/back-сервисов ✨
👍5🔥1
cva: когда обычного сlsx уже мало

Пока у кнопки два состояния — «обычная» и «выключенная» — легко склеить классы через clsx:
<button className={clsx("btn", isDisabled && "btn-disabled")} />

Но стоит появиться трём размерам и трём цветам, как в className начинается каша из условий. cva (class-variance-authority) помогает удобно описывать варианты стилей компонента — размеры, цвета, состояния. Внутри он использует clsx, так что это не замена, а надстройка над ним.

Основная идея

cva предлагает описать все варианты один раз и в понятном виде:
- variants — какие вообще варианты есть (размер, цвет и т.д.);
- defaultVariants — что ставить, если ничего не передали;
- compoundVariants — особые классы для конкретных сочетаний;
- VariantProps — готовые типы для пропсов компонента.

В ответ получаем функцию: передали в неё варианты — получили готовую строку классов. clsx при этом никуда не делся — cva склеивает классы через него.

Пример

import { cva, type VariantProps } from "class-variance-authority";

const button = cva("btn", {
variants: {
intent: {
primary: "btn-primary",
danger: "btn-danger",
},
size: {
sm: "btn-sm",
md: "btn-md",
},
},
compoundVariants: [
{ intent: "primary", size: "sm", className: "btn-uppercase" },
],
defaultVariants: { intent: "primary", size: "md" },
});

// выводим типы из описания вариантов
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> &
VariantProps<typeof button>;

export function Button({ intent, size, className, ...props }: ButtonProps) {
return <button className={button({ intent, size, className })} {...props} />;
}


Частые ошибки


- Тянуть cva туда, где хватает одного-двух условий, — обычный clsx проще и легче.
- Забыть про defaultVariants — и в каждом месте вызова вручную передавать одни и те же варианты.
- Продублировать описание вариантов в нескольких компонентах вместо одного общего.

Итог

clsx отвечает на вопрос «добавить ли этот класс?», а cva — «как устроены все варианты компонента?». Если условий одно-два, clsx вполне хватает. 👉 Как только появились размеры, цвета, дефолты и сочетания — используем cva.

#js #javascript #typescript #frontend #фронтенд #разработка #dev #webdev #react
🔥2