JS F/k


Kanal geosi va tili: Rossiya, Ruscha


HTML/TS/Vue — с примерами, по делу, без воды
https://js-f-k.netlify.app
#html #vue #typescript #npm

Bog‘liq kanallar

Kanal geosi va tili
Rossiya, Ruscha
Statistika
Postlar filtri


mefody.dev dan repost
Вам больше не нужен initial-scale

Стопудово где-то у вас в вёрстке есть . Он почти у всех есть. Потому что emmet его вставляет, всякие бутстрап-шаблоны тоже.

Так вот, initial-scale можно удалить. Он был нужен давно, чтобы на iPhone при повороте экрана работало так же, как на всех остальных смартфонах. Но Apple это несоответствие уже давно пофиксили. Экономим байтики.

https://quirksmode.org/quirksblog/2026/0902-initial.html


Веб-стандарты dan repost
HTML-бойлерплейт 2026 года. Мануэль Матузович разбирает каждую строку в и объясняет, зачем она нужна: кодировка перед заголовком, вьюпорт, Open Graph и отдельная таблица стилей для печати. В этом году добавились метаэлемент text-scale для системного размера текста на мобильных, SVG-фавиконка с поддержкой тёмной темы, ссылка на маркдаун-версию страницы для LLM и fediverse:creator для атрибуции в Mastodon. #html #learn

https://www.matuzo.at/blog/2026/html-boilerplate


Веб-стандарты dan repost
Безопасный способ выпустить npm-пакет в 2026 году. Андрей Ситник разбирает, как атаки на цепочку поставок идут полуавтоматически и компрометируют сотни пакетов в день и предлагает строить защиту как повышение стоимости атаки. Быстрые меры, большинство из которых внедряются за день: доверенная и поэтапная публикация в npm, обязательная 2FA, создание тегов только админами, экшены CI по SHA и трёхдневная выдержка обновлений. #npm #security

https://evilmartians.com/chronicles/the-secure-way-to-release-an-npm-package


Отображение SHA и времени коммита в веб-приложении

Если вы не используете SemVer или приложение еще не получило стабильной версии — имеет смысл отображать SHA последнего коммита и его дату, чтобы понимать, какая версия сейчас запущена. В Vite это реализуется в несколько строк.

Получение информации о коммите

В любом удобном файле, либо прямо в vite.config.ts напишите:
import { execFileSync } from "node:child_process";

const commitSHA = execFileSync("git", ["rev-parse", "--short", "HEAD"], { encoding: "utf8" }).trim();
const commitDate = execFileSync("git", ["log", "-1", "--format=%cI"], { encoding: "utf8" }).trim();

Что делает этот код?
execFile (и его синхронная версия execFileSync) запускает исполняемый файл, в нашем случае git и передаёт в него параметры.

- git rev-parse --short HEAD — возвращает сокращённый SHA текущего коммита.
- git log -1 --format=%cI — возвращает дату последнего коммита в формате ISO.

Используется execFile вместо exec, чтобы запускать команду напрямую без передачи строки на обработку shell.


В опции encoding передается значение utf8, чтобы вызов вернул строку вместо Buffer.

Добавьте значения в define в vite.config.ts:
export default defineConfig({
+ define: {
+ "import.meta.env.VITE_GIT_COMMIT_SHA": JSON.stringify(commitSHA),
+ "import.meta.env.VITE_GIT_COMMIT_DATE": JSON.stringify(commitDate)
+ }
});

Добавление в компонент
Теперь в любом компоненте можно получить значения из переменных среды через import.meta.env.
const { VITE_GIT_COMMIT_SHA, VITE_GIT_COMMIT_DATE } = import.meta.env;

И использовать, например, вот так:
const commitDate = new Intl.DateTimeFormat(navigator.language, {
year: "numeric",
month: "long",
day: "2-digit"
}).format(new Date(VITE_GIT_COMMIT_DATE));

const revision = `${commitDate} [${VITE_GIT_COMMIT_SHA}]`; // July 18, 2026 [369f0b3]

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

⚠️ Этот способ работает только если во время сборки доступен git-репозиторий. Если проект собирается без каталога .git, команды завершатся ошибкой.

#build #git #vite


Веб-стандарты dan repost
Современное оформление тем в CSS с light-dark(), contrast-color() и style-выражениями. Юна Кравец объединяет light-dark() для цветов с учётом предпочтений пользователя, @​property для типизированных свойств, contrast-color() для автоматического выбора чёрного или белого текста и @​container style() для более насыщенных палитр. Так разделяются темизация всей страницы и отдельных компонентов, а тени в светлой теме и свечение рамок в тёмной задают глубину. #css #color

