Frontender's notes [ru] – Telegram
Frontender's notes [ru]
33.8K subscribers
579 photos
38 videos
1 file
3.43K links
Ведущий канал о современном фронтенде: статьи, новости и практики.

По вопросам рекламы или разработки:
@g_abashkin

РКН: https://vk.cc/cJPG6y
Download Telegram
Proxy и Reflect: как сделать работу с объектами удобнее

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

💬 Логирование и отладка

// Представьте, что вам нужно отследить, кто и когда обращается к объекту. Вместо того чтобы забивать код десятками console.log, можно просто использовать Proxy для перехвата. Теперь любое обращение к объекту будет логироваться. Это очень удобно, если вы работаете с большими стейтами, как в Vue или MobX.

const user = { name: "Alex", age: 25 };

const loggedUser = new Proxy(user, {
get(target, prop) {
console.log(`GET ${prop}`);
return Reflect.get(target, prop);
},
set(target, prop, value) {
console.log(`SET ${prop} = ${value}`);
return Reflect.set(target, prop, value);
}
});

loggedUser.name; // GET name
loggedUser.age = 26; // SET age = 26


💬 Валидация данных

// Proxy может отловить некорректные значения и не дать им попасть в бизнес-логику. С таким подходом можно сделать простые data-models без классов и лишнего кода. Валидация и контроль за данными — проще не бывает.

const product = new Proxy({}, {
set(target, prop, value) {
if (prop === 'price' && value < 0) {
throw new Error("Цена не может быть отрицательной");
}
return Reflect.set(target, prop, value);
}
});


💬 Reflect: безопасный доступ

// Reflect — набор методов для безопасной работы с объектами. Они выполняют стандартные операции, но предотвращают неожиданные ошибки и обеспечивают предсказуемое поведение.

Reflect.get(obj, 'key'); // вместо obj.key
Reflect.set(obj, 'key', 'value'); // возвращает true/false, не выбрасывает ошибки

// Комбо с Proxy выглядит так:
const safe = new Proxy(obj, {
get: (t, p) => Reflect.get(t, p),
set: (t, p, v) => Reflect.set(t, p, v)
});


📌 Реактивность, которую вы видите во Vue 3, MobX и других фреймворках, тоже во многом основана на Proxy. Этот инструмент позволяет «подписываться» на изменения данных и автоматически обновлять UI, не меняя структуру данных. Proxy и Reflect — мощные инструменты. Используйте их правильно, и вы сможете строить эффективные слои логирования, валидации и реактивности без лишнего кода и сложных хаков.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍124🐳1
⭐️ Utility-first CSS: больше, чем просто Tailwind

Многие, когда слышат термин utility-first CSS, сразу думают о Tailwind. Но на самом деле это не просто фреймворк, а подход к верстке. Tailwind лишь помог сделать этот подход популярным. Давайте разберёмся, что это за стиль и как его можно применить.

👀 Что такое utility-first?

<!-- В классическом CSS мы описываем сущности. Utility-first CSS — это немного другой подход. Вместо того чтобы описывать компоненты, мы описываем свойства. Каждый класс — это атомарная единица стиля, которая выполняет одно действие. Когда нужно собрать сложный элемент, мы комбинируем несколько таких атомов, чтобы получить нужный результат -->

<button class="bg-black text-white rounded-lg px-4 py-2">Click</button>


👏 Почему этот подход работает?

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

• Изолированность без сложных каскадов. Нет таких длинных цепочек, как .card .button.active:hover. Всё работает локально и предсказуемо.

• Нужно создать новый элемент? Просто комбинируешь существующие утилиты, без копирования и написания новых классов. Не нужно писать «ещё одну кнопку, только поменьше».

• Если нужно изменить отступы, это быстрее, чем искать, где в CSS заданы padding. Например, меняем класс px-4 на px-6 и сразу видим результат.


📣 Но utility-first ≠ Tailwind

Этот подход можно применить и без фреймворка.

— Заведи слой утилит в обычном CSS:

.flex { display: flex; }
.gap-2 { gap: 0.5rem; }
.text-sm { font-size: 14px; }

— Используй CSS custom properties для хранения токенов, как --color-primary, --space-sm.
— Используй PostCSS или UnoCSS, чтобы собирать утилиты динамически.


Когда это не работает?

Если команда не договорится об atomic naming и начнёт использовать названия вроде text-12px flex1 mt-8px, это может привести к путанице и усложнить понимание кода. Особенно это критично в проектах без дизайн-системы, где утилиты могут превратиться в хаос. В таких ситуациях лучше использовать гибридный подход, комбинируя утилитарный стиль с обычными компонентами, чтобы обеспечить масштабируемость и переиспользование блоков.


📌 Utility-first CSS — это создание маленьких, независимых стилей для переиспользования и изменения. Это не монолитные архитектуры, а атомарные единицы, которые можно применять в чистом CSS, CSS-in-JS и других фреймворках. Tailwind упрощает этот подход. Забудь про гигантские CSS-классы, строй стиль на атомах!

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7👎71
👥 Что скрывает псевдо-класс :not() в CSS?

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

❗️ Основы использования :not() и множественные условия

Вы наверняка знаете, что :not() используется для исключения элементов с определенным классом или позицией в списке. Например, стиль применяется ко всем элементам .link, кроме последних в списке. Однако :not() позволяет комбинировать несколько условий. Код применяет стиль ко всем img без атрибута class и не являющихся первыми детьми в родительском элементе. Это возможно благодаря тому, что :not() принимает несколько селекторов, разделённых запятыми.


📝 Пример
/* Базовое применение */
.link:not(:last-child) {
margin-left: 1rem;
}

/* Применение для всех img, кроме тех, у которых есть атрибут class */
img:not([class], :first-child) {
margin-block-start: var(--ds-typography-img-margin-block-start, var(--_ds-typography-main-margin));
}


👩‍🎨 Сложные селекторы: :not() и :has() для детальной настройки стилей

Что если вы хотите применить стиль только к тем элементам, которые не содержат в себе определённого соседа? Это легко сделать, используя комбинацию :not() и :has(). В примере стиль background-color: lightblue применяется ко всем параграфам <p>, за которыми не следует элемент <h2>. Это позволяет точно контролировать, какие элементы подвергать стилизации, не добавляя лишних классов или элементов разметки.


📝 Пример
<body>
<h1>Париж</h1>
<p>Столица и крупнейший город Франции...</p>
<h2>История</h2>
<p>Париж вырос на месте поселения...</p>
<p>Поселение располагалось на безопасном острове...</p>
</body>

/* Применяем стиль только к параграфам, за которыми не следует элемент h2 */
p:not(:has(+ h2)) {
background-color: lightblue;
}


📌 Идея за :not()

Псевдо-класс :not() — это просто огонь-фича для тех, кто любит делать код проще и понятнее. Он позволяет исключать элементы по разным условиям, что значительно упрощает создание сложных селекторов. В отличие от старых методов, :not() даёт вам больше свободы и точности.

С его помощью можно создавать более чистые и понятные разметки, которые легко подстраиваются под изменения в структуре документа. Это как улучшенная версия селекторов :first-child или :last-child, только с гораздо большими возможностями.


🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍103🐳1
⬆️ Почему важно тестировать интерфейсы, и какие инструменты для этого использовать

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

👁 Почему стоит тестировать интерфейсы?

Интерактивность и поведение: Простой пример — форма, которая не отправляется после клика, или чекбокс, который не обновляет свой статус. Такие вещи сложно отловить вручную, но они могут стать причиной огромного недовольства пользователей.

Кросс-браузерность и адаптивность: Интерфейс может выглядеть идеально в Chrome, но ломаться в Safari или на мобильном. С тестами таких проблем можно избежать, проверяя поведение компонентов на разных устройствах и браузерах.

UI/UX баги: Строго говоря, это не «классовые» баги, а проблемы, которые влияют на восприятие приложения. Несоответствие дизайну, неправильные анимации — всё это может уйти незамеченным в процессе обычного тестирования, но сказаться на восприятии вашего продукта.


