Будни разработчика
14.4K subscribers
1.27K photos
379 videos
8 files
2.17K links
Блог Lead JS-разработчика
Автор: @bekharsky

По рекламе: https://telepost.pro/ch/id2415 или https://t.me/it_adv

Чат: https://t.me/htmlshitchat

№5001017849, https://www.gosuslugi.ru/snet/679b74f8dad2d930d2eaa978
Download Telegram
Я довольно часто вижу тексты про выгорание и «научитесь отдыхать», и каждый раз немного спотыкаюсь об один момент. Там обычно много советов про хард-стопы, не писать после восьми, не работать в отпуске — и это всё, конечно, правильно. Но создаётся ощущение, что проблема будто бы решается просто дисциплиной: возьми и выключи работу из головы.

Вот в тему поста Димы из Яндекс Лавки — поймал себя на мысли, что на практике это у многих работает чуть сложнее. Мозг продолжает крутить работу не из вредности. Он просто пытается дожевать то, что осталось незакрытым: нерешённую задачу, странное решение, ощущение, что что-то пошло не так. И сколько ни говори себе «стоп», если внутри висит этот незакрытый хвост — он всё равно будет возвращаться.

Иногда помогает довольно простая вещь: довести мысль до какого-то финала. Принять решение. Даже если это решение — «ну и чёрт с ним».

Недавно у меня сломался чемодан — крепление колёс. Первый раз починил. Второй раз починил. На третий раз даже приготовил всё для ремонта — и вдруг понял, что это уже какой-то чемодан без ручки.

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

С рабочими задачами часто так же. Иногда мозгу нужно не «перестань думать», а точка: решение, план, отказ, перенос, признание, что это не стоит времени. Как только она появляется — он обычно довольно охотно отпускает.
12👍4🤡4🤩1
#инструмент дня

Иногда мелкие неудобства в разработке настолько привычны, что мы перестаём их замечать. Один из таких примеров — бесконечные localhost:3000, localhost:5173, localhost:8080.

Запускаешь несколько сервисов — фронтенд, API, сторибук, документацию — и через час уже не помнишь, что было на каком порту. Перезапустил сторибук — и он уже на другом.

Бесит.

В Vercel Labs решили попробовать убрать саму причину проблемы и выпустили экспериментальный инструмент Portless. Идея очень простая: вместо портов использовать локальные доменные имена.

Было так:

http://localhost:3000
http://localhost:8080
http://localhost:5173


Стало так:

http://app.localhost
http://api.localhost
http://docs.localhost


Домены просто пробрасываются на реальные порты. Но разработчику больше не нужно их помнить.

Самое интересное — почему это вообще стало возможным.

Несколько лет назад в спецификациях закрепили правило: любой домен вида *.localhost должен автоматически резолвиться в loopback-адрес (127.0.0.1). Браузеры реализовали это поведение, поэтому api.localhost, app.localhost и любые другие подобные имена гарантированно указывают на ваш компьютер и даже считаются безопасным контекстом для веб-API.

Это открыло путь для инструментов, которые делают локальную разработку похожей на продакшен и больше не вспоминать, где был :3000, а где :5173.

Такая схема неожиданно удобна и для AI-инструментов. Когда адрес сервиса всегда один и тот же (app.localhost), кодовые агенты не ломаются из-за того, что dev-сервер внезапно переехал на другой порт.

В общем, такое мы одобряем.

Впрочем, никто никогда не мешал поднять локальный nginx и делать вообще что угодно.

#dev #port
1👍33
#событие дня

Я понятия не имею, как я пропустил! Итак, соревнование March MadCSS!

16 лучших фронтенд-разработчиков схлестнутся в жаркой битве по вёрстке интерфейсов.

Ну, я надеюсь, вам что-то говорят имена Josh Cameau, Wes Bos, Kyle Cook, Chris Coyier... если нет — очень зря!

Первый раунд был неделю назад и его можно посмотреть на YouTube: https://www.youtube.com/watch?v=nuxSFTjXrhI

А второй как раз будет сегодня.

И да, даже лучшие верстальщики мира гуглят, как выровнять текст.

