valya_reads_issue | Unsorted

Telegram-канал valya_reads_issue - Валя читает ишью

3625

Делюсь интересными ишьюсами и пул-реквестами в мире фронтенда и около github.com/7rulnik twitter.com/7rulnik

Subscribe to a channel

Валя читает ишью

Валя больше не читает ишью

Well, полгода (рекорд однако!) без постов. Пожалуй, хочется объяснить, что же произошло.

Если смотреть поверхностно, то всё просто: я утратил интерес не столько к формату, сколько к лайфстайлу «программирование — это хобби» и перестал в первую очередь маниакально мониторить ишью и пул-реквесты на гитхабе и в твиттере. Сгорел я где-то между очередным обсуждением о выпиливании corepack из ноды и фокусов ljharb с поддержкой той самой ноды, которая вышла 13 лет назад. Даже не столько сгорел, сколько разочаровался в текущем состоянии индустрии. Это правда самые важные вопросы, которые комьюнити должно решать и к чему должны быть прикованы наши взгляды?

Ну а перестав читать такой контент, оказалось и не о чем писать. Вполне закономерный итог. Но всё же, пожалуй, вопрос чуть более экзистенциальный. Звучит примерно так: «а кому и для чего нужен этот канал?».

Изначально мне просто нравилось структурировать свои мысли о происходящем, рассказывать вам о нюансах, расширять границы и кругозор. И это, пожалуй, получилось. И даже получилось достичь какого-то признания — 3700 подписчиков в пике (за последние полгода сотня куда-то разбежалась, бывает). Более того, 5 лет назад такой контент был по-своему уникальным — не было такого количества авторских каналов о фронтенде и JS в целом, как сейчас. Возможно, здесь я присваиваю себе какие-то несуществующие достижения, но чувствую, что было приятно находить и осозновать себя в начале этой волны. Было интересно конкурировать и развивать комьюнити. Вместе с конкуренцией было интересно и предоставлять трибуну для менее популярных авторов. Но в определенный момент стало сложно этой самой конкуренцией заниматься. Ради многих постов приходилось ложиться спать позже или откладывать важные дела. Хотелось написать первым, выиграть этот спорт и забрать свою порцию внимания и просмотров. И это тоже у меня прекрасно получалось. Более того, главное метрикой для меня всегда были просмотры, а не подписчики. И почти под каждым постом первого больше, чем второго. Так далеко не у всех.

Я не особо часто рефлексировал зачем мне нужен этот канал в принципе. Логично, что за 5 лет цели могли поменяться. Я предпринимал несколько четных (и, видимо, наивных) попыток хоть как-то монетизировать всю эту историю. Основной же платой всегда была медийность — рост количество подписчиков и моей узнаваемости. Но что с этой популярностью делать? Быть может, в какой-нибудь яндекс возьмут без собеседования (хаха)? Вывод простой — моя медийность не сильно поможет моей карьере, а если и поможет, то карьере только в пределах России. Но даже это сомнительная (лично для меня) награда, потому что кратно, ну хотя бы в 1.5 раза больше (а именно это как-то существенно может повлиять на мой образ жизни), денег российские компании просто не дадут. А если и дадут, то скорей всего с бонусами вида «удалёнка только внутри РФ». По крайней мере так я вижу рынок сейчас. А как делая то, что я делаю, выйти на англоязычную аудиторию, за эти 5 лет я так и не придумал.

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

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

Новый сезон, получается. Посмотрим что из этого выйдет.

Читать полностью…

Валя читает ишью

Если вы вдруг в Питере, то приходите во вторник (23 июня) в Юнион на дринкап SPB Frontend!

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

В общем, буду завтра там сам, приходите и вы! :*

Читать полностью…

Валя читает ишью

Как я положил продакшен базу на выходных
Вчера произошла эпическая история. После планового деплоя в субботу вечером (так было нужно), мне прилетело сообщение “кирилл, у нас почему-то не показываются заявки”. Наверное фильтры слетели, подумал я и пошел проверять. Фильтры не слетели. Я слегка напрягся и пошел в яндекс клауд посмотреть что там в базе. Как я и боялся, таблицы были пустыми. Причем не все, но многие. Самое интересное, что они были не просто пустыми, но у них сбросились счетчики.

Увидел я это не сразу после деплоя, поэтому было не до конца понятно, это деплой привел к удалению данных или что-то другое. Я быстро восстановил снепшот на новом кластере, благо это делается одним кликом и выполнил туда деплой заново. Какого было мое удивление, когда после деплоя база очистилась. Какого хрена подумал я, прикидывая, что могло быть причиной. В этот момент ко мне присоединился второй разработчик проекта, с которым мы весело провели 3 часа за дебагом.

Сам деплой был необычным, потому что мы выкатывали большое изменение для обработки заявок основного договора (до этого работало только раннее бронирование). Туда входило и много кода и около 40 миграций и обновления зависимостей и новая конфигурация. Но мы точно не добавляли код, который бы грохал половину базы (как нам тогда казалось, хаха).

Дальше мы полезли изучать код на предмет подозрительных вещей:

1. Логи
2. Изменения в конфигурации
3. Ишьюсы в Laravel (основной фреймворк)
4. Миграции

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

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

Открываем миграцию, а там тот самый пресловутый транкейт, который хоть и выглядел подозрительно, но не касался других таблиц. Смотрю в логи и вижу что транкейт выполняется так: TRUNCATE marketing_discounts CASCADE. И тут я как понял. Не знаю как так получилось, но я даже не был в курсе, что у трункейта есть такая опция. CASCADE приводит к тому, что дропаются все связанные таблицы (рекурсивно) независимо от того, есть ли там данные или нет. Сказать что я был в шоке, ничего не сказать. Тут же нашелся issues в ларавеле, где выяснилось несколько интересных деталей. Мы не единственные кто грохнул базу таким образом. Собственно сам issue появился с целью того, чтобы защитить всех остальных, на что разработчики сказали сорян, обратная совместимость. Самое смешное, что подобное поведение реализовано только для драйвера постгреса, у остальных такого нет.


When you truncate tables using the laravel illuminate db builder it truncates the table as expected. However, postgresql is different because it changes the DEFAULT behavior of truncate from RESTRICT to CASCADE. This means that you can loose all your data in other "related" tables (something that doesn't happen with the other sql drivers)


И ниже смешные комментарии в духе:


3 years passed, Laravel users still truncates their entire databases...

We were also a victim of this behavior this morning, fortunately we were on a test database. Very dangerous!


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

В итоге мы все поправили и восстановили данные, но открыли в себе новый страх. Давно в моей жизни не было таких приключений)

ишью: https://github.com/laravel/framework/issues/35157

Читать полностью…

Валя читает ишью

Кыргызы против Intl.NumberFormat

Когда лучшее враг хорошего.

Недавно к нам в команду web platform в aviasales пришли из техподдержки со странным багом у пользователя: в Arc браузере сломано отображение символа валюты кыргызских сомов, вместо него выводится непонятный символ. Проще всего конечно было ответить, что браузер не поддерживается, но стоп, разве арк не на хромиуме, чем он такой особенный?

Начал разбираться

Действительно, в обычном хроме сомы показываются как KGS, а в арке как символ, и символ явно ошибочный.
Для отображения валют мы используем стандартный Intl.NumberFormat и в арке он действительно выдаёт другой символ. Начало проясняться. Возможно, арк использует новую версию хромиума и поэтому показал проблемы раньше? И действительно, Chrome Canary получил точно такой же баг. Получается, совсем скоро, валюта сломается у всех, вообще у всех сайтов и пользователей страны, и отсчёт времени уже пошёл 🫠

Куда отправлять баг? У хромиума есть свой баг трекер, но работа с ним оставляет желать лучшего, выглядит он мягко говоря антично. Никогда не заполнял баги для браузера, но видимо этот час настал. В процессе подготовки репорта вспомнил, что вообще говоря, локализациями занимается не хромиум а отдельная библиотека ICU, то есть проблема ещё глубже, чем просто баг браузерного движка. А, казалось бы, невинная проблема

Описываю свои приключения коллегам, один замечает, что это первый раз, когда мы нашли баг не в самом лучшем браузере safari а в хроме, теперь счёт багов 4:1 в пользу первого. А действительно, а как себя ведёт в таких условиях сафари? Открываю. Встречаю тот же баг 🫡

Очевидно, проблема на уровне операционной системы.

Решил присмотреться к символу внимательнее, это просто мусорный вывод или он имеет какую-то семантику?

Символ который выдаётся на macos выглядит так: ⃀, если вы читаете с macos то почти наверняка ничего не увидите (в первом комментарии скриншот как это рендерилось в реальности). В базах данных по юникоду описание: Unicode Character 'SOM SIGN'. Бинго. Это не баг, это настоящий символ валюты, но в стандартных шрифтах macos его нет, на windows всё отображается нормально

В итоге получается ситуация: раньше вместо символа валюты выдавалась аббревиатура, библиотека ICU исправила эту проблему чем ухудшила вывод на девайсах apple

Это многое говорит о нашем обществе

Issue в багтрекере хрома или ICU открывать не стал. Очевидно они всё сделали правильно; парадоксальная ситуация в которой никто толком не виноват. Ну, точнее, можно конечно попинать apple чтобы добавляли символ, но это всё равно что орать на баобаб

Оценив диспозицию, решил что надёжнее всего будет просто сделать .replace для проблемного символа на старый вариант.
Мимоходом заметил, что в некоторых других условиях у нас на сайте кыргызская валюта отображается нормально. Оказалось, что вместо официального символа используется юникод-комбинация c + нижнее подчеркивание под символом: c̲. Как говорится c̲мекалочка ок. Но чтобы я не сильно радовался, оказалось, что в том самом стандартном шрифте apple этот символ тоже отображается криво, проще заменить обратно на KGS, как это было раньше и всех устраивало

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

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

Читать полностью…

Валя читает ишью

Стажировка в Авиасейлс

У нас открывается набор на летнюю стажировку!
2 месяца по 500 баксов, 4-6 часов в день, ремоут, все дела

Фронтенд, go, iOS, юристы, редакторы, дизайнеры, маркетинг — в общем есть всё!

Аплайтесь через сайт, можете указать что вакансию в канале увидели

https://aviasales.ru/about/vacancies

Читать полностью…

Валя читает ишью

Не смотря на то, что профилирование JavaScript является мощным инструментом, мне всегда не хватало возможностей инструментов. Так что последние годы я почти перестал пользоваться этим методом. Для меня это просто не работало: для небольших скриптов – слишком мало деталей, для долго работающих (например, сборка webpack или выполнение unit-тестов) – сплошная каша. Оказывалось, что инструментирование с помощью console.log() работает куда эффективнее, чем ковыряние в CPU профилях. В тоже время, мне казалось это неправильным.

2,5 года назад, очередной раз разбираясь в тормозящей webpack сборке, и делая аналитику что и как работает, представил как это могло бы выглядеть в инструментах. Пришла идея кластеризации функций по модулям, пакетам, категориям. Это казалось очевидным решением, странно, что никто еще не сделал. "Если никто не сделал, наверное это не будет работать" – думал я тогда. Но "не попробуешь не узнаешь", и решил попробовать реализовать – вдруг заработает.

Сначала я начал разбираться с тем как устроен формат ".cpuprofile". Было ничего непонятно, и казалось очень сложным. Но на деле вышло, что ничего сложного в этом нет, сложно только разобраться. Сложность в том, что материалов про то как устроен формат и про логику его работы, и вообще профилирование с точки зрения аналитики, обнаружить не удалось. Обычно ограничиваются базовыми туториалами по профилированию. Информацию приходилось собирать по крупицам: по ишуям, по комментариям, по коду v8 и т.д. И еще много экспериментировать.

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

Время от времени я понемногу допиливал CPUpro, продолжал экспериментировать. А некоторое время назад пришло озарение, на фоне размышлении о том, как сделать сравнение профилей "до" и "после" без сопоставления двух флеймчартов глазками. Сравнение профилей пока не реализовано, но многое для этого уже сделано (высокая производительность, низкое потребление памяти), и вообще стало получаться что-то приличное. Теперь я ковыряюсь в CPU профилях каждый день, и все больше коллег делают тоже самое.

В общем, инструмент приобрел состояние, когда его не стыдно показать 🙂 Еще много что предстоит сделать, но он полезен уже сейчас, нам уже не раз помог в работе. Особенно если нужно проанализировать профайл на десятки или сотни мегабайт.

Release notes (там больше деталей, бенчмарки и скриншоты)
Твит анонса (спасибо за лайк, ретвит)
CPUpro (GitHub)

Читать полностью…

Валя читает ишью

Vitest: invalid JSON syntax found at position -1.

Алло, это канал о витесте? Ну а если серьёзно, то пожалуй столкнулся с одним из самых интересных багов в своей жизни.

Я уже рассказывал, что витест для нас компромиссный опыт и породил экстравагантные практикие в духе «гоняем 100 пайплайнов и проверяем, что не флакает». В общем, задумал я обновить его немного, открыл пул-реквест, погонял те самые 100 пайплайнов — всё зеленое! Мёрджим!

Проходит 2 недели и 60% пайплайнов начинают падать… Разработчики ругаются, тимлид предлагает откатывать, я в замешательстве — работало же! Снова начинаю гонять пайплайны, находим 3 проблемных теста, которые никто не трогал уже полгода. Выключаем — всё снова стабильно и зелено. Начинаю разбираться…

Ошибка выглядит так — Error: Failed to parse JSON file, invalid JSON syntax found at position -1. Спасибо, очень информативно! Собираю такой же докер образ как на CI, тыкаю проблемные тест — ничего. Т.к. проблема воспроизводится только на CI, то решаю запатчить vite через yarn patch, добавив название файла в лог. Сработало — проблемный файл мы генерируем на CI и путь до него известен.

Проверяю содержимое файла до тестов — всё на месте. Проверяю после тестов — и снова всё на месте. Но в тестах почему-то всё так же ломается. И тут я замечаю, что у падающих шардов есть кое-что общее — падает именно первый тест. Смотрю как это работает внутри vite — обычный fs.readFile и JSON.parse. В голову закрадывается страшная идея — а что если это какя-то проблема с файловой системой и одновременным чтением одного файла из нескольких процессов. Ищу ишью в ноде, но ничего прям конкретного не вижу. Уже начинаю писать скрипт для стресс-теста одновременного чтения, чтобы проверить гипотезу и тут в голову приходит идея — а что если кто-то этот файл всё таки перезаписывает?

Проверяю файл через fs.stat сразу после записи и после тестов — даты создания и редактирования отличаются! Смотрю немного в пайплайн и понимаю, что внутри одной из команд мы запускаем генерацию этого файла. Мда! А ларчик просто открывался, как говорится. Убираю лишнюю генерацию и всё сразу же зеленеет.

Для меня было откровением, что при записи файл может принимать какое-то промежуточное состояние. Т.е. не before → after, а before → empty → after.

Рефлексируя о дебаге и что могло упростить поиск, пришёл к такому алгоритму:
1. Если ошибка указывает на неочевидное место, то её сразу же надо патчить, чтобы сузить радиус дебага (в очередной раз могу поругать бандлинг зависимостей в vite, кажется в новой версии зависимости ошибка уже содержит путь до файла).
2. В ошибках нужно искать общие признаки (в моём случае что падает только первый тест в каждом из шардов).
3. Проверять самые простые гипотезы в userland коде, а не искать какие-то баги в больших популярных библиотеках (vite и node в нашем случае)

Остаётся вопрос: а почему ошибка не сразу всплыла, а через 2 недели?
Ответ прост: у нас 4 шарда и не все тесты импортируют проблемный файл. С добавлением/удалением тестов порядок в шардах немного меняется и тесты, которые читают файл, становятся первыми в очереди и попадают в те самые первые 5 секунд, когда мы перезаписываем файл.

Такой вот детектив. А как вы провели вечер пятницы?

Читать полностью…

Валя читает ишью

Никита очень чётко сформулировал все мои претензии к гиту

А лучший гуй, который я пробовал — Fork

Читать полностью…

Валя читает ишью

Node.js 22 is now available!

Вышла 22 нода, которая станет LTS в октябре. Важных изменений много!

---------

1. Support require()ing synchronous ESM graphs

Что ж, взяли опыт bun, который, на сколько я понимаю, нарушает спеку. Кажется, что все в восторге, но я думаю радоваться пока рано. Подождём пока фича станет стабильной (сейчас нужно запускать ноду с флагом --experimental-require-module). А там глядишь и проблема миграции на ESM уйдет. Сейчас ситуация катастрофическая.

Кстати, фичу затащила Joyee Cheung, о которой мы с вами ещё поговорим!

---------

2. Watch Mode (node --watch)

Для простых кейсов, nodemon, получается, больше не нужен

---------

3. glob and globSync

Супер! Я каждый раз мучался в выборе библиотеки для глоба. Забавно, что изначально эту функциональность затащили ради встроенного тест-раннера , а теперь она доступна и в fs модуле.

---------

4. Running package.json scripts

Теперь можно запускать скрипты из package.json в обход пакетного менеджера — node --run <script-in-package-json>. Кажется, самая спорная фича. 212 комментариев в пул-реквесте на 352 строки! Нода испытывает большой кризис в области пакетных менеджеров — вновь разгорелась дискуссия на счёт corepack, а этот пр отчётливо показывает, что в команде нет чёткого мнения на счёт того, что должно быть в ноде, а что нет. Но и об этом тоже как-нибудь в отдельном посте.

---------

Релиз-пост:
https://nodejs.org/en/blog/announcements/v22-release-announce

Читать полностью…

Валя читает ишью

fetch() performance parity

Из скриншота всё должно быть понятно.

Вот такая вот дорога от экспериментальной фичи до самого быстрого http клиента в ноде. Ну и вот само ишью.

У Маттео есть даже стрим об этом — Improving Node.js fetch() by 10% - From flamegraph to implementation!

P.S. Мне лично тяжко смотреть такие долгие стримы, но из них обычно можно подчерпнуть какие-то новые привычки и оптимизации воркфлоу.

Читать полностью…

Валя читает ишью

Как дела, потомки? Узнаёте?

P.S. Увидел в твиттере и аж прослезился, простите.

Читать полностью…

Валя читает ишью

Temporal

Ну и история! 13 мая 2017 появляется первый коммит Temporal Proposal - нового апи для управления датами, вдохновленный moment и luxon.

Ключевые отличия от Date: продуманная работа с часовыми поясами, иммутабельное апи, работа с интервалами (Duration). Схема ключевых сущностей.

В 20 году идет активная работа над полифилом. Игалия вкладывает в него много сил, написано куча тестов, многое сделано типобезопасно и даже в рантайме расставлено куча ассертов - все по лучшим практикам.

Я сам использовал этот полифил в течении года, пока пилил проект на ноде, остался очень доволен! С багами не сталкивался, только сделал ПР с улучшением типов (приятно делать даже небольшой вклад в такие крупные проекты)

Уже в 21 году я считал сам пропосал и полифил к нему самым продуманным и проработанным тулом для работы с датами. И сейчас так считаю, но смущает js-temporal/polyfill">200 kB (50 kB gzip), что бы тянуть на фронт. Хотя стоит учитывать, что когда оно появится в браузере вы сможете просто вырезать полифил не меняя сам код, чего не скажешь про остальные либы для дат из NPM.

Но почему это все еще не стандарт?

Ключевая фича нового апи - работа с часовыми поясами, не могла быть реализована из-за недоработки самого стандарта часовых поясов. Ужвал - сотрудник Игалии и основной разработчик Temporal, а так же просто очень крутой чел, внес предложение в стандарт дат всея интернета по расширению формата хранения и передачи времени с возможностью расширять его дополнительной информацией. Например?

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

23 октября 2023 предложение апрувнули!

Работа над темпорал продолжается, серьезных блокеров, кажется, больше нет. Текущий статус трекатеся тут: https://github.com/tc39/proposal-temporal/issues/2628

Мне сложно сказать, когда предложение станет стандартом и мы увидем его в браузерах, но вот в V8 реализация Temporal занимает уже больше 2.6% бинарника и вы уже можете использовать его в Deno.

Напоследок, очень порекомендую великолепный доклад Пару календарей назад я был совсем другим Алексея Охрименко, для понимания всей проблематики. А вот доклад конкретно про Temporal: How to Outsmart Time Building Futuristic JavaScript Apps Using Temporal

Читать полностью…

Валя читает ишью

git rerere

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

Например, если вы работаете в какой-то «гигаветке» (долго делаете большую недробимую фичу), постоянно подливая из других веток изменения и разрешая одни и те же мерж-конфликты, то с включённой в конфиге опцией rerere (reuse recorded resolution) вы можете разрешить конфликт всего один раз, а затем git, если увидит, что в файле с таким-то именем уже была ситуация, что у нас такая-то строчка, а снаружи пришла такая-то строчка, то разработчик решал конфликт вот так. И, собственно, не будет спрашивать ещё раз, а решит, как вы решили в первый раз.

git config --global rerere.enabled true

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

https://git-scm.com/book/en/v2/Git-Tools-Rerere

Читать полностью…

Валя читает ишью

Vitest: 9 месяцев спустя

Напомню, мы в Авиасейлс переехали с Jest на Vitest и были (ну, я уж точно) не очень довольны результатом. Прошло 9 месяцев, вышла Vitest 1.0 (а актуальная версия уже и 1.2.1) и мы научились с ним как-то жить.

Во-первых, я оказался прав на счёт шардирования. В синтетических тестах (только vitest в пайплайне, это существенно ускоряет тесты) используя 12 тредов, тесты проходили за ~3 минуты. 4 шарда по 3 треда в каждом (с меньшим количеством тредов тесты начинали зависать) мы укладываемся в ~2 минуты. Сайд-эффект шардов — теперь у нас 4 разных отчёта, а не один единый. Неудобно. Команда Vitest открыта к blob репортерам, как в playwright. Их можно склеить после и получить единый отчёт. Осталось написать ишью и реализовать, хех.
Касательно перформанса тредов вот моё ишью — The performance of threads doesn't scale much after 8 threads.

Во-вторых, нам удалось стабилизировать тесты и избавиться от залипаний и случайных падений. С тех пор мы обновились до node v18.19.0 и vitest v1.1.3, удалили любые исключения из poolMatchGlobs и используем threads пул (стандартный и не самый быстрый).

В-третьих, нестабильность витеста породила особенный подход обновлению его самого и ноды. Мы запускаем 100+ пайплайнов по крону, смотрим fail rate и принимаем решение об обновлении или включении каких-то опций. Как я сказал выше, на v1.1.3 нам удалось добиться 100% стабильности, но вот уже с v1.2.1 (latest) один из тестов начинает отваливаться в трети случаев.

В-четвёртых, я был не особо прав, когда сравнивал типы пулов. С тех пор в витесте появился пул vmThreads, который полностью копирует подход из джеста. Он действительно быстрее (в нашем случае срезает ~30 секунд), но менее стабильный и течёт по памяти (как и джест).

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

Читать полностью…

Валя читает ишью

VSCode 1.85: Floating windows

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

Ну что ж, можно поздравить этих самых владельцев нескольких мониторов! Мне же эта штука показалась интересной по двум причинам.

1. Судя по всему реализовать это было не очень просто либо это было совсем неприоритетной задачей.

2. Я пользуюсь внешним терминалом (iTerm), который показывается на любом воркспейсе на пол экрана по хоткею. Но работая с вскодом удобней использовать встроенный, т.к. в нём работает парсинг и всякие ошибки удобно смотреть в панельке «Problems» и перемещаться между ними. Уже какое-то время терминал можно перенести в поле редактора (ну там где файлики открытые) через команду «Move terminal into Editor Area», а теперь его можно будет и вынести в отдельное окно. Far from perfect, но мне определённо нравится куда всё это движется. Может быть когда-нибудь и перепридумаю свой воркфлоу. Хотя я, конечно, хотел бы иметь возможность как-то связывать внешний терминал с вскодом…

На текущий момент этой фиче посвящено 37 ишью, что как бы намекает, что она работает неидеально и будет дорабатываться. Отдельно отмечу возможность вытаскивать панели и вьюшки, а не только редактор: Aux window: allow detaching views and panels.

Читать полностью…

Валя читает ишью

Уже завтра состоится наш Дринкап! 🍺

— Когда: завтра, 23.07, начало в 20:00 (но можно подходить в 19:00)
— Где: Бар Union, Литейный пр., 55
— Вход: бесплатный

А пока делимся с вами расписанием:

20:00 — Приветствие
20:10 — Алексей Хлебаев: Побеждаем выгорание за 10 минут
20:25 — перерыв
20:35 — Антон Ленев: We need to go deeper - куда нас привела дорога WYSIWYG
20:50 — перерыв
21:20 — Андрей Соколов: Как мы делали стартап
21:35 — перерыв
21:45 — Тимур Гафиулин: Мечта любого айтишника или как я год не работал

Ждем вас! 🍻

Читать полностью…

Валя читает ишью

ljharb

Ситуация с ljharb продолжает быть веселее и веселее. Это тот чувак, который решил в доку свелта добавить поддержку ноды 0.4.

Вчера я пытался в очередной раз апнуть наш проект до eslint 9 и увидел, что eslint-plugin-import принадлежит как раз этому челобеку. Следовательно, по классике, этот плагин поддерживает eslint 2, node 4 и прочую некрофилию. А так же чувак попросту не добавляет поддержку flat config и eslint 9. И вот история в том, что игнор идёт уже больше года. В итоге появляется eslint-plugin-import-x: https://www.npmjs.com/package/eslint-plugin-import-x, который поддерживает только eslint 8/9, не имеет кучи говнозависимостей и пока поддерживается новым ментейнером.

Другая история происходит прямо сейчас про библиотеку traverse. Как легко догадаться, туда тоже пришёл ljharb. В итоге ша маемо, то маемо. Но благо, благодаря этому появилась библиотека neotraverse: https://www.npmjs.com/package/neotraverse, которая является форком оригинальной, но без всей этой дичи от нашего поциента.

В итоге, если хотите получить популярный проект, то алгоритм чуток прост:
1. Смотришь, в какой очередной утилитарный проект пришел ljharb и навернул секурности
2. Делаешь форк от прошлой версии без зависимостей, обзываешь neo/nano/x-оригинальное имя и публикуешь
3. Профит, благодарные юзеры благодарны на ровном месте, репутация локального спасителя экосистемы

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

Читать полностью…

Валя читает ишью

axobject-query: maximize back compat

3 дня назад Jordan Harband потряс всё JS комьюнити своим пул-реквестом в проект axobject-query с названием «maximize back compat». 210 дизлайков, ни одного лайка, бесконечное количество критики…

Давайте сперва про Джордана — это очень известный человек в комьюнити, работал в твиттере, коинбейзе, эирбнб. Участник TC39, контрибьютил в еслинт, бабель, ноду, опубликовал 513 пакетов в npm.

Теперь про сам axobject-query — я, честно говоря, не знаком с AXObject (и если ещё более честно, то и знакомиться особо не хочу), какая-то низкоуровневая штука для работы с доступностью в общем. Интересно кто этим пакетом пользуется — eslint-plugin-jsx-a11y (пакет Джордана), svelte, astro. Короче, короче, большие и уважаемые проекты.

А теперь давайте про пул-реквест — под названием «maximize back compat» скрывается поддержка ноды v0.4. Знаете когда он вышла? 12 февраля 2011 (!!!) года! Я даже не успел её застать, кажется моя первая версия была 0.8 или 0.9 Поддержка достигается за счёт смены jest на tape, который написал Джордан. А так же замены dequal на deep-equal-json т.к. первый требует ноду старше v6. А кто является автором deep-equal-json сами догадаетесь. deep-equal-json как минимум ругают за то, что он тянет 17 зависимостей, в то время как dequal ни одной. Это критично для svelte, т.к. у них есть REPL и юзеры будут загружать эти пакеты в том числе и в браузере.

В ответ на критику Джордан занимает очень оборонителньую позицию. Например, его спрашивают «а как ты стал мэйнтейнером этого пакета? Как мы видим, это твой пул-реквест в этот проект. Понятно, что ты уважаемый человек с большой историей контрибьюшенов, но ответь пожалуйста на этот простой вопрос» или «замотивирован ли ты внедрять свои пакеты т.к. можешь получать отчисления от tidelift». В ответ Джордан либо не отвечает либо делает это очень уклончиво.

Интересно, что в описании пул-реквеста указано «It also expands the test matrix so that all supported engines are tested, now and moving forward.», но на деле в CI указано >= 0.8, а в engines 0.4… Кажется уж,если решил быть таким педантичным, то надо идти до конца…

В общем, рекомендую почитать комментарии в пул-реквесте. Там правда очень уважаемые люди. А на самого Джордана свалилось много как конструктивной критики, так и булинга. Хоть я и осуждаю такое, но природа этого понятна. Уж очень экстравагантное решение получилось.

P.S. once JS drama — always JS drama…

Читать полностью…

Валя читает ишью

Мой тиммейт Дима (а заодно и автор effector) на днях тоже с веселой детективной историей столкнулся

Читать полностью…

Валя читает ишью

React Compiler доступен для пользователей

https://react.dev/learn/react-compiler

Если вперые слышите об этом, то взгляните на пост про React Forget (предыдущее название)

Исходный код вот тут

Читать полностью…

Валя читает ишью

cpupro — лучший cpu профайлер

Не так давно я искал узкие места в витесте и вебпаке и внезапно наткнулся на cpupro. Когда я увидел, кто автор, то понял что инструмент плохим быть не может в принципе: Рома Дворнов — знак качества!

Традиционно, это самый быстрый аналайзер из существующих, способный переваривать огромные (2гб) профайлы.
Ну и по функциональности он впереди всех существуюших профайлеров — куча разных вьюшек, сортировки по пакетам/функциям и так далее. В общем, очень рекомендую!

https://github.com/lahmatiy/cpupro/releases/tag/v0.5.0

Читать полностью…

Валя читает ишью

Ну что, кот вылез из мешка (сорян, вы же хотели, чтобы я русский не забывал?), вышел подкаст Бирмана, в котором я рассказываю про Гит. Вообще идите послушайте, а я тут коротенько наброшу.

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

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

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

Вторая беда — они всегда показывают прошлое. То есть я ветку уже удалил, но если на экране есть вывод предыдущей git branch -a, то он не обновится. Вот ты и сидишь и спрашиваешь постоянно: где я? кто я? какой сейчас статус? Закоммитить не в ту ветку — одна из самых частых ошибок, потому что ветка нигде не написана.

(мне сейчас скажут, что у них условный oh-my-zsh запрашивает и печатает ветку после каждого нажатия enter, на что я скажу: вы что, ебанутые? ^W^W^W вот мы и начали делать gui колхозными средствами)

Ну и в целом многие вещи исходно требуют графического представления (diff-ы, лог), которое консольному интерфейсу приходится как-то колхозить. Для чего, для кого? Зачем вы страдаете, мистер Андерсон?

Вторая часть моих претензий связана с ебанутостью конкретно git-ового cli.

- Например, команды, которые и не существительные, и не глаголы (`git checkout`/`git branch`).

- Команды, которые полностью меняют свой смысл в зависимости от ключа (`git branch`, git branch -l, git branch -d, `git checkout --merge`).

- Команды, которые полностью меняют свой смысл от аргумента (`git checkout`).

- Неконсистентный словарь (staging, index, cache — это все одно и то же).

- Команды, которые очевидно создавались заплаткой поверх других команд. Попробуйте понять логически, что с чем сравнивает команда git diff --cached

- Git status, который пишет «You are up to date», даже не сходив в интернет и ничего не проверив! Распределенная система контроля версий боится ходить в сеть!

- Просто идиосинкразия удаления файла через git add

- То, что стеш автоматически не стешится (правда, это во многих gui тоже так)

- Отсутствует анду. А это, между прочим, столп вообще любого человеко-компьютерного взаимодействия.

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

В общем, you do you, конечно, но меня раздражает, что эта вот пытка считается чем-то вроде badge of honor, чем-то, чем люди прям гордятся. А на деле самый обычный стокгольмский синдром.

Конечно, это не отменяет того, что какой-то конкретный GUI для гита тоже может быть плохим! Условный VS Code, в котором одна кнопка sync, которая делает и пуш и пулл и черт знает что еще, да, действительно, с такой каши не сваришь.

Но бывают и хорошие ведь! Условный Sublime Merge снимает почти все головняки консоли и при этом не идет против правды и показывает вещи как есть. И это просто хорошо сделанная обертка, даже не переосмысление самой работы с DVCS.

Короче, дискурс «нАдО сИдЕтЬ в КоНсОлЕ» вредит и развитию инструментов, и доступности профессии для новичков. Да и вам самим было бы легче, просто кто-то фильмов про хакеров насмотрелся с зелеными буквами. На терминале свет клином не сошелся, алло!

Читать полностью…

Валя читает ишью

TypeScript 5.5 Beta

Вышла новая бета ТС и самое интересное, если не долгожданное, это Isolated Declarations.

Работа над это штукой началась больше двух лет назад при участии людей из Майкрософта, Блумберга и Гугла.
Тайпскрипт использует d.ts файлы для проверки типов, когда мы используем библиотеки. А чтобы сгенерировать d.ts нужно осуществить полный тайпчек и уже после записать d.ts на диск.

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

Основная идея — не совершать полный тайпчек и генерировать d.ts на основе типов, указанных для возвращаемого значения.

Т.е. вместо


export function foo() {
return x;
}


нужно будет явно указывать


export function foo(): string {
return x;
}


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

Чтобы тайпскрипт работал в таком режиме, нужно включить опцию isolatedDeclarations. На текущий момент это влияет только на вычисление типов. По сути этот режим является некой валидацией. В будущем скорей всего у tsc появится отдельный режим (или cli) именно для компиляции d.ts. Уже сейчас есть API transpileDeclaration, но использовать его напрямую нет смысла, т.к. пока что всё равно будет происходить полная проверка типов.

Готовиться к этому режиму и уже сейчас включать isolatedDeclarations тоже не стоит, т.к. придётся руками указывать типы для каждой экспортируемой функции. В будущем для большинства (или всех) таких ошибок будут атоматические фиксы

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

Ну а основной релиз этой версии ТС состоится 18 июня

Релиз-пост:
https://devblogs.microsoft.com/typescript/announcing-typescript-5-5-beta/

Читать полностью…

Валя читает ишью

И в догонку статью про внутренне устройство undici — HTTP Fundamentals: Understanding Undici and its Working Mechanism

Читать полностью…

Валя читает ишью

Начиная с ноды v20 и в браузерах есть встроенный генератор uuid v4
crypto.randomUUID(), доступен глобально.

Это самый частый юзкейс для пакета https://github.com/uuidjs/uuid и если другие версии или валидация не нужна, смело дропайте.

Читать полностью…

Валя читает ишью

GitLab copyright strike

4 года назад я работал в Альфа-Банке и был у нас там гитлаб. Хорошая штука: и селфхост, и дифф быстро работает, и CI есть, и регистр пакетов. В общем, не инструмент, а мечта!

Но одна штука меня очень сильно раздражала — перенос строк в логах CI. Особенно сильно бесило это при использовании покрытия кода (coverage) в Jest. Он там рисует достаточно широкую и массивную табличку, и смотреть на всё это в маленьком окошке очень неудобо.

Я немного подумал и за один вечер написал простенькое расширение для браузера: берём лог, делаем сплит по строкам, парсим ANSI, рендерим как виртуальный список. Дешёво и сердито. Контрибьютить в гитлаб мне почему-то тогда не захотелось. Видимо, подумал, что это будет не очень просто.

Спустя год я уволился из Альфы, перестал пользоваться гитлабом и благополучно забыл про экстеншн. Но вот неделю назад мне пришлось вспомнить о нём: на почту пришло сообщение «Unauthorized Use of GitLab Intellectual Property». Меня похвалили за экстеншн (американцы ж без этого не могут, вы знаете), но сказали что я мягко говоря не прав т.к. использую в название «GitLab» и ещё и над логотипом надругался (покрасил в другие цвета). Что ж, справедливо — трейдмарк есть трейдмарк™.

Склонировал репо, попытался установить зависимости и сбилдить — всё сразу же сломалось. Заметка на будущее — сразу коммитить .nvmrc, чтоб потом не вспоминать на какой это версии ноды работало. Переименовал, поменял (я тот ещё дизайнер) лого — моя совесть чиста. Надеюсь ребята из гитлаба так же считают…

А расширение теперь называется gtlb-job-log-viewer, и им даже 500 таких же страдальцев, как я, пользуется.

P.S. Ради интереса посмотрел как гитлаб нынче выглядит. Мож и не нужен мой экстеншн то? Добавили возможность открыть логи во весь экран. Ну, неплохо, но хотелось бы большего…

Читать полностью…

Валя читает ишью

Мне, кстати, кажется это многое говорит о том какой гит "юзер-френдли"...

Читать полностью…

Валя читает ишью

Vitest: шардирование

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

Вот так мы запускали витест до:





VITEST_MIN_THREADS=12 VITEST_MAX_THREADS=12 yarn vitest --reporter=html --reporter=html --outputFile.html=./vitest-reports/01/index.html


А вот так запускаем теперь (команды запускаются параллельно):




VITEST_MIN_THREADS=3 VITEST_MAX_THREADS=3 yarn vitest run --shard=1/4 --reporter=html --outputFile.html=./vitest-reports/01/index.html

VITEST_MIN_THREADS=3 VITEST_MAX_THREADS=3 yarn vitest run --shard=2/4 --reporter=html --outputFile.html=./vitest-reports/02/index.html

VITEST_MIN_THREADS=3 VITEST_MAX_THREADS=3 yarn vitest run --shard=3/4 --reporter=html --outputFile.html=./vitest-reports/03/index.html

VITEST_MIN_THREADS=3 VITEST_MAX_THREADS=3 yarn vitest run --shard=4/4 --reporter=html --outputFile.html=./vitest-reports/04/index.html


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

https://vitest.dev/guide/cli.html#shard

Читать полностью…

Валя читает ишью

VSCode 1.85: Multi-file diff editor

Есть одна вещь, которую я ненавижу в ГитХабе — страничка с дифом у пул-реквестов. А ненавижу я её, потому что пользоваться ей невозможно. Я не понимаю, как ключевая часть продукта может быть сделана так плохо. Я понимаю, что это сложная задача, даже Илья Климов пришёл в твиттер со словами «Как человек пытающийся сделать это в гитлабе - это очень сложно :)». Но, однако, к ГитЛабу у меня никаких претензий нет. Ну т.е. можно ли сделать лучше? Ну, да. Но у них хотя бы список файлов не грузится минуту. Обычно к таким постам приходят люди со словами «а ты не пробовал делать пул-реквесты поменьше???». Это, кстати, для меня прям показатель неопытности: не все пул-реквесты реально разбить на части, особенно какие-то миграции на другие подходы и библиотеки. За 3 года в Авиасейлс у меня было множество ПРов на 5000 строк, но дифф сводится к 5 строкам в 1000 файлах. Самое смешное, что после какого-то количества файлов ГитХаб просто не показывает дифф, и приходится тыкать кнопочку «Show diff» на каждом файле. Треш!

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

1 вариант был открывать дифф в браузере, нужно просто добавить .diff к пру:
github.com/nodejs/node/pull/51124.diff
Но смотреть такое невозможно — просто простыня текста

В качестве 2-го варианта я попробовал официальный CLI ГитХаба:
gh pr diff — отдаёт тот же самый дифф, что и первый способ, но уже с подстветкой. Иногда я запихивал этот дифф в diff2html. Так же я пытался прикрутить delta, чтобы не покидать консоли (это всё таки работает быстрее, чем браузер), но мне не хватило усидчивости его приготовить.
В общем, последний год я просто вызывал gh pr diff и листал вывод. Не могу сказать, что меня устраивал это способ, но работало точно лучше ГитХаба и позволяло оценить нет ли лишних изменений в ПРах.

И вот в VS Code 1.85 появилась экспериментальная фича multi-file diff editor. Это, в общем-то, тот же дифф, что всегда был в вскоде, только в виде простыни из файлов. И знаете, оно работает! Не идеально, но работает!

Я открывал пул-реквест в ноду выше: github.dev/nodejs/node/pull/51124.
Дифф внушительный 1854 файла —+48,035 −17,659 строк. Да, нужно подождать пока оно прогрузится, но я лучше подожду, чем буду постоянно пользоваться лагающим интерфейсом. Да, это не 60fps и даже не 30, но я скролю в любую позицию и сразу же вижу файл и его дифф. И да, могу прям здесь написать комментарий к любой строке. В общем, я в восторге!

Т.к. фича экспериментальная, то её надо принудительно включить:
"multiDiffEditor.experimental.enabled": true

Такой дифф доступен для локальных и staged изменений, incoming/outgoing изменений при мёрдже и для просмотра пул-реквестов.

Читать полностью…

Валя читает ишью

Object.groupBy() и Map.groupBy() достигли stage 4

Новость, как и методы, прекрасная! Боюсь сосчитать сколько раз мне приходилось писать что-то подобное.

Пример использования:


const array = [1, 2, 3, 4, 5];

// `Object.groupBy` groups items by arbitrary key.
// In this case, we're grouping by even/odd keys
Object.groupBy(array, (num, index) => {
return num % 2 === 0 ? 'even': 'odd';
});
// => { odd: [1, 3, 5], even: [2, 4] }

// `Map.groupBy` returns items in a Map, and is useful for grouping
// using an object key.
const odd = { odd: true };
const even = { even: true };
Map.groupBy(array, (num, index) => {
return num % 2 === 0 ? even: odd;
});
// => Map { {odd: true}: [1, 3, 5], {even: true}: [2, 4] }

Читать полностью…
Subscribe to a channel