💼 Какие инструменты использовать для тестирования интерфейсов?

👀 Cypress: Простой и мощный инструмент для энд-ту-энд тестирования. Он позволяет тестировать, как ваш интерфейс ведет себя в реальных сценариях: клики, заполнение форм, навигация, и многое другое. Cypress особенно удобен для динамичных SPA-приложений, где важно протестировать все возможные переходы и взаимодействия.

👀 Если вам нужно больше гибкости, попробуйте Playwright. Он поддерживает тестирование нескольких браузеров и идеально подходит для тестирования UI на разных платформах, таких как Chrome, Firefox и WebKit. А ещё, в отличие от Cypress, Playwright поддерживает тестирование мобильных устройств из коробки.

👀 React Testing Library: Если вы работаете с React, этот инструмент поможет вам тестировать компоненты с учётом пользовательских взаимодействий. Он фокусируется на тестах, которые проверяют не только логику, но и правильное поведение в контексте UI. Например, как компоненты реагируют на пользовательский ввод или как они отображаются при разных состояниях.

👀 В случае, если вам нужно тестировать поведение интерфейса в браузере, Puppeteer — это тот инструмент, который поможет вам автоматизировать тесты в реальных браузерах. Это идеальный выбор для UI-тестов, где важен контроль над браузерными событиями и точность.


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

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍71
Связность и сцепленность. Почему код живёт или умирает.

Недавно наткнулся на пост Темы Сенюкова из Кинопоиска про Cohesion и Coupling. Кажется, это одни из тех базовых понятий, которые ты вроде знаешь, но понимаешь только после кучи сделанных ошибок.

С опытом начинаешь видеть закономерность: код умирает не потому, что «технология устарела» или «всё переписали на React 19». Он умирает, потому что у него нарушен баланс — внутри всё плохо связано, а снаружи всё переплетено.

Когда связность (cohesion) низкая — модуль делает всё подряд: загружает данные, форматирует дату, логирует аналитику и варит кофе юзеру. Заходишь туда через полгода — и не понимаешь, что и где.

Когда сцепленность (coupling) высокая — любое изменение где-то «там» ломает всё «здесь». Изменили API? Привет, бесконечный refactor. Поменяли store? Упало полстраницы.

В какой-то момент я перестал смотреть на код просто как на функции и компоненты. Теперь я думаю о нём как о «разговорах» между кусками приложения. Хороший код — это когда эти разговоры короткие и по делу. Плохой — когда все орут непонятно что.

Вот пара мыслей, которые реально помогают:

🟢 Делайте компоненты, которые умеют ровно одно. Остальное пусть решают «соседи».
🟢 Прокидывайте зависимости явно — пусть всё, что нужно компоненту, приходит снаружи.
🟢 Разделяйте слои. Данные, логика, UI — три мира, не обязанные знать детали друг друга.
🟢 И самое главное — не бойтесь «резать» код. Маленькие куски легче понимать, менять и тестировать.

Это те вещи, которые определяют, живёт ли ваш проект дольше полугода
👍122
📖 Почему стоит использовать transform и opacity для анимаций

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

⬅️ Что происходит при анимации обычных свойств

Анимация свойств, таких как width, height, margin, padding, top и left, требует от браузера выполнения нескольких ресурсоёмких шагов: Reflow (пересчёт размеров и расположения элементов), Repaint (перерисовка частей страницы) и отображение на экране. Эти процессы могут значительно замедлить работу страницы, особенно при большом количестве элементов, что негативно сказывается на её производительности.


Как сделать анимации более быстрыми и плавными

Для повышения производительности веб-анимаций рекомендуется использовать свойства, обрабатываемые графическим процессором (GPU), вместо центрального процессора (CPU). Это позволяет избежать лишних вычислений и ускоряет отображение, особенно при анимации таких свойств, как transform (например, translate, scale, rotate) и opacity (прозрачность). В этих случаях браузеру не нужно пересчитывать размеры элементов или перерисовывать всю страницу, так как изменения происходят на уровне графики, что значительно улучшает производительность.


