Интерактивный стримкаст со зрителями 9 марта в 19:00
Максим будет писать веб интерфейс для вики (с выделением текста и возможностью отставлять инлайн комментарии) с помощью последней версии Copilot agent. А все мы (включая вас) — токсично (и не очень) комментировать.
Если вы только начинаете (или хотите начать) изучать JavaScript, то для вас есть подборка обучающих материалов. Все они доступны бесплатно. Регистрироваться, оставлять контактные данные или оформлять подписку тоже не нужно.
Если долго использовать какой-то инструмент, мозг вырабатывает паттерны: мы повторяем одни и те же решения, не всегда задумываясь, что появились новые, более удобные способы. Так происходит и с JavaScript.
JS развивается каждый год, но многие продолжают писать код, как привыкли, не используя свежие возможности языка. Я стараюсь бороться с этим и внедрять новшества в свою повседневную работу и недавно пошел посмотреть что там нового подвезли в ECMAScript 2024 (ES15). А там оказалось довольно много интересного.
Например, новые методы массивов. Раньше методы вроде .sort() и .reverse() изменяли исходный массив, что могло привести к неожиданным багам.
Точно так же работают новые методы .toSorted() и .toSpliced(). Они делают код более предсказуемым и чистым.
Также, я с огромным восхищением прочитал про Temporal - новый объект для работы с датами и временем. Например, меня всегда поражало , что в Date месяцы индексируются с 0 (январь – это 0), а вот дни месяца начинаются с 1. Temporal фиксит эти проблемы и теперь можно: ✅ Создавать объекты только с датой или только со временем ✅ Удобно складывать и вычитать даты ✅ Работать с часовыми поясами без боли В общем делать все, для чего мы раньше тащили в проекты всякие moment и day.js.
К огромному сожалению Temporal пока не поддерживается в браузерах, но когда выйдет – работа с датами в JS станет в разы удобнее.
Если вам интересны такие обновления подписывайтесь на мой Telegram-канал!
Вчера впервые попробовал flushSyncб который подвезли в React еще в 18 версии. Классное решение для определенных моментов! Выглядит так, будто React выдал нам костыль, но сразу предупредил: пользоваться с осторожностью.
❓ Почему это вообще нужно? (Для тех, кто не совсем в теме) В React изменения в useState или в useEffect выглядят синхронными, но на самом деле они асинхронны.
Простой пример:
...
const [count, setCount] = useState(0);
console.log(count); // 0
setCount(1); console.log(count); // Всё ещё 0! 😲
...
Кажется, что setCount(1) сразу меняет count, но на самом деле новое значение попадёт в консоль только при следующем ререндере.
То же самое в useEffect:
...
useEffect(() => { console.log("Эффект сработал!"); }, [count]);
setCount(1); console.log("А это после setCount");
...
Лог "А это после setCount" появится в консоли раньше, чем "Эффект сработал!", потому что useEffect выполняется уже после рендера.
Как flushSync меняет поведение?
Обычно React группирует обновления (batching) и откладывает ререндер до конца текущего цикла. flushSync ломает это поведение и заставляет React сразу выполнить ререндер.
Что тут происходит? Без flushSync React подождал бы до конца текущего вызова и только потом обновил DOM. С flushSync обновление происходит немедленно, и console.log видит уже новый DOM.
React нас предупреждает В документации прямо сказано:
"flushSync – это низкоуровневый API. Используйте его только тогда, когда вам действительно нужно измерить DOM сразу после обновления состояния."
Когда не стоит использовать flushSync? Если можно обойтись обычными useEffect или useLayoutEffect. Если batching работает нормально и не мешает. Если нет необходимости немедленного ререндера (иначе можно уронить производительность).
Итог flushSync – мощный инструмент, но использовать его нужно осознанно. Он нужен в случаях, когда важно немедленно обновить стейт и тут же прочитать DOM (например, для анимаций).
Если понравился пост присоединяйтесь к моему каналу в Telegram по ссылке https://t.me/+qbK9ZPuAocI2MWUy. Там я делюсь своим опытом и пишу материалы которые будут полезны как новичкам, так и матерым разработчикам.
По итогам жарких обсуждений и критики по поводу медленного кода и плохого fps в тесте вывода на экран графика sin()+noise для Matplolib были внесены усовершенствования и привлечен ИИ для полировки. Исходная статья и код https://habr.com/ru/articles/878002/
Отказ от медленного вывода текста, применение FuncAnimation вместо простого цикла, применение мэджик команды для подключения PyQT backend. FPS поднялся с 12 до 35. Подробности читайте в исходной статье https://habr.com/ru/articles/878002/
Оригинальная идея второго графика позволила отказаться от медленного вывода текста
Написана статья о тестировании (и сравнении FPS) на скорость рисования 2D графиков на python популярных и относительно малоизвестных графических пакетов 2D и 3D (Mayavi 3D, PyVista, Matplotlib, PyQTGraph, Plotly, PyGame, Arcade, pyOpenGL, VisPy, Bokeh) Возникли некоторые технические проблемы и срок публикации пока не ясен (надеюсь, на следующей неделе). Поэтому, заинтересовавшиеся коллеги, прошу подписаться на мой профиль на хабре, чтобы не пропустить публикацию этой статьи. В статье будут видео с отрисовкой в реальном времени 2D графиков и будут измерены FPS. Специально использовался слабенький мини ПК без дискретки. Тем не мене FPS достигал в некоторых случаях 100. Пример видео ниже:
Признавайтесь, кто любил в детстве пострелять уток? Для скучающих по Nintendo товарищ jslegend написал веб-версию игры Duck Hunt (прежде, чем уходить играть, не забудьте поставить нам лайк) на JavaScript с использованием библиотеки KAPLAY.
Управление максимально простое — стрелять ЛКМ, а кнопка P ставит игру на паузу. Мышкой играть, конечно, не так удобно, но достаточно, чтобы вызвать ностальгическую улыбку.
Бросите вызов уткам и злодейски хихикающей собаке?
Как избавиться от всех костылей? Достаточно всего лишь одной функции...
Если считаете, что это кликбейт — настоятельно рекомендуем посмотреть доклад Марата Зимнурова, техлида Авито. В своем выступлении Марат раскрывает все подробности функционального программирования:
что это такое — функциональное программирование — на практике?
какие методы оттуда уже проникли в повседневную разработку?
какие конкретные недостатки существуют для применения такого способа, в том числе в JavaScript?
В примерах — детальный разбор, как написать веб-приложения и бэкенды, используя практики функционального программирования.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
Буквально на днях со мной произошла интересная история, которой я хочу поделится с Вами.
Я состою в одном чатике, где собрались энтузиасты Telegram Mini Apps. Там фаундеры, разработчики и просто интересующиеся обсуждают идеи, делятся опытом и помогают друг другу. Мне очень интересна эта тема, и я планирую запустить что-то своё на базе Telegram.
Но ближе к делу. 2 января в чат зашёл человек в поисках разработчика для своего проекта. Он выглядел весьма взволнованным и объяснил, что помимо долгосрочного сотрудничества ему срочно нужен фикс для его мини-приложения. Это небольшое приложение с игровой механикой, у которого Monthly Active Users (MAU) — около 30 тысяч. Впечатляет, согласитесь! Проблема заключалась в том, что текущие разработчики ушли на праздники и не выходили на связь.
Я решил попробовать помочь просто ради интереса. Сидел за компьютером, пытаясь дописать свою дипломную работу, а мозг требовал смены деятельности. Когда мне дали доступ к репозиториям, я увидел следующее:
Проект довольно крупный: около 10k строк кода на фронтенде и 5k строк на бэкенде.
Фронтенд написан на React с использованием Jotai для управления состоянием. Интерфейс реализован с помощью Tailwind CSS.
Бэкенд — Express.js, взаимодействующий с MongoDB.
Весь проект написан на чистом JavaScript, и вот что меня поразило:
Полное отсутствие типов. Никакого TypeScript, PropTypes или хотя бы JSDoc. После нескольких лет работы с TS мне было трудно принять, что я не могу быстро понять, какие аргументы ожидаются в функциях. Я думал что все крутые проекты используют TS, а JS только для маленьких проектов, обучения и чего-то не совсем серьезного.
Полное отсутствие безопасности. Захардкоженные ключи для подключения к телеграм боту и базе данных. Сервер обрабатывает запросы с любого origin. Это буквально учебник по тому, как не надо делать.
Нарушение принципов DRY. Например, в коде вручную прописывались заголовки для fetch-запросов — везде, где только можно.
Неоптимальный код. Неправильный вызов хуков, отсутствие lazy loading, дублирование логики и так далее. Я могу продолжать список почти бесконечно.
В общем, код был ужасен. Даже мои студенты, которые только начинают изучать программирование, иногда пишут лучше. Но! Несмотря на всё это, продукт работал, пользователи были довольны, и проект приносил прибыль.
Я быстро разобрался с багом, исправил его и в итоге получил предложение помочь улучшить проект. В ближайшие пару недель как раз займусь этим — заработаю сыну на шоколадки и, надеюсь, сделаю код немного лучше. А теперь — к выводам, которые я сделал (а точнее получил подтверждение в очередной раз):
Выводы:
Работа и подработка всегда найдутся. Если у вас есть знания и навыки, найти проект даже в текущее время— не проблема. Главное — свободное время и скилл. Я получил подтверждение этого тезиса в очередной раз и последние несколько лет я понимаю, что возможность зарабатывания денег ограничивается только наличием свободного времени для этого. Ну и осознав это я пытаюсь найти варианты, которые напрямую не связаны с обменом моего времени на деньги. Во многом моя попытка раскачать телеграмм канал именно об этом.
JS жив и приносит прибыль. Люди продолжают писать серьёзные проекты на JavaScript. Да, TypeScript стал стандартом в моей работе, но это не мешает другим писать на чистом JS и чувствовать себя отлично.
Маркетинг побеждает. Код, который я видел, был ужасен. Но приложение успешно благодаря сильному маркетингу. Это очередное подтверждение фразы: “Best products never win. But best sales & marketing always win.” Как программисты, мы должны стремиться к чистому коду и хорошей архитектуре, но успех продукта в конечном счёте определяется вовсе не этим.
А что вы думаете о роли маркетинга? Согласны ли вы, что он может перевесить техническую сторону?
Если вам интересны темы веб-разработки, тимлидства, управления проектами и вы хотите получать больше полезного контента, присоединяйтесь к моему Telegram-каналу.
Объектно-ориентированное программирование и его реализация в JavaScript
Именно так звучит тема нового выпуска нашего открытого курса по JavaScript. В 12 серии вместе с веб-разработчиком Василием Новиковым разберёмся:
что такое объектно-ориентированное программирование (ООП) и его функции;
как реализовывать ООП на конкретном примере;
как применять метод проверки getPrototypeOf.
Больше информации о сериях, а также полезных материалах к ним можно найти на сайте курса JS.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
Немного о резолверах в Angular 19 (теперь в них есть редиректы).
В логике использования гвардов применяется подход:
проверить что-то, если все ок то вернуть true или кинуть редирект на другую страницу
Выглядит достаточно удобно. Но если мне не изменяет память в резолверах такого нет, вместо этого приходилось натягивать Router и рулить navigate или navigateByUrl и т.д.
В 19 же версии нам немного упростили жизнь и резолвер научили в RedirectCommand.
Пришло время зафиналить тему контекста исполнения: в новом выпуске нашего открытого курса по JavaScript веб-разработчик Василий Новиков рассказывает про способы вызова функции и методы bind, call и apply.
Из одиннадцатой серии вы узнаете:
как автоматически установить thisArgument для функций;
как работают методы bind, call и apply при ручной установке;
как ведут себя стрелочные функции при привязке this через bind, call и apply.
Больше информации о сериях, а также полезных материалах к ним можно найти на сайте курса JS.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
Собрали подборку различных ресурсов, которые помогут познакомиться с JavaScript, узнать больше об этом языке и попрактиковаться. Сохраняйте, чтобы не потерять, и делитесь с коллегами.
Телеграм-каналы
Задачи по Frontend — опросы, которые помогут разобраться в вёрстке и основах.
Frontend | Вопросы собесов — разбор вопросов с собеседований: HTML, CSS, JavaScript, фреймворки React, Angular и Vue.js.
Будни разработчика — блог с рабочими инструментами, новостями, видео и лайфхаками.
YouTube-каналы
Yandex for Frontend — о командах и технологиях, запис с митапов и конференции.
IT-KAMASUTRA — советы для начинающих и обзоры инструментов. Есть плейлисты по JS: про изучение с нуля и прохождение собеседований.
dcode — туториалы по разработке. HTML, CSS, JavaScript, PHP и Rust.
Недавно при создании приёмочных тестов для плагина столкнулся с необычной ситуацией. В before-хуке настраивалось окружение: записи в БД, моки зависимостей. В after-хуке происходила зачистка. Отдельно тест работал, но в группе начинал сбоить: оставались следы от предыдущих тестов.
При запуске под отладчиком it-секции пропускались и сразу выполнялись after-хуки. "Игорь Иваныч" (ИИ) объяснил, что mocha пропускает тесты, если в before-хуке есть ошибки. Использование try-catch и несколько часов отладки и рефакторинга убедили меня только в том, что ошибок нет, но it-блоки всё равно пропускаются.
Однако на следующий день при запуске всех тестов мой проблемный тест неожиданно заработал. Хотя при попытке отладки он опять начинал сбоить. Правильно заданный вопрос "Игорь Иванычу" привёл к получению правильной "таблетки":
before(async function () {
this.timeout(60000); // 1 min
});
Всё. Это сняло проблему. В mocha по-умолчанию timeout для выполнения before-хука составляет 2 секунды. Ошибкой с точки зрения mocha было то, что разработчик (т.е. - я) тупил в отладчике больше 2 секунд и не оповестил её об этом в явном виде.
Это вполне себе логичное поведение фреймворка, о котором нужно просто знать. Теперь я знаю. Но если бы я знал об этом перед началом отладки, то я бы сэкономил несколько часов своей жизни.
Об этом веб-разработчик Василий Новиков рассказывает в новой серии нашего открытого курса по JavaScript. Из десятой серии вы узнаете про:
три вида записей окружения: LexicalEnvironment, VariableEnvironment и PrivateEnvironment;
шаги каждого из четырех алгоритмов контекста исполнения;
инициализацию глобального контекста исполнения.
Больше информации о сериях, а также полезных материалах к ним можно найти на сайте курса JS.
Подписывайтесь на канал AvitoTech в Telegram, там мы рассказываем больше о профессиональном опыте наших инженеров, проектах и работе в Авито, а также анонсируем митапы и статьи.
Для тех, кто рассматривает TypeScript как инструмент (язык) для борьбы с ошибками: склонность к ошибкам и время их исправления в TypeScript оказались не значительно ниже, чем в JavaScript. Среднее отношение коммитов с исправлениями ошибок в проектах на TypeScript было более чем на 60% выше (0.126 против 0.206), и в среднем проектам на TypeScript требовалось более чем на один день больше для исправления ошибок (31,86 против 33,04 дней).
В одном из комментариев был вопрос по поводу Promise, а умеет ли Joomla? Умеет, но начиная с Joomla 4. Достаточно при создании запроса выставить флаг promise в true и результатом выполнения запроса будет Promise: