WebDev+ | Веб-разработка
8.3K subscribers
507 photos
242 videos
10 files
702 links
Присоединяйтесь к нашему каналу и погрузитесь в мир веб-разработки

Связь: @devmangx
Download Telegram
This media is not supported in your browser
VIEW IN TELEGRAM
Мой любимый терминал — Warp. Я до сих пор нахожу в нём мелкие фишки, которые помогают работать быстрее. Знал, что там есть встроенный файловый менеджер?

@WebDev_Plus
2
Вот небольшой совет, не про Angular.

Не обязательно держать submit/reset кнопки прямо внутри формы. Можно повесить на кнопку атрибут form.
Этот атрибут связывает кнопку с нужной формой, и тогда её можно разместить где угодно в документе, независимо от её позиции.

Надеюсь, пригодится.

@WebDev_Plus
1👍1
Array.with() для аккуратных неизменяемых обновлений

@WebDev_Plus
1
Разработчик экспериментирует с HTMX и нашёл способ комбинировать JSX, TypeScript и кастомные HTML-элементы… без привычной фронтовой сборки. Стили и небольшой клиентский код он просто инлайнит прямо с сервера. Звучит странновато, но есть плюсы: всё лежит рядом, не нужно возиться с бандлерами, а работа идёт быстрее.

Фокус в одном трюке: клиентские функции можно передавать в <script> как есть, забрав их исходник через Function.prototype.toString(). То же работает и для CSS. Получается, будто пишешь фронт прямо в браузере, но все плюшки TypeScript и JSX получаешь на сервере.

Метод, конечно, не для гигантских приложений. Но для маленьких виджетов, кастомных элементов или отдельных фич без тонны зависимостей — вполне себе вариант. Минификацию можно отдать CDN или вообще забить, если кода немного. С внешними библиотеками помогут import maps.

Автор задумки признаёт: это не серебряная пуля. Просто ещё один инструмент, который делает разработку чуть приятнее, когда он уместен.

@WebDev_Plus
4
This media is not supported in your browser
VIEW IN TELEGRAM
Свежак в ChromeDevTools! Отладка полной performance-трейсы с помощью Gemini.

Записал трейс, а дальше просто общаешься с Gemini про весь этот трейс: связанные Performance Insights и даже данные из поля. И главное.. не надо заранее выделять контекст, Gemini сам разберется

@WebDev_Plus
1😁1
Менять HTML на лету еще никогда не было так просто.

Bun HTMLRewriter API дает низкоуровневый контроль для парсинга, модификации и улучшения HTML через CSS-селекторы, и все это на бешеной скорости. Реализация в Bun основана на Cloudflare lol-html.

Можно переписывать контент из строк, Blob, ArrayBuffer, файлов или даже HTTP-ответов. Есть тонкое управление элементами, текстовыми нодами и комментариями. Идеально, когда нужно подправить HTML прямо в процессе обработки.

@WebDev_Plus
2
Оцените мой алгоритм сортировки 🤓

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
😁153🔥2
Получите локализованные названия стран и языков с помощью Intl.DisplayNames

@WebDev_Plus
👍1
Bun.password упрощает безопасное хеширование и проверку паролей.

Алгоритм, который используется для генерации хеша, хранится внутри самого хеша. Если используется bcrypt, возвращаемый хеш кодируется в Modular Crypt Format для совместимости с большинством существующих реализаций bcrypt. Если применяется argon2, результат кодируется в более новом PHC формате. Функция verify автоматически определяет алгоритм по входному хешу и использует правильный метод проверки. Она корректно определяет алгоритм как из PHC-, так и из MCF-кодированных хешей.

По умолчанию библиотека bcrypt обрезает пароли длиннее 72 байт. В Bun, если передать Bun.password.hash пароль длиннее 72 байт и использовать алгоритм bcrypt, пароль сначала будет захеширован через SHA-512, а затем уже отправлен в bcrypt. То есть вместо того чтобы отправить в bcrypt 500-байтный пароль, который без предупреждения обрежется до 72 байт, Bun сначала прогонит его через SHA-512 и передаст в bcrypt уже получившийся хеш (только если длина превышает 72 байта). Это более безопасное поведение по умолчанию.

@WebDev_Plus
4
This media is not supported in your browser
VIEW IN TELEGRAM
Отличный веб-компонент для создания эффекта спойлера на вашем веб-сайте. Совместим с React, Vue, Angular, Svelte и другими.

> npm install spoilerjs


@WebDev_Plus
3
This media is not supported in your browser
VIEW IN TELEGRAM
Шарь свой localhost кому угодно прямо из VS Code 🤯

В VS Code есть встроенная фишка с портами, которая позволяет открыть твой локальный сервер в интернет без всяких сторонних тулз.