Пример плохой и хорошей анимации анимации

/* Когда вы анимируете left, браузер выполняет перерасчёт и перерисовку страницы. Этот способ медленный, так как каждый сдвиг элемента требует выполнения операций reflow и repaint. */

.element {
transition: left 0.5s ease;
}

/* При использовании transform, браузер просто сдвигает элемент на графическом уровне, избегая дополнительных перерасчётов. Здесь браузер применяет изменения только на уровне GPU, что делает анимацию плавной и быстрой. */

.element {
transition: transform 0.5s ease;
}


📌 Если хочешь, чтобы анимации на твоей странице были плавными и шустрыми, используй свойства transform и opacity. Они не заставляют браузер пересчитывать размеры и перерисовывать элементы, так что сайт будет работать быстрее.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍15🔥93
Псевдо-классы :user-valid и :user-invalid: как исправить проблему с изначальными стилями

При создании форм часто встречаются обязательные поля. Они могут быть заполнены верно или нет. Для стилизации этих состояний обычно используют псевдо-классы :valid и :invalid. Эти классы применяются сразу после загрузки страницы, даже если пользователь ещё не успел взаимодействовать с полем. Это может раздражать из-за некорректного отображения. Рассмотрим, как можно исправить и улучшить ситуацию.

🔎 Вот пример того, как эти псевдо-классы работают по умолчанию:

<<!-- Первое поле с логином зелёное (корректно заполнено). Второе поле с паролем красное (пусто и недействительно) -->
<body>
<form class="form">
<div class="form__group">
<label for="name">Введите логин</label>
<input id="name" type="text" value="melnik909" required>
</div>
<div class="form__group">
<label for="password">Введите пароль</label>
<input id="password" type="password" required>
</div>
<button>Войти</button>
</form>
</body>

<style>
input:invalid {
box-shadow: 0 0 10px red;
}

input:valid {
box-shadow: 0 0 10px green;
}
</style>


Псевдо-классы :user-valid и :user-invalid

Для предотвращения преждевременного применения стилей добавлены псевдо-классы :user-valid и :user-invalid, которые активируются при взаимодействии пользователя с полем. Стили применяются только после ввода данных. Давайте заменим старые псевдо-классы на новые:

input:user-invalid {
box-shadow: 0 0 10px red;
}

input:user-valid {
box-shadow: 0 0 10px green;
}


📌 Теперь форма будет выглядеть нормально сразу, и стили начнут применяться, только когда пользователь начнёт что-то вводить. Это делает интерфейс более удобным и понятным.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍95🔥2
Forwarded from xCode Journal
Media is too big
VIEW IN TELEGRAM
🤖 Том был первым, кто потерял работу из-за ИИ:

💥 xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
😁38👎4🔥4👍2👀2
#react #вакансия

Позиция: Fullstack Web Developer (React + Next.js)
Компания: MiningPool
Формат работы: удаленка
Занятость: полная
Вилка: $2500-$4000

Ты построишь клиентский кабинет: UI для мониторинга, биллинга, управления воркерами и токенами. Это роль с упором на React и Next.js, с лёгкой интеграцией backend API, аутентификацией и авторизацией.

Зоны ответственности:
* Реализация интерфейса Dashboard: статистика хешрейта, состояние воркеров, лимиты и токены доступа, история начислений
* Интеграция с Clerk (аутентификация, RBAC)
* Подключение REST API (на Rust)
* Фронтовая бизнес-логика: генерация воркеров, отображение статусов, установка ограничений
* Создание простых визуализаций (charts, таблицы, фильтры)

Технологии:
* React, Next.js, Tailwind, shadcn/ui
* Clerk SDK (auth)
* REST API (axios, react-query или SWR)
* PostgreSQL (через API), Supabase.

Требования:
* 2+ года опыта с React / Next.js
* Уверенная работа с REST API и Auth SDK
* Умение быстро проектировать UI на Tailwind или shadcn
* Знание баз данных на уровне SQL и умение читать EXPLAIN — большой плюс