Сайт ивента с турнирной таблицей и мерчом: https://madcss.com/

Смотрим?

#css #dev #battle
6🤩1
#статья дня

Как вообще меняется JavaScript?

В блоге Bloomberg вышла интересная история про Temporal — новый API для дат и времени. Но статья на самом деле не столько про сам API, сколько про то, как такие вещи вообще появляются в языке.

Объект Date появился в JavaScript в 1995 году и, по сути, был просто позаимствован из Java. Тогда это казалось нормальным решением. Спойлер: нет.

Проблема в том, что веб сильно вырос, а Date почти не менялся. Со временем стало понятно, что работать с датами в JavaScript неудобно: таймзоны, переходы на летнее время, странный парсинг строк.

Экосистема ответила библиотеками вроде Moment.js, date-fns и Luxon. Их скачивают десятки миллионов раз в неделю — почти каждый проект как-то решает эту проблему.

В 2017 году появилась идея сделать нормальный API прямо в стандарте. Так началась история Temporal.

Дальше — девять лет обсуждений и доработок. В работе участвовали инженеры из Microsoft, Google, Mozilla, Bloomberg и Igalia. Предложение прошло весь процесс TC39 и в итоге стало крупнейшим добавлением в ECMAScript со времён ES2015.

Любопытная деталь: для реализации Temporal разработчики движков даже сделали общую библиотеку на Rust — temporal_rs. Редкость!

Ещё, конечно, поражает количество тестов.

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

Почитать:
https://bloomberg.github.io/js-blog/post/temporal/

Если что, есть и перевод.

#javascript #temporal
👍9
#ссылка дня

Поскольку не говорить про ИИ и агентсткую разработку не получается, давайте пробовать хотя бы извлекать из этого пользу.

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

Вот только пока что всё ровно наоборот! Все же знают, что такое skills — умения?

А skills в контексте ИИ-агентов — это буквально описание лучших практик. Вот это делай, вот это не делай, а в случае таких-то условий, поступай вот так.

Люди создают целые маркетплейсы скиллов, конкурируют за лучшие из них, пишут решения для своей работы. А самое главное, скиллы — это, буквально, текст! Который и прочитать может кто угодно. Да, сжато, но всё же.

Ладно, к чему это я. Anthropic выкатили гайд по созданию скиллов. Да, формально — для Claude, но все известные мне инструменты подхватывают скиллы Клода вообще без проблем.

И почему-то по принятой в западном сегменте интернета традиции — в абсолютно ублюдочном формате презентационного PDF на 33 страницы.

К счастью, нашёлся человек, который не только перевёл это на русский, но и оформил в виде нормального веб-решения: https://fkonovalov.github.io/claude-skills-guide-ru/

fkonovalov, спасибо! :)

#ai #skills
12🫡2
#заметка дня

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

А тема сегодняшней заметки — очередная статья на тему «Нам не нужен useEffect»: вот тут.

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

И недосказанность эта связана с тем, что ВСЕ ваши прекрасные библиотеки управления состоянием, анимацией, загрузкой данных и кешем — будут использовать useEffect внутри себя. И говорить, что вы отказываетесь от useEffect — не очень верно.

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

Тем не менее, самый любимый пример, когда отказ от useEffect действительно имеет смысл — на иллюстрации.

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

Продублирую текстом:


// BAD: Effect attempts to emulate remount behavior
function VideoPlayer({ videoId }) {
useEffect(() => {
loadVideo(videoId);
}, [videoId]);
}

// GOOD: key forces clean remount
function VideoPlayer({ videoId }) {
useMountEffect(() => {
loadVideo(videoId);
});
}

function VideoPlayerWrapper({ videoId }) {
return <VideoPlayer key={videoId} videoId={videoId} />;
}


Это настолько чисто, элегантно и понятно — что удивляешься, почему это не стало общим паттерном.

Впрочем, дело за вами, котаны.

#react #useeffect #article
1🫡5👍4👎32
#фишка дня

А вы знали, что Apple уже очень давно для каждой ноутбука поставляет и 3D-модель?

