Анимации с Framer Motion
Framer Motion — популярная библиотека для React, которая упрощает создание плавных анимаций. С её помощью можно легко добавлять интерактивные эффекты, такие как масштабирование кнопки при наведении или анимация появления элемента.
👉 @sWebDev
Framer Motion — популярная библиотека для React, которая упрощает создание плавных анимаций. С её помощью можно легко добавлять интерактивные эффекты, такие как масштабирование кнопки при наведении или анимация появления элемента.
import { motion } from 'framer-motion';
const Button: React.FC = () => {
return (
<motion.button
whileHover={{ scale: 1.1 }} // Анимация при наведении курсора
whileTap={{ scale: 0.9 }} // Анимация при клике
initial={{ opacity: 0 }} // Начальное состояние
animate={{ opacity: 1 }} // Конечное состояние
transition={{ duration: 0.3 }} // Длительность
>
Нажми меня
</motion.button>
);
};
export default Button;👉 @sWebDev
👍2❤1
Примеры использования JS Fetch
Статья на Snipp.ru объясняет, как использовать
Пример отправки POST-запроса с JSON из статьи:
👉 @sWebDev
Статья на Snipp.ru объясняет, как использовать
fetch() в JavaScript для отправки HTTP-запросов и получения данных. Рассматриваются GET, POST и другие методы, обработка ошибок, работа с JSON и заголовками.Пример отправки POST-запроса с JSON из статьи:
fetch('https://example.com/api', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'John', age: 30 })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Ошибка:', error));👉 @sWebDev
👍2
React Error Boundary
Error Boundary изолирует ошибки в компонентах (например, при сбоях в сторонних библиотеках или API), чтобы приложение оставалось стабильным. Это особенно актуально для крупных проектов, где ошибка в одном компоненте не должна ломать весь UI.
👉 @sWebDev | #полезные_сниппеты
Error Boundary изолирует ошибки в компонентах (например, при сбоях в сторонних библиотеках или API), чтобы приложение оставалось стабильным. Это особенно актуально для крупных проектов, где ошибка в одном компоненте не должна ломать весь UI.
import { Component } from 'react';
class ErrorBoundary extends Component {
state = { hasError: false, error: null };
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidCatch(error, info) {
console.error('Error:', error, info);
}
render() {
if (this.state.hasError) {
return <div>Error: {this.state.error.message}</div>;
}
return this.props.children;
}
}
// Использование
const App = () => (
<ErrorBoundary>
<FaultyComponent />
</ErrorBoundary>
);👉 @sWebDev | #полезные_сниппеты
❤3👍1
JavaScript. Рецепты для разработчиков
Книга «JavaScript. Рецепты для разработчиков» Шелли Пауэрс, представляет собой практическое руководство для программистов, желающих углубить свои знания в JavaScript. Автор предлагает множество готовых решений и «рецептов» для типичных задач веб-разработки, таких как работа с DOM, асинхронное программирование, обработка событий и создание интерактивных интерфейсов. Книга отличается ясным стилем, примерами кода и акцентом на современные стандарты JavaScript, что делает её полезным ресурсом как для начинающих, так и для опытных разработчиков.
👉 @sWebDev | #книги
Книга «JavaScript. Рецепты для разработчиков» Шелли Пауэрс, представляет собой практическое руководство для программистов, желающих углубить свои знания в JavaScript. Автор предлагает множество готовых решений и «рецептов» для типичных задач веб-разработки, таких как работа с DOM, асинхронное программирование, обработка событий и создание интерактивных интерфейсов. Книга отличается ясным стилем, примерами кода и акцентом на современные стандарты JavaScript, что делает её полезным ресурсом как для начинающих, так и для опытных разработчиков.
👉 @sWebDev | #книги
Отложенный вызов
Вопрос:
Что произойдёт, если передать null в качестве задержки в
Посмотреть ответ.
👉 @sWebDev
Вопрос:
Что произойдёт, если передать null в качестве задержки в
useTimeout?Посмотреть ответ.
👉 @sWebDev
Что произойдёт, если передать null в качестве задержки в useTimeout?
Anonymous Quiz
36%
Функция выполнится сразу.
7%
Будет бесконечный цикл вызовов.
28%
Ошибка: delay должен быть числом.
28%
Таймер не будет запущен.
Tabulator
Библиотека, которая превращает HTML-таблицы или данные из JavaScript в интерактивные, полнофункциональные виджеты с огромным количеством функций. Философия — "простота настройки, мощь под капотом".
👉 @sWebDev
Библиотека, которая превращает HTML-таблицы или данные из JavaScript в интерактивные, полнофункциональные виджеты с огромным количеством функций. Философия — "простота настройки, мощь под капотом".
👉 @sWebDev
👍2
JavaScript для профессиональных веб-разработчиков
Автор доступно объясняет сложные концепции языка, включая замыкания, асинхронное программирование, работу с DOM и современные стандарты ECMAScript.
Книга сочетает теорию с практическими примерами, что делает её полезной как для начинающих, так и для опытных программистов. Обновлённое издание охватывает последние тренды веб-разработки.
👉 @sWebDev | #книги
Автор доступно объясняет сложные концепции языка, включая замыкания, асинхронное программирование, работу с DOM и современные стандарты ECMAScript.
Книга сочетает теорию с практическими примерами, что делает её полезной как для начинающих, так и для опытных программистов. Обновлённое издание охватывает последние тренды веб-разработки.
👉 @sWebDev | #книги
👎2👍1
✨ Анимации в React без библиотеки анимаций
В React 19.3 стал стабильным компонент <ViewTransition>. Он отдаёт анимацию переходов между состояниями интерфейса браузерному View Transition API.
Автор статьи в блоге LogRocket собрал одно приложение дважды: на библиотеке анимаций Motion и на <ViewTransition> с CSS. Модалка в нативной версии:
Сами движения описываются в CSS. JS в этой сборке похудел на 39 005 байт (gzip), зато кода анимаций вышло 253 строки против 75 у Motion.
Для жестов, пружин и эффектов по скроллу автор скорее оставил бы библиотеку. А в статье ещё сортировка 250 карточек, навигация и перелёт картинки, плюс грабли, на которые он наступил.
👍 - если было полезно
👉 @sWebDev
В React 19.3 стал стабильным компонент <ViewTransition>. Он отдаёт анимацию переходов между состояниями интерфейса браузерному View Transition API.
Автор статьи в блоге LogRocket собрал одно приложение дважды: на библиотеке анимаций Motion и на <ViewTransition> с CSS. Модалка в нативной версии:
function openModal() {
startTransition(() => setIsOpen(true));
}
{isOpen && (
<ViewTransition enter="modal-enter" exit="modal-exit">
<div className="modal-overlay" onClick={closeModal}>
<ModalContent onClose={closeModal} />
</div>
</ViewTransition>
)}Сами движения описываются в CSS. JS в этой сборке похудел на 39 005 байт (gzip), зато кода анимаций вышло 253 строки против 75 у Motion.
Для жестов, пружин и эффектов по скроллу автор скорее оставил бы библиотеку. А в статье ещё сортировка 250 карточек, навигация и перелёт картинки, плюс грабли, на которые он наступил.
👍 - если было полезно
👉 @sWebDev
❤1
⚡ Angular 22.2: данные маршрута грузятся параллельно
Резолверы в Angular Router загружают данные до открытия страницы. Но вдоль иерархии маршрутов они идут по очереди: родитель грузится 2 секунды, дочерний маршрут 3, и пользователь ждёт 5.
В Angular 22.2 появилась альтернатива: Router Resources. В маршруте пишут свойство resources с обычными resource, а роутер запускает их все сразу. В том же примере ждать придётся 3 секунды.
Компонент получает готовое значение как input, так же как от резолвера. А если обернуть ресурс в nonBlocking, страница откроется сразу, и загрузку покажет сам компонент.
Пока это Developer Preview: до стабилизации API может поменяться в деталях.
В статье ещё перезагрузка данных без новой навигации и редирект, когда их нет.
👍 - если было полезно
👉 @sWebDev
Резолверы в Angular Router загружают данные до открытия страницы. Но вдоль иерархии маршрутов они идут по очереди: родитель грузится 2 секунды, дочерний маршрут 3, и пользователь ждёт 5.
В Angular 22.2 появилась альтернатива: Router Resources. В маршруте пишут свойство resources с обычными resource, а роутер запускает их все сразу. В том же примере ждать придётся 3 секунды.
{
path: 'passenger-edit/:id',
component: PassengerEdit,
resources: (ctx) => ({
passenger: createSimplePassengerResource(ctx.params),
}),
},Компонент получает готовое значение как input, так же как от резолвера. А если обернуть ресурс в nonBlocking, страница откроется сразу, и загрузку покажет сам компонент.
Пока это Developer Preview: до стабилизации API может поменяться в деталях.
В статье ещё перезагрузка данных без новой навигации и редирект, когда их нет.
👍 - если было полезно
👉 @sWebDev
⚡ React Compiler в Vite теперь работает на Rust
React Compiler оптимизирует React-компоненты прямо во время сборки. Раньше в Vite его подключали через Babel. В @vitejs/plugin-react v6.1.0 появилась экспериментальная нативная версия от команды oxc, которая делает JS-инструменты на Rust.
Автор перевёл на неё конструктор сайтов из 1036 файлов. Сама компиляция ускорилась с 14,3 до 0,81 секунды. Сборка целиком ускорилась скромнее: с 22,1 до 9,3 секунды.
На Vite 8+ переход сводится к упрощению конфига. Babel-плагин больше не нужен:
Учтите, что поддержка пока помечена как экспериментальная.
В статье есть рецепт и для React Router в framework mode, где плагин Vite React не используется.
👍 - если было полезно
👉 @sWebDev
React Compiler оптимизирует React-компоненты прямо во время сборки. Раньше в Vite его подключали через Babel. В @vitejs/plugin-react v6.1.0 появилась экспериментальная нативная версия от команды oxc, которая делает JS-инструменты на Rust.
Автор перевёл на неё конструктор сайтов из 1036 файлов. Сама компиляция ускорилась с 14,3 до 0,81 секунды. Сборка целиком ускорилась скромнее: с 22,1 до 9,3 секунды.
На Vite 8+ переход сводится к упрощению конфига. Babel-плагин больше не нужен:
npm install -D oxc-transform-react
// vite.config.js
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
export default defineConfig({
plugins: [react({ compiler: true })],
});
Учтите, что поддержка пока помечена как экспериментальная.
В статье есть рецепт и для React Router в framework mode, где плагин Vite React не используется.
👍 - если было полезно
👉 @sWebDev
🛡️ Как не дать чужому пакету украсть ваши секреты через pnpm install
Атаки на npm-пакеты обычно идут по одной схеме. Пакет взламывают, его postinstall-скрипт запускается у вас на машине и уносит данные. В менеджере пакетов pnpm v10 есть настройки, которые сильно усложняют такой сценарий.
Скрипты установки там выключены по умолчанию. А
Мягкий вариант конфига из статьи:
Подвох в том, что пакеты, которым скрипты нужны по делу (нативные аддоны, esbuild), придётся явно разрешить через
В статье есть и строгий конфиг: неделя ожидания новых версий и падение CI на всём подозрительном.
👍 - если было полезно
👉 @sWebDev
Атаки на npm-пакеты обычно идут по одной схеме. Пакет взламывают, его postinstall-скрипт запускается у вас на машине и уносит данные. В менеджере пакетов pnpm v10 есть настройки, которые сильно усложняют такой сценарий.
Скрипты установки там выключены по умолчанию. А
minimumReleaseAge откладывает установку только что опубликованных версий: большинство взломанных пакетов обнаруживают и снимают за считанные часы.Мягкий вариант конфига из статьи:
# pnpm-workspace.yaml
blockExoticSubdeps: true
trustPolicy: no-downgrade
minimumReleaseAge: 1440 # 1 day
allowBuilds:
esbuild: true
fsevents: true
Подвох в том, что пакеты, которым скрипты нужны по делу (нативные аддоны, esbuild), придётся явно разрешить через
allowBuilds.В статье есть и строгий конфиг: неделя ожидания новых версий и падение CI на всём подозрительном.
👍 - если было полезно
👉 @sWebDev
🪄 Один URL: модалка поверх списка и полноценная страница
В каталоге детали карточки удобно открывать поверх списка. Но если модалка живёт в useState, адрес не меняется. Ссылкой не поделиться, после reload остаётся список, а поисковик деталей не видит.
В Next.js App Router это решают Parallel Routes и Intercepting Routes. Модалка лежит в слоте @modal, который layout рисует рядом со страницей. Папка с префиксом (.) перехватывает обычный маршрут:
При клике через Link адрес меняется на /en/events/123, а детали открываются поверх списка. При прямом заходе или reload перехвата нет, и рендерится обычная страница со своими metadata и canonical.
Слоту обязательно нужен default.tsx, который возвращает null. Без него при прямом заходе можно получить 404.
В статье ещё разобрано, как закрыть модалку и вернуться к списку с теми же фильтрами.
👍 - если было полезно
👉 @sWebDev
В каталоге детали карточки удобно открывать поверх списка. Но если модалка живёт в useState, адрес не меняется. Ссылкой не поделиться, после reload остаётся список, а поисковик деталей не видит.
В Next.js App Router это решают Parallel Routes и Intercepting Routes. Модалка лежит в слоте @modal, который layout рисует рядом со страницей. Папка с префиксом (.) перехватывает обычный маршрут:
@modal/
(.)events/
[id]/
page.tsx
При клике через Link адрес меняется на /en/events/123, а детали открываются поверх списка. При прямом заходе или reload перехвата нет, и рендерится обычная страница со своими metadata и canonical.
Слоту обязательно нужен default.tsx, который возвращает null. Без него при прямом заходе можно получить 404.
В статье ещё разобрано, как закрыть модалку и вернуться к списку с теми же фильтрами.
👍 - если было полезно
👉 @sWebDev
🛟 Angular 22.2: упавший шаблон больше не ломает страницу
Раньше ошибка при рендере шаблона уходила в глобальный ErrorHandler, а часть страницы оставалась недорисованной.
Новый блок @boundary ограничивает ущерб: если внутри что-то бросит исключение, Angular покажет вместо этой секции блок @error. Идея подсмотрена у React.
Первый @error ловит сетевые ошибки и даёт повторить рендер через $reset, второй ловит всё остальное. С Resource API это удобно: value() при сбое загрузки бросает исключение, и проверять error() заранее не нужно.
Пока @boundary в статусе developer preview.
А ещё в статье Router Resources: данные маршрутов грузятся параллельно, а не цепочкой резолверов.
👍 - если было полезно
👉 @sWebDev
Раньше ошибка при рендере шаблона уходила в глобальный ErrorHandler, а часть страницы оставалась недорисованной.
Новый блок @boundary ограничивает ущерб: если внутри что-то бросит исключение, Angular покажет вместо этой секции блок @error. Идея подсмотрена у React.
@boundary {
<app-chart />
} @error (let err; retry = $reset; when isNetworkError(err)) {
<p>{{ err.message }}</p>
<button (click)="retry()">Retry</button>
} @error {
<p>Something went wrong.</p>
}Первый @error ловит сетевые ошибки и даёт повторить рендер через $reset, второй ловит всё остальное. С Resource API это удобно: value() при сбое загрузки бросает исключение, и проверять error() заранее не нужно.
Пока @boundary в статусе developer preview.
А ещё в статье Router Resources: данные маршрутов грузятся параллельно, а не цепочкой резолверов.
👍 - если было полезно
👉 @sWebDev
🧩 Страница в Angular, которая не знает про роутер
Обычно компонент страницы сам берёт userId из ActivatedRoute, зовёт UserService и рисует «Loading...». Переиспользовать такой компонент сложно, а для теста нужен роутер и мок сервиса.
Опция роутера withComponentInputBinding (есть с Angular 16) сама записывает данные маршрута в инпуты компонента с тем же именем:
Загрузку пользователя автор выносит в резолвер, то есть функцию, которая получает данные до перехода на маршрут. В компоненте остаётся одна строка с
Учтите, что роутер сверяет только имя ключа и имя инпута, а типы не проверяет. Если резолвер вернёт объект другой формы, всё скомпилируется. Автор советует общий интерфейс и интеграционный тест.
В статье разобрано, где здесь инверсия зависимостей и как показать лоадер, пока резолвер ждёт ответа.
👍 - если было полезно
👉 @sWebDev
Обычно компонент страницы сам берёт userId из ActivatedRoute, зовёт UserService и рисует «Loading...». Переиспользовать такой компонент сложно, а для теста нужен роутер и мок сервиса.
Опция роутера withComponentInputBinding (есть с Angular 16) сама записывает данные маршрута в инпуты компонента с тем же именем:
provideRouter(routes, withComponentInputBinding())
Загрузку пользователя автор выносит в резолвер, то есть функцию, которая получает данные до перехода на маршрут. В компоненте остаётся одна строка с
input.required<User>().Учтите, что роутер сверяет только имя ключа и имя инпута, а типы не проверяет. Если резолвер вернёт объект другой формы, всё скомпилируется. Автор советует общий интерфейс и интеграционный тест.
В статье разобрано, где здесь инверсия зависимостей и как показать лоадер, пока резолвер ждёт ответа.
👍 - если было полезно
👉 @sWebDev
Please open Telegram to view this post
VIEW IN TELEGRAM
🧭 Предзагрузка в TanStack Router, которая тихо ломается
В TanStack Router данные можно начать грузить в loader маршрута ещё до рендера, а компонент заберёт их из кэша TanStack Query. Но запрос при этом описан в двух местах:
Если они разойдутся, ошибки не будет. Loader скачает лишнее, а компонент сделает второй запрос.
TkDodo предлагает собирать queryOptions один раз в новой функции маршрута
Учтите, что на момент написания статьи функция
Отдельно TkDodo объясняет, почему такой контекст не плодит лишних ререндеров.
👍 - если было полезно
👉 @sWebDev
В TanStack Router данные можно начать грузить в loader маршрута ещё до рендера, а компонент заберёт их из кэша TanStack Query. Но запрос при этом описан в двух местах:
// loader
await context.queryClient.ensureQueryData(
dashboardQueryOptions(params.dashboardId, deps),
)
// component
const { data } = useSuspenseQuery(
dashboardQueryOptions(params.dashboardId, { asOf }),
)
Если они разойдутся, ошибки не будет. Loader скачает лишнее, а компонент сделает второй запрос.
TkDodo предлагает собирать queryOptions один раз в новой функции маршрута
context. Loader и компонент берут их оттуда (компонент через useRouteContext()), и разойтись им уже не в чем.Учтите, что на момент написания статьи функция
context ещё не была описана в документации.Отдельно TkDodo объясняет, почему такой контекст не плодит лишних ререндеров.
👍 - если было полезно
👉 @sWebDev
🚀 Next.js 16.4 научил ИИ-агента искать лишний JavaScript
В Next.js 16.4 появился next-bundle-optimizer: навык для ИИ-агента, который разбирает граф модулей сборщика Turbopack и ищет код, попавший в бандл зря.
Пример: тяжёлый компонент обёрнут в lazy(), но другой модуль импортирует его напрямую, и он всё равно грузится сразу. Агент прослеживает такие цепочки и предлагает, где их разорвать.
Затем в агенте вызываете /next-bundle-optimizer. По умолчанию он только сообщает о проблемах, а /next-bundle-optimizer fix применяет правки и сравнивает размер до и после.
Учтите: нужен Turbopack, без его графа модулей анализ не работает. С Next.js 16 это сборщик по умолчанию.
В Vercel агент так убрал почти 2 МБ сжатого JS на v0 и vercel.com, и список его находок стоит посмотреть.
👍 - если было полезно
👉 @sWebDev
В Next.js 16.4 появился next-bundle-optimizer: навык для ИИ-агента, который разбирает граф модулей сборщика Turbopack и ищет код, попавший в бандл зря.
Пример: тяжёлый компонент обёрнут в lazy(), но другой модуль импортирует его напрямую, и он всё равно грузится сразу. Агент прослеживает такие цепочки и предлагает, где их разорвать.
npx skills add vercel/next.js --skill next-bundle-optimizer
Затем в агенте вызываете /next-bundle-optimizer. По умолчанию он только сообщает о проблемах, а /next-bundle-optimizer fix применяет правки и сравнивает размер до и после.
Учтите: нужен Turbopack, без его графа модулей анализ не работает. С Next.js 16 это сборщик по умолчанию.
В Vercel агент так убрал почти 2 МБ сжатого JS на v0 и vercel.com, и список его находок стоит посмотреть.
👍 - если было полезно
👉 @sWebDev
🚀 Tailwind или StyleX: что меняет реальная миграция
StyleX: система стилей от Meta. Стили пишутся объектами в TypeScript и при сборке превращаются в статический CSS.
Разработчик сделал 20 компонентов на Tailwind и переписал их на StyleX с новым пропом
Кода стало вдвое больше (3143 строки против 1568), а размер CSS и время сборки почти не изменились. Зато TypeScript ловил опечатки в токенах и неверные варианты до браузера. В Tailwind класс вроде bg-blue-60 может молча не сработать.
StyleX стоит рассмотреть для библиотеки компонентов с общими токенами и кучей вариантов. Но его публичная экосистема намного меньше, многое придётся писать самому.
В статье разобраны пять граблей миграции, от barrel-экспортов до порядка CSS-слоёв.
👍 - если было полезно
👉 @sWebDev
StyleX: система стилей от Meta. Стили пишутся объектами в TypeScript и при сборке превращаются в статический CSS.
Разработчик сделал 20 компонентов на Tailwind и переписал их на StyleX с новым пропом
sx={}. Кнопка с вариантами выглядит так:return (
<button sx={[styles.base, styles[variant], styles[size]]}>
{children}
</button>
);
Кода стало вдвое больше (3143 строки против 1568), а размер CSS и время сборки почти не изменились. Зато TypeScript ловил опечатки в токенах и неверные варианты до браузера. В Tailwind класс вроде bg-blue-60 может молча не сработать.
StyleX стоит рассмотреть для библиотеки компонентов с общими токенами и кучей вариантов. Но его публичная экосистема намного меньше, многое придётся писать самому.
В статье разобраны пять граблей миграции, от barrel-экспортов до порядка CSS-слоёв.
👍 - если было полезно
👉 @sWebDev
👎3