Для связи и отправки резюме:
@dishsh
3👎3🔥2🐳1
🔫 Как использовать requestIdleCallback для улучшения производительности

Когда говорим о производительности веб-приложений, вспоминаем уменьшение веса страниц и оптимизацию кода. Однако есть requestIdleCallback — это API для запуска задач в моменты, когда браузер не занят важными операциями, например, рендерингом или обработкой событий. Это идеальный способ для фоновых задач, таких как загрузка или обработка данных, без влияния на пользовательский интерфейс и основные операции.

Когда использовать?

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


ℹ️ Пример кода:

/* Предположим, вы хотите загрузить данные с API в фоновом режиме. Вместо того чтобы инициировать запрос сразу и блокировать основной поток, можно использовать requestIdleCallback: */
function fetchDataInIdleTime() {
requestIdleCallback(() => {
fetch('/some-api')
.then(response => response.json())
.then(data => {
console.log('Data loaded in idle time:', data);
})
.catch(error => console.error('Error loading data:', error));
});
}

fetchDataInIdleTime();


Как это работает

— Мы создаём функцию fetchDataInIdleTime(), которая запускает requestIdleCallback.

— Внутри колбэка выполняем асинхронный запрос к серверу.

— Запрос будет выполнен в момент, когда браузер освободится от важных задач, таких как рендеринг или обработка событий.

— Таким образом, мы делаем загрузку данных менее приоритетной и не нагружаем браузер, пока он не свободен.


📌 Этот метод позволяет выполнять фоновые задачи без задержек для пользователя, экономя ресурсы и улучшая общую производительность. Довольно удобно и эффективно!

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3🔥32👀2
Intersection Observer API: как улучшить производительность и UX в 2025 году

Технологии не стоят на месте, и в 2025 году Intersection Observer API продолжает развиваться и становится важным инструментом для веб-разработчиков. Этот API не только помогает улучшить производительность, но и заметно повышает качество взаимодействия с пользователем. Давайте разберемся, почему вам стоит обратить на него внимание, и как он может упростить вашу жизнь.

➡️ Что такое Intersection Observer?

Intersection Observer API отслеживает видимость элементов, оптимизируя загрузку контента. Он не требует постоянного мониторинга прокрутки или размера окна. Вместо этого, API реагирует только на изменения видимости, активируя логику, например, загрузку изображений или анимаций, когда пользователь достигает нужного места. Это сокращает ненужные рендеры и повышает производительность. Меньше вычислений, меньше данных — это особенно важно на устройствах с низкими характеристиками.


ℹ️ Пример кода:

const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
// Загружаем изображение, когда оно попадает в область видимости
entry.target.src = entry.target.dataset.src;
observer.unobserve(entry.target);
}
});
});

const images = document.querySelectorAll('img.lazy');
images.forEach(img => observer.observe(img));


Объяснение кода

— Предположим, вы хотите отложить загрузку изображений до тех пор, пока они не окажутся в области видимости.
— Здесь мы создаём новый IntersectionObserver.
— Для каждого изображения с классом .lazy, как только оно появляется в зоне видимости, происходит загрузка изображения.
— Весь этот процесс запускается только в нужный момент, что минимизирует ненужные операции.


📌 В общем штука реально неплохая и может вам пригодиться в ваших проектах.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍95
Forwarded from xCode Journal
🖥 Инструмент для разработчиков, которым нравится копаться под капотом

Вводи в адресную строку Chrome: chrome://chrome-urls и открываем список всех внутренних страниц браузера: от отладочных тулзов до экспериментальных фич. Внутри:
- chrome://flags → скрытые настройки
- chrome://gpu → информация о работе GPU
- chrome://net-export → отладка сети

✖️ xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍92🐳1
Forwarded from xCode Journal
🤣 Весомый аргумент

💥 xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
😁133
⬆️ Container Queries — новый подход к адаптивной вёрстке