Кроме шуток, если зайти на страницу продукта с Safari на iPhone, появится возможность посмотреть, например, ноутбук в дополненной реальности. Ясное дело, скачивается 3D-модель. Но эту модель легко вытащить и посмотреть даже на десктопе! Ссылка, нонечно, скрыта, потому лезем в исходники и ищем USDZ-файл.

USDZ расшифровывается как Universal Scene Description Zipped, и придумал был ещё в Pixar. Что значит Zipped? Очевидно, zip-контейнер, а значит, можно распаковать и найти там и модель, и текстуры и карты нормалей.

Но это история давняя, ARKit с нами уже лет 10. Что новое — это то, что начиная с MacBook Neo модель поставляется с возможностью конфигурации по цвету и состоянию! Закрыт-открыт, розовый-жёлтый... вот это вот всё.

Можете сами зайти на яблочный сайт и скачать USDZ любого продукта. Как минимум, это забавно. А дальше уже можно и модельки покрутить, если надо.

#apple #3d #ar
👍5
#статья дня

Страница грузится 7 секунд.
Причина — один эмодзи ❤️

Иногда проблемы с производительностью оказываются совсем не там, где их ищешь. В статье Аллена Пайка «A Broken Heart» он разбирает случай, когда страница внезапно начала грузиться по 7 секунд, хотя сервер, сеть и JavaScript работали нормально. В профайлере оказалось, что почти всё время Safari тратит на layout — причём один проход занимал больше секунды.

Дальше — обычный путь: постепенно вырезать куски интерфейса и смотреть, когда станет быстрее. В какой-то момент выяснилось, что всё упирается в один эмодзи в кнопке. Убираешь его — всё работает мгновенно. Возвращаешь — снова тормоза.

Причина оказалась в том, как Safari работает со шрифтами. Если указать Noto Color Emoji как основной шрифт, он используется даже для обычного текста, хотя покрывает только эмодзи. Для всех остальных символов браузер каждый раз ищет подходящий fallback-шрифт. В процессе layout он пересчитывает размеры текста, переносы строк и позиции элементов, и делает это много раз подряд.

В норме такие пересчёты почти ничего не стоят, но в Safari здесь есть просадка, из-за которой всё резко замедляется. В итоге одна строка с emoji-шрифтом может увеличить время layout в десятки или даже сотни раз.

Минимальный пример:


<link href="https://fonts.googleapis.com/css2?family=Noto+Color+Emoji" rel="stylesheet">

<style>
body {
font-family: "Noto Color Emoji";
}
</style>

<button>Click ❤️</button>


Если не ставить emoji-шрифт основным, а оставить его только в конце списка как fallback, проблема исчезает. В оригинальной статье есть ещё детали про поиск причины и минимизацию примера — стоит почитать: https://allenpike.com/2026/a-broken-heart/

Ну и официальный issue: https://bugs.webkit.org/show_bug.cgi?id=305636

Потрясающая хрень, конечно. На пустом месте.

#css #emoji #svg #performance
1👍2310🫡1
#фишка дня

Я всегда считал карту кода достаточно бестолковой фишкой. С другой стороны, TODO-комментарии и ошибки достаточно легко распознаваемы и перемещаться по ним удобно.

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

В идеале, конечно, не стоит развозить свой код на несколько экранов, но прежде чем разбивать — надо ж распознать, верно? :)

#vscode #minimap #бородач
👍10🤩2
This media is not supported in your browser
VIEW IN TELEGRAM
#такое дня

Развлекаюсь тем, что извлекаю из ТВ-пульта на Flutter разные общие штуки в библиотеки. Первым на выход пошла реализация DLNA, ну а теперь — D-Pad, крестовина.

Понятное дело, сама по себе крестовина мало интересна. А вот как концепт радиального меню — очень даже!

Ну и потренироваться выкладывать пакеты в общий репозиторий тоже надо.

#flutter
5
#статья дня

А ну, сходу ответьте, чем отличается :has(:not()) от :not(:has())?

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

Разработчики браузера для, простите, разработчиков —Polypane — ведут свой блог с разными мелкими фишками, и сегодня — вот такая, как раз об этом.

📌 :has(:not())

Выбирает элементы, которые содержат определённые дочерние элементы, но не содержащие другие.