https://una.im/modern-css-theming/


Веб-стандарты dan repost
Replacements​.fyi. Инструмент от сообщества e18e помогает находить более производительные и безопасные альтернативы устаревшим или ненужным npm-пакетам. Введите имя пакета — например, is-number, left-pad или is-odd — и получите готовую замену или короткий фрагмент кода. Можно фильтровать по среде: Node, Bun, Deno, Cloudflare или браузер. Также есть список всех пакетов и проверка package.json. #npm #tools

https://replacements.fyi/


Веб-стандарты dan repost
HTML Sanitizer API. Ахмад Альфи рассказывает о новом браузерном API для защиты от XSS без DOMPurify. Безопасные методы setHTML и parseHTML всегда удаляют опасное содержимое, а setHTMLUnsafe и parseHTMLUnsafe уважают ваши настройки. Списки разрешённых и запрещённых элементов и атрибутов дают гибкий контроль. Подходит для комментариев, WYSIWYG-редакторов и предпросмотра Markdown, но серверная санитизация по-прежнему обязательна. #security #html

https://alfy.blog/2026/05/07/html-sanitizer-api.html


Как закрепить порт за проектом и избежать коллизий

Если у вас несколько фронтенд-проектов (особенно на Vue или других SPA-фреймворках), почти наверняка они по умолчанию используют один и тот же dev-порт — чаще всего 3000 или 5173. Использование проектами одного порта рано или поздно приводит к ошибкам, так как для браузера это одна и та же среда: общий localStorage, общие cookie, общие service workers.

Проблема
В итоге можно получить:
- перезапись данных (например, токенов)
- неожиданные авторизации
- сломанные страницы без видимых причин
- кэш от другого проекта

Особенно проблемным станет service worker — он может начать обслуживать вообще другой проект.

Ручное решение
Можно задать порт вручную:
// vite.config.ts
export default defineConfig({
server: {
port: 7000
}
});

Но с ростом числа проектов появляется новая проблема — требуется запоминать, какие порты заняты и следить за коллизиями.

Автоматическое решение
Решение — использовать пакет named-port.

named-port решает проблему иначе: он детерминированно вычисляет порт на основе переданной строки. Таким образом, каждый проект получает свой стабильный порт на основе его имени или произвольной строки.

Использование
npm install --save-dev named-port
// vite.config.ts
import process from "node:process";
import namedPort from "named-port";
import { defineConfig } from "vite";

export default defineConfig({
server: {
port: namedPort(process.env.npm_package_name)
}
});

Теперь порт зависит от поля name из package.json. Главное отличие — предсказуемость: порт не случайный, его не нужно запоминать, и он одинаковый на всех машинах.

Настройка
// передать в качестве аргумента произвольную строку
namedPort("custom-key");
// изменить диапазон портов (по умолчанию 1024..65535)
namedPort("my-app", { min: 3000, max: 3999 });

Итог
named-port — маленькая утилита, которая помогает избежать коллизий при работе с несколькими проектами и убирает целый класс неочевидных багов. Порт становится стабильным и уникальным свойством проекта.

#npm


Веб-стандарты dan repost
Великое расширение CSS. Павел Лаптев рассматривает CSS-фичи, заменяющие JavaScript-библиотеки: anchor positioning вместо Floating UI, Popover API и вместо Radix, scroll-driven animations вместо GSAP, view transitions вместо Motion и кастомизируемый вместо React Select. Вместе они могут убрать до 322 КБ JavaScript. #css #performance

https://blog.gitbutler.com/the-great-css-expansion


Веб-стандарты dan repost
Нативные JSON-модули наконец-то стали реальностью. Мэтт Смит объясняет, как атрибуты импорта позволяют загружать JSON-файлы напрямую через import data from 'data.json' with { type: 'json' } без сборщика. Браузеры и рантаймы обрабатывают JSON-модули нативно с явным указанием типа, что избавляет от трансформаций на этапе сборки и закладывает основу для будущих типов модулей. #json #js

https://allthingssmitty.com/2026/03/16/native-json-modules-are-finally-real/


Отказ от scoped стилей в Vue

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

scoped в Vue
добавляет каждому селектору уникальный атрибут вроде data-v-xxxx.


Click



.button { color: red; }

Компилируется в:
.button[data-v-1234] { color: red; }