Адаптивный дизайн изначально базировался на @media с условием: если ширина экрана меньше 768px, уменьшаем шрифт. Но проблема в том, что компоненты могут адаптироваться по-разному в зависимости от контекста (сайдбар, карточка, модальное окно), даже при неизменном размере экрана. Media queries реагируют только на размер viewport, а не на размеры родителя. Container Queries позволяют учитывать размеры родительского контейнера, что даёт CSS возможность адаптировать компоненты в зависимости от контекста.

ℹ️ Пример кода:

.card {
container-type: inline-size;
}

@container (max-width: 400px) {
.card-noscript {
font-size: 1rem;
}
}


Как это работает?

• Мы объявляем контейнер с помощью свойства container-type.
• Пишем условие с @container, чтобы адаптировать элементы внутри контейнера.
• Компонент автоматически адаптируется под размеры своего родителя, а не под весь экран.
• Теперь компоненты не зависят от глобальных media queries и могут быть использованы в любом месте без дополнительных хаков или специфичных классов.
• Можно описывать адаптив прямо в компонентах, как это делают дизайнеры в Figma. Теперь ваш CSS гораздо точнее отражает реальные потребности.
• Сокращается использование JS для адаптивных изменений и избавляет от необходимости работать с множеством media queries, что делает код чище.


📌 Современные браузеры теперь поддерживают Container Queries без всяких дополнительных префиксов. Это как React для CSS: теперь адаптивный дизайн можно делать локально и контекстно, как будто у каждого элемента свой мини-сайт.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11🔥81
Forwarded from Технотренды
⚡️ Запускаем крупный розыгрыш призов, где можно выиграть iPhone 17, игровые наушники, клавиатуру и мышь!

Без лишних слов, условия:

1. Подписка на:
бизнестрендс
Технотренды
Блумберг
2. Нажать кнопку «Участвовать» снизу

Итоги будут опубликованы 15 ноября в 18:00 на наших каналах, желаем удачи!
😁1
📝 Structuring large JS/TS проектов — как не утонуть в своём же коде

Проект начинается с идеальной структуры в src/, но через год появляются папки вроде utils, helpers, components-old, нарушая порядок. Архитектура страдает, так как файлы растут быстрее структуры. Как избежать хаоса и не утонуть в коде?

💡 Что работает на практике?

— Feature-sliced design (FSD)
В проекте можно использовать подход, при котором структура делится не по типу файлов, а по функциональности. Например, вместо создания папок для компонентов и утилит организуется структура вокруг функциональных блоков. В папке src создаются разделы: entities, features, pages и shared. Каждая «фича», например, авторизация или профили пользователей, изолирована и имеет свой пользовательский интерфейс, бизнес-логику и сервисы. Это облегчает масштабирование проекта и предотвращает поломку старых функций при добавлении новых.

— Domain-first подход
Теперь ты называешь папки не components, hooks, utils, а по именам бизнес-областей: auth/, profile/, dashboard/. Это упрощает понимание контекста и делает код более организованным.

— Index-файлы как интерфейсы
Каждый модуль экспортирует наружу только то, что нужно. Это помогает уменьшить сцепленность между модулями и делает импорты предсказуемыми.

// Ты исключаешь импорт ненужных частей и делаешь структуру кода более читаемой.
// features/login/index.ts
export { LoginForm } from './ui/LoginForm';
export { useLogin } from './model/useLogin';


— Слои зависимостей
Организуй проект так, чтобы зависимости двигались в одном направлении: от UI → Features → Entities → Shared. Никаких цикличных импортов или «вверх по слоям». Архитектура будет выглядеть как дерево зависимостей, а не как хаотичная паутина.


💼 Инструменты для упрощения

— TypeScript path aliases: Используй алиасы для упрощения импорта, например: @/shared, @/features/auth.

— ESLint rules: Настрой правила для контроля правильности импортов между слоями.

— Barrel files (index.ts): В каждом модуле используй index.ts для экспортирования публичных интерфейсов. Это поможет сократить количество файлов и сделать структуру более понятной.

— Nx / Turborepo: Эти инструменты идеально подходят для крупных монорепозиториев, где нужно поддерживать чистоту и порядок.