Как это юзать:

Открой вкладку Ports в терминальной панели

Жми Forward a Port

Введи номер локального порта (у меня был 5173, у тебя может быть 3000, 3001 и т. д.)

VS Code сгенерит ссылку — правой кнопкой и Make Public

Копируй ссылку и кидай кому надо

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

В видео есть пошаговый разбор, как это делается 👌

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
4🔥3
This media is not supported in your browser
VIEW IN TELEGRAM
Очень интересный ресурс для программистов и веб-дизайнеров. Инструмент для создания анимированных фонов с цветовыми градиентами.

https://www.krumzi.com/tools/animated-background-generator

@WebDev_Plus
Совет по NgRx на сегодня (и чуть вопрос)

Когда используешь @ngrx/signals/events с

{ providedIn: 'root' }


ты можешь подписаться на события из фичи, которая вообще не инжектит стор.

В таком случае стор может ещё не создаться, и события просто проглотятся 😅

В целом логично, это стандартное поведение DI в Angular, но я почему-то предполагал, что в NgRx есть какая-то магия, которая из коробки стартует «глобальные» сторы (срезы состояния) заранее.

Решение: заинжектить глобальные сторы в app.config.ts (или core.ts), чтобы инстанс стора создавался с самого начала.

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Совет по JavaScript:

Можно обернуть аргументы console.log() в фигурные скобки, чтобы в выводе были видны имена переменных.

@WebDev_Plus
10👍4😁1
Насколько быстрый Bun?

Настолько, что он успел сломать настройку нашей тестовой базы, которая крутится в Docker-контейнере.
Bun выполнил SQL-запросы до того, как база вообще успела подняться. Пришлось прикрутить sleep(), чтобы дать контейнеру время стартануть.

Жесть. С pnpm такого никогда не было.

@WebDev_Plus
1
This media is not supported in your browser
VIEW IN TELEGRAM
Держите полезную CLI-утилиту — npkill, предназначенную для удаления всех папок node_modules в проектах.

Позволяет освободить значительное количество места на диске

Запускаешь команду:
npx npkill

Дальше, просто нажимаешь [Пробел], чтобы удалить те папки, которые больше не используешь

Удобно ещё и то, что она показывает, сколько дней назад была последняя модификация

@WebDev_Plus
4
TypeScript: единый источник для значений, меток и сравнений

export const ORDER_TYPES = {
product: "Product Order",
service: "Service Order",
} as const;

// Тип, представляющий ключи ORDER_TYPES
export type OrderType = keyof typeof ORDER_TYPES;

// Опции для дропдауна
export const ORDER_TYPE_OPTIONS = Object.entries(ORDER_TYPES).map(
([value, label]) => ({ value: value as OrderType, label }),
);

// Пример использования:
// - Сравнение: if (type === "product")
// - Получить метку: ORDER_TYPES[type]
// - Для дропдауна: <Select options={ORDER_TYPE_OPTIONS} />


@WebDev_Plus
3
This media is not supported in your browser
VIEW IN TELEGRAM
CSS карточка с параллакс-эффектом через pointermove и кастомные CSS-переменные

<div class="ring" style="--i: 2">

.ring {
translate: calc(var(--px) * (var(--i) * -2rem))
calc(var(--py) * (var(--i) * 2rem));
}


Фишка: координаты курсора мапятся в поворот карточки по 3D-оси,
а кольца двигаются по 2D-плоскости для создания иллюзии объёма 🤙

@WebDev_Plus
Please open Telegram to view this post
VIEW IN TELEGRAM
6
JavaScript может форматировать числа гораздо умнее, чем вы думаете

// Intl.NumberFormat — форматирование чисел: единицы измерения, сокращения, валюты

// Пример форматирования со скоростью (единицы измерения)
const numberFmt = new Intl.NumberFormat("en", {
style: "unit", // стиль "единица измерения"
unit: "kilometer-per-hour", // километры в час
});

// Пример форматирования в компактной форме (например, "15.3K" вместо "15320")
const compactFmt = new Intl.NumberFormat("en", {
notation: "compact", // компактная запись (K, M и т. д.)
maximumFractionDigits: 1, // максимум 1 знак после запятой
});

// Пример форматирования валюты (йены, без округления вверх)
const currencyFmt = new Intl.NumberFormat("en", {
style: "currency", // стиль "валюта"
currency: "JPY", // японская йена
roundingMode: "floor", // округление вниз
});

// Примеры вывода
console.log(numberFmt.format(88)); // "88 km/h"
console.log(compactFmt.format(15320)); // "15.3K"
console.log(currencyFmt.format(4999.99)); // "¥4,999"


@WebDev_Plus
1👍1