- Плюсы: полная изоляция стилей, отсутствие коллизий. Такие стили легко переносить между проектами и вы не рискуете случайно задеть существующие.
- Минусы: небольшой runtime/compile overhead, раздувание CSS из-за добавленных хешей.

Scoped удобен для быстрых прототипов, но для крупных проектов это чаще лишняя нагрузка.

module в Vue
Vue поддерживает ещё один способ изоляции — CSS Modules, через .


Click



.button { color: red; }

Классы получают уникальные имена при компиляции (например button_abc123) и доступ через объект $style.

- Плюсы: полная изоляция, удобно для динамических классов, можно комбинировать с BEM.
- Минусы: синтаксис чуть сложнее ($style вместо обычного класса), больше boilerplate, не так нагляден для людей привыкших к plain CSS.

Если BEM уже соблюдается, CSS Modules чаще всего не нужны, но для компонентов с динамическими классами могут быть полезны.

Уникальные имена классов (BEM)
Если проект использует строгий нейминг, например BEM (Block-Element-Modifier), scoped можно не применять. Классы блоков уже уникальные, а дочерние элементы и модификаторы ограничены областью блока:

.block {
display: flex;
flex-direction: column;
&__element {
flex-basis: 50%;
}
&--modifier {
flex-direction: row;
}
}


- Плюсы: plain CSS без data-v-xxxx, уменьшенный размер бандла, отсутствие runtime/compile overhead. Отсутствие коллизий при строгом следовании BEM.
- Минусы: требуется соблюдать BEM нейминг, который не всем по вкусу, незначительное увеличение времени на code review.

Этот вариант подходит для команд с code review и зафиксированными стандартами разработки.

Валидация классов и стилей
Соблюдение этих правил можно автоматизировать с помощью линтеров.

- Stylelint — запрет не-BEM классов:
{
"selector-class-pattern": "[a-z]([a-z-]+)?(__([a-z]+-?)+)?(--([a-z]+-?)+){0,2}"
}
- Eslint — запрет scoped в Vue-компонентов:
{
"vue/enforce-style-attribute": ["error", { "allow": ["plain"] }]
}

Заключение
- Scoped стилей можно смело избегать, если применяется строгий BEM.
- CSS без scoped уменьшает размер бандла и нагрузку на runtime.
- Линтеры stylelint и eslint помогут ускорить миграцию и предотвратить ошибки в будущем.
- Scoped остаётся безопасным и допустимым подходом, но только если понимать цену его использования.

#build #css #vue


Vueist dan repost
Мне прислали вопрос по моему докладу:
почему нежелательно использовать классы вместо компосаблов.

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

Так как композаблы сами в себе альтернатива ООП заточенная конкретно под нужды Vue. Они уже используют фичи соответствующие потребностям и отсекают вещи которые не особо нужны.

Выше уже было мое сравнение композаблов и ООП, потом в отдельных чатах эта тема прорабтывалась куда подробнее. Но тут я сосредоточусь на минусах классов как замены композаблов

1) Классы - не vue way. Ни в одном гайде не будет такого использования. Вы увеличите время онбоардинга, а разработчикам придется куда сложнее с точки зрения приспосабливаемости к проекту, Библиотеки также не адаптированы под данный подход. В одном из случаев вам придется писать огромную портянку с оберткой композаблов в классы, в другом у вас будет адская смесь из классов и композаблов. Выдерживать единый стиль в таких проектах кратно сложнее.

2) Нет четко выработанных практик о том как БЕЗОПАСНО использовать смесь Vue и классов. Высока вероятность получения хрупкого кода, потери реактивности и лапши, При этом опять же у вас не будет гайдов, как правильно это использовать в том или ином случае. Реактивность Vue не дружит полноценно с классами. Например private property несоввместимы с proxy, вам придется полагаться только на TS зоны видимости, но и с ними будут свои нюансы

3)ООП дает избыточные инструменты которые будут только мешать при использовании Vue, они хуже связываются с его жизненным циклом. Наследование, instanceof и тп просто бесполезны. А вот классическую деструктуризацию использовать сложнее

4) Вы не получите никаких бенефитов от данного подхода. Все что дает ООП и реально нужно, то возможно использовать с композаблами и так.

Так стоит ли это того? Классы часто берут по привычке, либо если почувствовали в себе труъ-инженеров (а это буквально самое страшное что может случиться с проектом, самые запущенные случаи которые видел, когда кто-то посчитал себя истинным инженером и нагородил такой лапши, что проще проект выкинуть и переписать заново, чем править его логику)

Почему же это использовали со Vue2?
- А потому что других вариантов адекватных не было. Как раз из-за отсутсвия композаблов выносить логику из компонентов для переиспользования было прям сильно сложнее, а миксины были еще хуже как решение. Вот собственно и все

Когда классы+Vue ок? Когда вы используете сторонние специализированные инструменты которые уже заточены под классовое ооп. Например, если вы подключили Mobx (хотя особого смысла я в этом тоже не вижу)


Обрезание текста по центру

В статье по переносу и обрезанию текста был показан часто используемый пример с text-overflow: ellipsis, где не влезающий в контейнер текст обрезается в конце. Но есть сценарии, когда требуется отобразить конец строки, а середину скрыть: UUID и хэши, email-адреса, пути к файлам, blockchain-адреса, токены и ключи.

Поскольку CSS не умеет обрезать текст в середине, строку приходится явно разбивать на две части на уровне разметки: левая может сжиматься и обрезаться, правая остаётся фиксированной и всегда отображается полностью.

Разбираем простой подход, без зависимостей и сложных вычислений ширины текста

#css #html


mefody.dev dan repost
Гайд по Anchor Positioning

Anchor Positioning — это декларативный способ описать визуальную привязку одного элемента к другому на странице. Тулптипы, подсказки, сноски, выносные элементы — всё это можно реализовать относительно легко при помощи Anchor Positioning API.

Рома Ахмадуллин в Доке написал подробную статью, как работать с этим однозначно полезным API. Много интерактивных демок.

https://doka.guide/css/anchor-positioning-guide/


Автоматизация релизов на GitHub

Если вы поддерживаете несколько проектов или библиотек на GitHub и устали делать релизы вручную, шаблон Auto Release Template поможет с автоматизацией. Он генерирует changelog, создаёт коммит с новой версией, добавляет тег и публикует GitHub Release. При этом ничего не опубликуется без вашего подтверждения — всегда есть возможность проверить релиз перед публикацией. Одно из значимых отличий — в GitHub Release сразу видны все изменения, без лишней ссылки на полный changelog.

Принцип работы
1. Вносите правки и называйте коммиты по Conventional Commits.
2. Запустите npm run release — обновится версия, сгенерируется CHANGELOG.md, создастся коммит и тег.
3. Вызовите git push --follow-tags.
4. GitHub Action сработает на новый тег и создаст GitHub Release с автоматически сгенерированным changelog.

Настройка и кастомизация
Вы можете изменить формат коммитов, префикс тегов и определить типы коммитов, которые попадут в changelog. Дополнительно вы можете настроить:
- автопубликацию npm пакета в registry npmjs или GitHub Packages;
- использование с pnpm;
- создание draft релиза;
- создание provenance statement;
- подключение хуков и добавление сгенерированных файлов в билд.

Подробные примеры для продвинутых сценариев есть в вики.

Итог
Использование Auto Release Template сокращает время на создание релизов, позволяет остановиться или откатиться на любом шаге и обеспечивает аккуратный changelog прямо в GitHub релизе. Дополнительно, с правильной настройкой GitHub Actions, это даст возможность публиковать релизы даже в приватных и командных репозиториях.

#ci #git #github #npm


Веб-стандарты dan repost
Явное управление ресурсами в JavaScript. Мэтт Смит объясняет using и await using, а также Symbol.dispose и Symbol.asyncDispose, чтобы очистка всегда выполнялась при выходе из области видимости и в обратном порядке для нескольких ресурсов. Для большей гибкости есть DisposableStack и AsyncDisposableStack. #js #ecmasript

https://allthingssmitty.com/2026/02/02/explicit-resource-management-in-javascript/


mefody.dev dan repost
Переезд с Chalk на нативный styleText

Есть такая утилита Chalk, которую даже если вы осознанно в проект на Node.js не подключали, есть высокая вероятность, что подключали неосознанно. У неё какое-то неприличное девятизначное число скачиваний в неделю. И нужна она, чтобы в терминале красиво выводить текст: с фоновым цветом, разноцветно, жирненько или курсивом и так далее.

В Node.js v22.13.0 стабильной стала нативная утилита node:util.styleText, которая может почти всё то же самое, но с некоторыми ограничениями. Для нас, разработчиков, это приятное удаление лишней зависимости и более быстрое логирование.

А самое приятное, что можно запустить официальный кодмод от команды Node.js, который мигрирует ваш проект сам:


npx codemod @nodejs/chalk-to-util-styletext


