Минутка просвещения

Читать в телеге. Когда-то там были посты не только от меня.

Минификация Javascript

Я попробовал два инструмента для сабжа — esbuild и rollup.

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

Итоговый JS-модуль для поиска, сгенерированный Koka, увы, был не очень высокого качества из-за того, как я понял, что у таргета нет четкого разделения между фронтом и бэком с нодой. Я пробовал пометить нодовские модули (os, fs) как внешние, пометить импорты Koka как внешние, выбрать platform=node и даже руками удалить “неправильные” импорты, но ничего не помогло: undefined в итоговом скрипте.

Rollup сработал с первого раза, и размер бандла получился меньше. Однако он менее строг, и что было ошибкой у esbuild, у него было просто предупреждением. И автономного варианта нет — только npm install (впрочем, распространенная проблема для JS экосистемы).

СсылкаКомментировать

Релизы на GitHub

Окей, сделать релиз на GitHub оказалось проще, чем ожидалось.

Главное — выбрать правильно action :) Официальное — в архиве, одно из 4 рекомендованных — тоже, еще 2 имеют странные настройки по умолчанию, и методом исключение было выбрано softprops/action-gh-release.

И настраивать особо не понадобилось — самому действию нужен только список файлов для загрузки, а для workflow достаточно настроить права на запись и триггер на обновление тэгов.

СсылкаКомментировать

Кэширование GitHub Actions

Когда добавил на сайт поиск, скорость сборки, которая была подвергнута сумасшедшей оптимизации год назад, и занимала около 30 секунд (из них 6 секунд сама сборка сайта), просела до катастрофических 2,5 минут — из-за того, что теперь надо качать еще один репозиторий для поиска, собирать его и индексировать данные.

Решение — довольно очевидное: закэшировать все что можно! Для многих популярных языков/билд систем и т.п. уже скорее всего есть какие-то действия, где все подумали за вас. Например, у меня в сборке уже был ruby/setup-ruby, который использовал кэш.

Однако, если ваш стек технологий не очень зрелый и/или в нем есть экзотические шаги, то можно сделать все самому с помощью actions/cache. По сути, вас должны волновать две вещи: какую папку кэшируем и что будет ключом в кэше.

Однако есть и нюанс. Не получится закэшировать системные папки из-за проблемы с правами. Поэтому всякие установленные инструменты надо будет класть в “рабочую папку”. При этом для менеджера пакетов APT есть действие, которое помогает обойти это ограничение.

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

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

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

СсылкаКомментировать

Метрики сложности кода не отражают реальность

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

Некоторые тезисы:

  • Код сам по себе слабо влияет на “читаемость” — другие факторы, возможно, более важны.
  • Метрики кода коррелируют с его сложностью, но довольно слабо.
  • Одно из исследований показало, что ни одна из 121 метрик сложности кода не отражает сама по себе “простоты”/“понимаемости” кода.
  • Процессные метрики лучше (и правда, если ваши процессы говеные, то качество кода не спасет разработку).
  • Паттерны имеют большое значение: принцип наименьшего удивления, безобразно, но единообразно и т.п.
  • Сложность/понятность кода зависит от контекста™ (причем в самом широком смысле).
  • Неправильные имена переменных и типов хуже отсутствия имен. При этом “неправильные” имена переменных для одного разраба могут быть “правильными” для другого.
  • Существующие метрики основаны на интуиции, а не на науке/нормальных эмпирических исследованиях.
СсылкаКомментировать

Отличие SQL Merge от Upsert

Облако напомнило, что пора бы обновить Postgres, потому что используемая версия (14) невероятно устарела. Я осознал, что мои знания о функциональности в новых версиях остановились где-то в районе 10 версии (работает и ладно же), а сейчас уже скоро будет 18, решил почитать, что нового там появилось.

Среди кучи улучшений производительность и новых фич, которые я вряд ли использую, с удивлением обнаружил, что в 15 версии добавили MERGE. Оказывается, эта команда так вообще часть стандарта SQL, причем достаточно старого, 2003. При этом проблема upsert в Postgres издревле решалась через INSERT ... ON CONFLICT ....

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

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

А еще SQL стандарт развивается. Теперь там еще и JSON есть, в 2023.

СсылкаКомментировать

Исследование про продуктивность разработчиков с ИИ

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

We do not provide evidence that … AI systems do not currently speed up many or most software developers

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

На месте исследователей я бы проверил гипотезу про область поиска. Мне иногда кажется, что довольно времени тратится в чате с гпт на изучение альтернативных путей решения (кроме “очевидных” уточнений задачи и просьб исправить ошибки и т.п.). Т.е. чат-бот может иногда подкинуть (довольно часто неправильное или вообще нагаллюционированное) альтернативное решение(я) проблемы, иногда они могут показаться перспективными (в редких случаях даже оказываются ими), но на их фильтрацию тратится уже человеческое время.

СсылкаКомментировать

Diátaxis — системный подход к документации

Сабж. Хороший материал, основная идея которого — определить цель документации (помочь понять или помочь получить результат) и ее фокус (теория или практика), а потом писать и структурировать материал соответствующим образом. Без понимания цели, аудитории и т.п. получается каша, которую тяжело использовать.

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

СсылкаКомментировать

Резиновый квадрат в CSS

Прогресс не стоит на месте. Когда делал галерею со смешнявками на чистом CSS в далеком 2020 году, у меня был вопрос, на который не могли ответить ни знакомые фронтендеры, ни на StackOverflow: как сделать “резиновый” квадрат, совместимый с другими фичами.

И вот, 5 лет спустя, шальная мысль пришла в голову и решение нашлось за один запрос: примерно с 2021 везде доступно свойство aspect-ratio, которое делает именно то, что нужно. Никаких больше уродских абсолютных значений в пикселях!

СсылкаКомментировать

Не тестируйте внешние домены

Не раз такое видел, что в тесте по интеграции с внешним API идет обращение к реальному домену. Некоторые даже при этом говорят “ачетаково”.

Основных проблем две: нестабильность теста и безопасность.

С нестабильностью понятно — сервис прилег, проблемы по дороге с сетью/DNS, rate-limiter зарубил вашего разраба, который запускал тесты 100500 раз в секунду, и привет, тест завален (очень сомневаюсь, что там учитываются подобные проблемы). Да, изредка нужно протестировать интеграцию 1-в-1, но это имеет смысл в весьма редких случаях и может быть достигнуто другими средствами (ну и graceful degradation никто не отменял). Опять же, как вы с реальным сервисом будете тестировать обработку всех проблем?

С безопасностью посложнее — между вами и доменом сервиса есть несколько промежуточных узлов, и вряд ли вы проверяете всю цепочку… Ок, домен доверенный, снимаем шапочку из фольги. А если у вас в коде randomserver.org? Конечно, вероятность, что об этом кто-то узнает, довольно мала. Внимательный читатель может догадаться, почему эта вероятность может резко повыситься:) Но если прям очень надо потестировать что-то связанное с реальной сетью (что еще более невероятно), то хотя бы используйте домены из RFC: .test, .example, .invalid.

Хотя о чем это я, простите, в половине инструкций в интернете сейчас curl | sh.

СсылкаКомментировать