📌 Структура проекта — это не просто папки и файлы. Это ограничения, которые помогают команде думать одинаково. Если проект можно читать без ментального GPS, значит, структура удалась. Это ключ к успешной разработке и долгосрочной поддержке.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
5👎1👀1
Forwarded from xCode Journal
🦾 Нашли для вас опенсорсную альтернативу Postman — Yaak

Можно импортировать коллекции из Postman, использовать переменные окружения, хранить ключи в системном хранилище и даже кастомизировать интерфейс

Работает просто магически.

✖️ xCode Journal
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍4🔥2
⚡️ Web Animations API или CSS transitions: какой инструмент выбрать для анимаций?

Когда речь заходит об анимациях на фронтенде, мнения расходятся: одни говорят, что для большинства случаев достаточно CSS transitions, а другие утверждают, что только Web Animations API даёт полный контроль над процессом. Давайте разберёмся, что из этого действительно нужно в вашем арсенале.

ℹ️ Для большинства стандартных анимаций CSS transitions — это отличный выбор

/* CSS transitions идеальны для UI-элементов, таких как кнопки, модальные окна и спиннеры */
.button {
transition: transform 0.2s ease;
}

.button:hover {
transform: scale(1.05);
}


• Лёгкость в реализации
• Браузер сам оптимизирует процесс анимации
• Подходит для простых эффектов: hover, fade-in/out, микровзаимодействий
• Нельзя ставить анимацию на паузу, изменить скорость или реверсировать её
• Не подходит для сложных или кастомных анимаций


👁 Web Animations API — полный контроль

// Это инструмент для более сложных анимаций: от секвенций и кастомных интеракций до scroll-анимаций
el.animate(
[{ transform: 'translateX(0)' }, { transform: 'translateX(100px)' }],
{ duration: 500, easing: 'ease-out', fill: 'forwards' }
);

// Лёгкость в синхронизации
// Можно комбинировать с библиотеками, такими как GSAP или React
// Можно ставить анимацию на паузу, ускорять, реверсировать
// Необходимость писать больше кода, чем для CSS


📌 А если хочется и простоты, и гибкости — можно комбинировать оба подхода. Используйте CSS для базовых эффектов и Web Animations API для более сложных сценариев.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍74👎1😁1🐳1
🔫 Accessibility 2.0 — не просто тренд, а новая норма

Когда-то доступность в веб-разработке воспринималась как что-то дополнительное. Ты просто добавляешь alt-тег, прописываешь aria-label и считаешь, что все сделал. Сегодня все изменилось. Доступность стала неотъемлемой частью UX, SEO и даже бренда.

ℹ️ Что меняется?

Доступность как часть производительности
Теперь доступность тестируется так же, как и производительность. Инструменты вроде Lighthouse, axe-core и SonarLint уже встроены в CI/CD. Ошибки a11y не остаются на потом, а реально блокируют билд, если что-то идет не так.

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

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


Инструменты 2025 года

• axe DevTools — проводите автоматические проверки доступности прямо в браузере.

• Polypane / Responsively App — визуализируйте интерфейсы с учетом различных состояний, включая цветовую слепоту и контрастность.

• Figma Contrast & A11y plugins — проектируйте интерфейсы с учетом доступности еще до начала разработки.

• aria-linter и eslint-plugin-jsx-a11y — обязательные инструменты для React/Next проектов.


📌 Важно, чтобы все могли пользоваться сайтом: и те, кто не может пользоваться мышью, и те, кто сидит на солнце. Если заранее позаботиться о доступности, можно избежать кучу косяков. Доступность 2.0 — это основа крутого фронтенда.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123👎1🐳1
👀 Streams API, Fetch и AbortController — идеальная связка для работы с данными

Когда мы думаем о fetch, сразу представляем себе старый добрый запрос: fetch(url).then(r => r.json()). Но современные веб-технологии куда мощнее. Вместе с Streams API и AbortController мы получаем уникальное сочетание, которое упрощает работу с большими данными и позволяет нам создавать более гибкие и быстрые интерфейсы.

❗️ Streams API — когда данные приходят по частям

Раньше ответ от сервера загружался целиком, а затем обрабатывался. Сегодня данные поступают по частям, что позволяет работать с ними постепенно. Это особенно полезно для больших JSON, видео и SSE. Мы можем отображать прогресс загрузки и не загружать весь файл в память, что делает работу с большими данными более эффективной и экономит ресурсы браузера.

// Пример кода
const res = await fetch('/big.json');
const reader = res.body?.getReader();

let chunks = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks += new TextDecoder().decode(value);
}


❗️ AbortController — контроль над асинхронными операциями

AbortController отменяет запросы и асинхронные операции, если они больше не нужны, например когда пользователь ушёл со страницы. Запрос отменяется через 2 секунды без ответа. Это можно использовать не только для fetch, но и для любых асинхронных операций, которые поддерживают signal.

// Пример кода
const controller = new AbortController();
const signal = controller.signal;

fetch('/api/data', { signal });
setTimeout(() => controller.abort(), 2000);


❗️ Вместе — это мощный инструмент для реактивных интерфейсов

Объединив эти возможности, мы получаем мощный паттерн для работы с данными в реальном времени: стриминг данных в UI, отображение частичных результатов без загрузочных экранов и экономию памяти. Это улучшает производительность и пользовательский опыт.

// Пример кода
const controller = new AbortController();
const res = await fetch('/api/stream', { signal: controller.signal });
const reader = res.body.getReader();

for await (const chunk of streamToAsyncIterator(reader)) {
renderChunk(chunk);
}


📌 Fetch, Streams API и AbortController — это не просто новые фичи. Эти инструменты открывают новые горизонты для создания плавных и эффективных интерфейсов. Многие фреймворки, такие как Next.js, Remix и Astro, уже используют эту технологию в своей основе. Значит, если вы хотите быть на волне, нужно освоить эти инструменты.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥54👍2👎1🐳1
🔫 Как сократить код, не теряя читаемости?

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

Не бойтесь удалять лишнее
Каждая функция и условие — это потенциальная точка отказа. Если код не добавляет ценности и не решает задачу, то его лучше удалить. Поддержка меньшего объёма кода позволяет сосредоточиться на более важных аспектах и упрощает развитие проекта. Меньше кода — значит меньше проблем в будущем.

• Повторение — не всегда плохо
Когда в коде появляются 2-3 одинаковые строки, не спешите их абстрагировать. Часто абстракции ради экономии пары строк только делают код сложнее для восприятия. Правило простое: «Не абстрагируй раньше времени, абстрагируй умно». Если повторение не вызывает затруднений, оставьте его.

• Используй возможности JavaScript
Есть ситуации, когда можно заменить несколько строк на одну — и при этом не потерять читаемости. Не бойтесь использовать тернарные операторы, если они действительно упрощают понимание логики. Главное — одна мысль в одну строку.

// Вместо:
if (isAdmin) return 'admin'
else return 'user'

// Можно:
return isAdmin ? 'admin' : 'user'


• Компоненты должны быть короткими
Если React-компонент начинает занимать больше 50 строк, подумайте, не пора ли его разделить. Логику можно вынести в хук, а часть верстки — в отдельный подкомпонент. Каждый компонент должен выполнять одну задачу, чтобы код оставался читаемым и легко поддерживаемым.

• Подход как у редактора

Каждый раз, когда добавляете новую строку в код, спросите себя: «Можно ли сделать это проще?» Пытайтесь всегда искать оптимальное решение. Иногда уменьшение кода на пару строк может значительно повысить его читаемость.


📌 Меньше кода — это не минимализм, а ясность и лаконичность. Когда через месяц работы вы открываете свой код и не хотите переписать его, значит, вы достигли цели. Секрет не в том, чтобы сделать код короче, а в том, чтобы он был простым и понятным.

🚪 Frontender's notes
Please open Telegram to view this post
VIEW IN TELEGRAM
👍82👎2