.card:has(:not(img)) {
background: lightblue;
}


🔹 Выберет .card, если внутри есть любой элемент, кроме <img>.

📌 :not(:has())

Выбирает элементы, не содержащие определённый дочерний элемент.


.card:not(:has(img)) {
background: lightcoral;
}


🔹 Выберет .card, если внутри вообще нет <img>.

🏁 Итого:

:has(:not(img)) проверяет, есть ли что-то, кроме <img>.
:not(:has(img)) проверяет, что <img> вообще нет.

Ну а в статье всё то же самое, только чуть подробнее.

Не ошибайтесь, котаны.

#css #has #not #бородач
👍135
Стань стажером-разработчиком Frontend/Fullstack в Яндексе

Реализуйте новые фичи и интерфейсы в приложении Умного Дома, пишите веб‑приложения для роботов‑доставщиков и автономных машин, участвуйте в развитии международных финтех‑стартапов Yango Pay и Buy&Sell, создавайте геймификацию на трекинге заказа в Яндекс Лавке и Яндекс Карты нового поколения.

Фронтенд-разработчику необходимо:
— уверенно владеть HTML, CSS и основами JavaScript
— иметь опыт взаимодействия с TypeScript, React и SSR. Как преимущество: понимать основы Git, Docker, написания тестов
— обладать базовыми техническими навыками.

Фулстек-разработчику необходимо:
— иметь опыт с Node.js
— понимать основы CI/CD, баз данных, WebSocket, REST API или GraphQL
— знать основы Python или Go.

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

Станьте частью одной из команд фронтенд или фулстек разработчиков в Яндексе — оставляйте заявку.
🤡8👍1
This media is not supported in your browser
VIEW IN TELEGRAM
#красивое дня

Угадайте, что красиво летит по небу и укладывается в 249 символов?

Правильно, SpaceX Starship!

Не, ну правда:

vec2 p=(FC.xy-r*.5)/r.y*mat2(8,-6,6,8),v;for(float i,f=3.+snoise2D(p+vec2(t*7.,0));i++<50.;o+=(cos(sin(i)*vec4(1,2,3,1))+1.)*exp(sin(i*i+t))/length(max(v,vec2(v.x*f*.02,v.y))))v=p+cos(i*i+(t+p.x*.1)*.03+i*vec2(11,9))*5.;o=tanh(pow(o/1e2,vec4(1.5)));


Это валидный код шейдера на GLSL для приложения Twigl: https://twigl.app/?ol=true&ss=-OGqcXbWDIJun2QTR4Cm

Они буквально конкуренты Shadertoy, и тот и другой — онлайн-инструменты для мгновенной проверки и рисования шейдеров на языке GLSL.

Вот, кстати, пример на Shadertoy: https://www.shadertoy.com/view/XX3fDH

В этом варианте ещё и камера дрожит.

Красиво? Не то слово!

#shader #glsl #3d #бородач
🤩6👍2
🌐 Что происходит внутри инфраструктурных сервисов Yandex Cloud?

Разработчики Yandex Cloud и Yandex Infrastructure расскажут об этом на встрече для разработчиков, архитекторов и инженеров, которая пройдет 16 апреля.

В программе вас ждут реальные технические варианты реализации и опыт нетривиальных решений разработчиков платформы:

— Инфраструктура как код для управления оповещениями: и никаких проблем
— Развёртывание в ритме танго: как мы заменили оркестрацию процесса установки «хореографией»
— Как мы оптимизируем вывод больших языковых моделей: кэширование, время отклика и ресурсы графических ускорителей
— Как мы строили собственную сеть доставки контента и через что нам пришлось пройти?
— Как мы работаем с уязвимостями на примере современных аппаратных атак

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

Участники смогут обсудить волнующие вопросы, варианты реализации и ошибки с разработчиками сервисов Yandex Cloud и другими участниками.

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

Зарегистрируйтесь, чтобы послушать реальные истории от разработчиков, обменяться опытом и узнать, что скрыто под «капотом» инфраструктурных сервисов, а также какие планы у команды на будущее!
🤡2
#видео дня

Оказывается, у блога Chrome for Developers есть свой собственный YouTube-канал: https://www.youtube.com/@ChromeDevs

Формат, правда, довольно странный. Основу канала составляют видео по 1-3 минуты, и нет, даже не все из них шортсы. Впрочем, есть и подкасты.

Ладно, это я к чему. Они выкатили очень пафосное видео о том, как в Pinterest пересмотрели свои методы создания CSS-каруселей и — как утверждается — избавились от кучи джаваскрипта, перейдя на нативные View Transitions и свежие API для скролла: https://youtu.be/oWJPu3yvfp8

Но, конечно, невозможно в две с половиной минуты уместить все идеи проекта. Потому действительная польза — в описании! А что там у нас?

А, собственно, ресурсы для повторения:

Доступные карусели → https://goo.gle/4aTpGtc
Карусели на CSS → https://goo.gle/3YuWhOv
Локальные View Transitions → https://goo.gle/3XuZMUX
View Transition API → https://goo.gle/3MzVngY

Другой вопрос, конечно, в том, что половина этих API толком недоступна не то что в других браузерах, а даже в самом Chrome без флага, это они аккуратно обходят стороной.

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

#chrome #css #carousel
5
2022-12-19_18-39-04.jpg
2.8 MB
#vscode дня

Если вы умеете пользоваться поиском — вы уже миддл. Если поиском с заменой — смело называйте себя сеньором.

Я щас не шучу, know your tools!

Огромное количество разработчиков вообще с трудом понимает, что код — это просто текст, без подсказок IDE не справляются. Но не будем о наболевшем.

Сейчас я вам покажу нечто, что выведет поиск кода на новый уровень: расширение CodeQue!

Ссылка: https://marketplace.visualstudio.com/items?itemName=CodeQue.codeque

Я иллюстрацию файлом приложу, ибо иначе мелко. Но в чём соль: вы можете искать код, который напоминает тот, что написан в области поиска!

Например, в примере — ищем div, внутри которого есть ещё div с атрибутом className, установленным через clsx. Или ещё, можнот найти все формы, внутри которых есть select (необязательно, HTML-тег или компонент).

Я честно говоря сразу вообще не понял, нафига это надо — есть же RegExp.

Но потом ка-а-ак понял!

#search #extension #бородач
👍131🫡1
This media is not supported in your browser
VIEW IN TELEGRAM
#инструмент дня

Хотели попробовать local‑first? Zero от Rocicorp — отличный способ это сделать.

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

Запросы к данным автоматически становятся подписками и кэшем. Не нужно писать refetch, invalidate или подписки вручную — библиотека сама решает, какие данные хранить на клиенте и когда их обновлять. Изменения, сделанные на клиенте, сразу видны в UI, а сервер получает их в фоне.

На клиенте данные хранятся в IndexedDB, что обеспечивает быстрый доступ и поддержку оффлайна. На сервере Zero использует Postgres как источник правды и реплицирует данные в т. н. zero-cache для обслуживания клиентских запросов. Конфликты при синхронизации обрабатываются библиотекой автоматически.

API достаточно простой: схема с типами и связями, queries для реактивного чтения данных и mutators для записи. Всё это позволяет строить приложения с мгновенным откликом и оффлайн-доступом без больших изменений в привычном коде.

Если хотите попробовать local‑first без сложной архитектуры и ручного синка — Zero даёт такую возможность.

https://zero.rocicorp.dev/

#local #indexeddb #postgresql
🫡63👍3
#польза дня

Самое важное при разработке ИИ-агентов (на мой взгляд) — создать такую систему, где тебя не нагружают очередными «можно и допилить», а снимают рутину, освобождают время.

Поэтому приглашаю всех на Agents Week от Школы анализа данных Яндекса, который пройдет с 6 по 10 апреля. В течение пяти дней будут вечерние лекции с экспертами, где вы сможете задать любой вопрос, а ещё практика-практика-практика.

За 5 дней узнаете с чего начать проектирование агентов и настройку их поведения, какие есть практики построения single-agent и multi-agent-систем, как доводить агентов до продакшена.

Программа, спикеры, регистрация — всё по этой ссылке
🫡2