https://nodejs.org/en/blog/migrations/chalk-to-styletext


Веб-стандарты dan repost
Простые поля для одноразовых кодов. Тайлер Стика показывает, как создать полностью рабочее поле для одноразового пароля (OTP) с помощью одного HTML-элемента — без JavaScript, CSS-хаков и сторонних библиотек. Достаточно атрибутов inputmode="numeric", autocomplete="one-time-code" и pattern="\d{6}", чтобы обеспечить автозаполнение, валидацию и доступность. Всё остальное можно добавить как прогрессивное улучшение. #html #a11y

https://cloudfour.com/thinks/simple-one-time-passcode-inputs/


Почему не стоит проверять email сложными регулярными выражениями

Если у вас появилась задача "проверить полное соответствие введённого email стандарту RFC", то скорее всего вы не понимаете реальной цели формы, которую даёте на заполнение пользователю. Единственная правильная цель – убедиться, что с введённым адресом можно связаться с пользователем.

Написание сложных regex, вроде:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\ x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])

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

Простая проверка

Если нужно просто убедиться, что пользователь не ошибся полем, достаточно проверить наличие символа @.

Если нужен более строгий подход: .+@.+\..+, это проверит:
- наличие хотя бы одного символа до @
- наличие домена после @
- наличие точки и домена верхнего уровня

Даже эта проверка чаще всего избыточна: главная задача — чтобы адрес был действующим.

Почему полноценная проверка избыточна

RFC 5322 описывает email как довольно сложную конструкцию:
- в локальной части до @ допустимы специальные символы
- допускаются комментарии в скобках, включая вложенные
- сервер обрабатывает локальную часть по своим правилам, и нестандартные адреса могут быть валидными

Даже идеально написанный regex может отклонять рабочие адреса. Строгая проверка может оттолкнуть пользователей с нестандартными, но рабочими почтовыми серверами.

Единственный надёжный способ проверить, что email рабочий, — это отправить письмо с подтверждением. Только так вы можете убедиться, что адрес действительно существует и пользователь реально может получить на него письмо.

Базовые правила проверки

Для упрощённого взаимодействия с пользователем достаточно проверить:
- поле не пустое
- поле содержит символ @
- наличие защиты от SQL-инъекций или других очевидных злоупотреблений

Итог

- Сложные regex для email почти всегда избыточны
- Базовой проверки достаточно для большинства задач
- Основной инструмент проверки — подтверждающее письмо

#html


Vueist dan repost
SFC и раздутые компоненты

какое-то время в нескольких сообществах бурно обсуждаются плюсы и минусы подходы к SFC в целом. Описание всех плюсов и минусов оставлю на другой раз. Сейчас же сосредоточимся на конкретной претензии: SFC ведет к раздутым компонентам. Так ли это? А давайте разберемся с этим на примере работы в вакууме.

1. У вас есть компонент и внутри него есть template + style + script
2. В какой-то момент времени вы ловите себя на мысли "компонент стал большим, по нему неудобно навигироваться и работать с ним"
3. Вам нужно что-то предпринять

И тут у вас 2 выбора, но вначале разберем первый:
Взять компонент и посмотреть на него еще раз:
- Вынести переиспользуемую логику в композаблы
- Разбить шаблон на более базовые компоненты
- Даже банально вынести обычные утилиты из компонента

Итого получаем обратно более лаконичный компонент, он не раздут. Стало больше переиспользуемых частей. Это и есть pit of succes.
- Делать хорошо легко: маленькие компоненты легко и приятно поддерживать в SFC стиле
- Делать вербозные и раздутые компоненты неудобно, навигация усложняется и вы чувствуете как много времени уходит на что-то не то
- Есть мотивация перейти из плохого состояния в хорошее: у вас естественным образом возникает желание разбить компонент

Однако иногда система дает сбой и кому-то кажется, что решение проблемы это "а давайте разобьем компонент и вынесем из него css/html/js" не важно что. Как только вы поставили самоцелью сделать не функциональное разбиение, а типовое, то вы сразу
1) Ломаете то как работает изначальная идея: вам должно неприятно работать с раздутыми компонентами
2) Ломаете привычный флоу работы со Vue
3) Теряете плюсы которые дает SFC
И ради чего? Ради того, чтобы лечить раковую опухоль(использование практики раздутых компонентов) сбивая температуру(просто разбивая файл, а не функционал)

Надеюсь, что мораль ясна. А вам стало понятна еще одна причина, почему SFC — это хорошо

20 ta oxirgi post ko‘rsatilgan.