Максим Морев
СтатистикаБлог опытного разработчика об IT и не только. Идеи, наблюдения, мемчики :)
- Последний пост
- 20 июл.
- Последнее чтение
- 18:42
- Постов за неделю
- 0
- Всего постов
- 20
- Тип
- открытый
- Язык
- русский
- Категория
- Технологии
- В каталоге с
- 12 авг.
- 1/24сутки в ленте
- 60
- 1/48двое суток
- 68
- 1/72трое суток
- 74
Оценка по просмотрам недавних постов: пост набирает почти всё за первые сутки.
Посты
видео или голосовое, без подписи
видео или голосовое, без подписи
Цена абстракций Делаю тут всякого разного и задумался над одной абстракцией, которую часто использую в библиотечном коде: const options = mergeObjects(defaultOptions, userOptions); Так выглядит ёмко выраженное намерение: есть опции по умолчанию, пользователь может некоторые из них изменить, но на выходе всегда нужен полный объект опций. То же намерение можно выразить прямым проектным кодом: const options = { hyphenate: userOptions?.hyphenate ?? defaultOptions.hyphenate, namespace: userOptions?.namespace ?? defaultOptions.namespace, delimiters: { element: userOptions?.delimiters?.element ?? defaultOptions.delimiters.element, modifier: userOptions?.delimiters?.modifier ?? defaultOptions.delimiters.modifier, modifierValue: userOptions?.delimiters?.modifierValue ?? defaultOptions.delimiters.modifierValue, }, }; Cори, это совершенно нечитаемо в тг. Cделаю себе большой блог когда-нибудь) Воспринимается заметно тяжелее, да? И корректность хочется перепроверить: не затесалось ли что-то хитрое? ➿➿➿ Решил замерить разницу по скорости (как я рад, что в наше время это можно сделать за 5 минут, почти не участвуя в процессе) и получил такие результаты: mergeObjects: 573 032 ops/sec Прямой код: 54 282 687 ops/sec Цена абстракции — примерно 100х замедления. Срочно надо всё переделать. А надо ли? "В 100 раз быстрее" звучит очень круто, но фактически мы сравниваем 0.000001ms против 0.0001ms. На единичный вызов и то и другое описывается словом "мгновенно". Убеждён, что в большинстве задач фронтенда ясность выражения намерения куда важнее оптимизации по цифрам, которые и без неё сильно меньше одной миллисекунды. До абсурда ведь можно довести. // (1) for (const [key, value] of Object.entries(object)) { // ... } // (2) Работает в 2-3 раза быстрее for (const key of Object.keys(object)) { const value = object[key]; } // (3) Ещё на 20% быстрее for (const key in object) { if (!Object.hasOwn(object, key)) continue; const value = object[key]; } Но важнее декларация намерения и скорость её восприятия. 1) В первом случае сразу понимаем: перебираем объект, нужны и ключи, и значения. 2) Во втором перебираем объект, работаем только с ключами... А нет, и со значениями. 3) В третьем работаем с ключами... Всеми? Нет, только собственными... А, и ещё со значениями. И тут стоит задуматься о стоимости сопровождения кода — на все многоточия выше разработчик тратит существенно больше времени, чем 0.0001ms. Что дороже стоит? :) ➿➿➿ Пока писал, вспомнил пару тематических медиа. Картинка просто забавная, а видео демонстрирует количество работы, которое скрывается за уже такой обыденной вещью, как простой вопрос в ChatGPT. Если достаточно приблизить любую абстракцию, то за строкой вроде createRoot(document.getElementById('app')) скрывается примерно столько же работы :)
Геометрия focus-ring по умолчанию в Chromium браузерах На такуу-у-у-ую интересную штуку наткнулся, причём для себя совершенно случайно. Предыстория: Делаю для жены простенький сайтик (прям своими руками и с большой любовью, что породит много контента). Решил CSS слои reset и base не притащить с последнего проекта, как это обычно бывает, а прям подумать и сформировать актуальные и современные, дабы выложить на npm и больше об этом не думать. Это важное уточнение, потому что в файлах с прошлых проектов обязательно есть правило :focus-visible со стилизацией outline под проект, а здесь систему проектирую абсолютно с нуля и без копипасты, и такого стиля не было. ➿➿➿ Теперь история: На странице есть список со ссылками на соцсети, у ссылок есть тултип, появляющийся по наведении. Оффтоп: а вы знали, что с предлогом "по" используется предложный падеж? Да, правильно сказать "по прилёте позвони" 💔 В процессе тестирования доступности заметил странное (на видео) — focus-ring захватывает абсолютно спозиционированных потомков элемента, причём в динамике. Моё лицо в тот момент, буквально — О_о Начал разбираться и обнаружил, что такое поведение возникает тогда, когда используется outline-style: auto в связке с браузером на основе Chromium. Это соответствует спецификации, которая буквально говорит, что в случае значения auto браузер сам решает, как рендерить outline. Ну, например, вот так... outline не обязан быть прямоугольным, он и раньше умел разрываться (представьте ссылку, которая начинается на одной строке и заканчивается на другой) — но то, что он может разрываться на потомках, вырванных из потока, для меня стало неожиданностью Исторические раскопки показали, что раньше (очень давно) подобное поведение наблюдалось в Firefox и на это жаловались. Вот, например, хороший комментарий с картинкой, иллюстрирующей, почему это весьма неожиданное поведение. Сейчас Firefox так не делает и нет способа заставить его это делать. У вас наверняка есть резонный вопрос: и что мне делать с этой информацией? А я не знаю, я обещал только делиться прикольными штуками :) Ну а кроме шуток — проверьте, что на ваших outline'ах не используется значение outline-style: auto, это может оказаться неожиданностью для вас и ваших пользователей :) Я вот такую базовую декларацию использую, по необходимости индивидуально адаптируя для элементов, которым это нужно: // Это весьма заметная рамка // и я нахожу её хорошим умолчанием :where(:focus-visible) { outline: 4px solid <color>; outline-offset: 4px; }
Про вау-эффекты и прочие свистоперделки Наткнулся тут на вот такой сайтик — документацию по библиотеке для Drag&Drop во Vue. Зашёл (на десктопе) и скривился — сомнительное удовольствие читать текст на переливающемся фоне, отвлекает от содержания. Ну, думаю, ладно — это же главная страница на один экран, контент тут не для чтения, а для привлечения внимания, этакий hero-page. Сомнительно, но окей. Перехожу на внутреннюю страницу и замечаю, что переливающийся фон никуда не делся. Более того — к тексту добавилась lens-анимация. Ещё и ширина строки в 170 символов (в то время как для чтения оптимально 60-80 символов на строку). Со стороны пользователя меня всё это раздражает, но как фронтенд-разработчик — я это с тёплым отеческим взглядом понимаю. Убеждён, что каждый фронтендер проходит этап, когда весь интерфейс такой "Пум-бдыщ! Смотрите все как я могу, как всё красиво вылетает со всех сторон, какой интерфейс живой, динамичный и нескучный! Сразу видно, за что мне деньги платят, какава красата" — Ваааань! А ты зачем корову через забор перекинул? — А потому что могу! У меня тоже это было, даже покажу попозже. Но хороший фронтендер обязательно должен этот этап переступить. Анимация — как соль в готовке, нужна в меру и не везде. Пошёл ассоциативный ряд: Вспомнил вопрос на Тостере о "модных фронтенд-фишках", на который отвечал когда-то, и порадовался тому, что и тогда было достаточно разработчиков, перешагнувших этот уровень. Вспомнил видеоролики Алексея Земскова (он толково рассказывает о ремонте, например, вот здесь), где на обзорах "дизайнерских" ремонтов хорошо видно, что почти всегда "красиво и необычно" является синонимом "совершенно непригодно к использованию". Ну, в общем, не надо так. Универсальный план проектирования чего угодно: 1. Делаем удобно. Дорисовываем сову. 2. Накидываем красивостей до тех пор, пока не начнёт становиться неудобно. Наоборот — не надо. P.S. Саму библиотеку так и не изучил, потому что из-за этих отвлекающих штук забыл, зачем вообще туда зашёл. Пользователь на вашем невероятно продающем сайте может поступить так же :) P.P.S. Кнопку "Read mode" видел. Но она должна быть нажата по умолчанию, и отожмёт её решительно никто :)
В чате веб-стандартов (доступном после подписки на Boosty) вчера притащили ссылку на заметку, предлагающую новый термин для надоедливых всплывающих окон — dickover. Вы их точно знаете, всевозможные — Мы используем куки, можно? Спасибо! — А рекомендательные технологии можно? Спасибо! — А хотите подписаться на нашу рассылку? — А в приложении удобнее. Открыть в приложении? — Вам подарок! Хотите забрать? Рассуждали на тему того, как это лучше локализовать. Херовер (от popover)? Херап (от popup)? Мудалка? Мудальное окно? Мне "мудальное окно" больше всего нравится — в русскоязычной разговорной речи редко слышу "popover" или "popup", а вот "модалка" всегда на слуху. Знаете какие-то ещё прикольные словечки? Мне вот очень нравится термин "нафигация" для обозначения плохо спроектированной навигации :) Или вот "наговноклодили" тоже хорошее выражение :)
видео или голосовое, без подписи
видео или голосовое, без подписи
Контраст текста на неоднородном фоне Зашёл тут на один сайт и прям захотел нажать на кнопку "Версия для слабовидящих". Что характерно — полегчало, в этом режиме промо-изображения в баннере не отображаются)) В картинках к посту показал, что с этим можно было бы сделать. А если интересно почитать о проблеме более техническим языком, то предлагаю посмотреть на пост из канала <divilopers> примерно про то же самое. Да и вообще канал хороший, один из самых ценных в моём списке источников. ➿➿➿ Ну и история из жизни: Я однажды проектировал дизайн-систему для сайта, где основная навигация располагалась поверх слайдера с промо-изображениями, прямо как на сайте, который меня триггернул на этот пост. Брендбук там был в тёмных тонах и я, разумеется, поместил под навигацию полупрозрачный градиент от тёмного до прозрачного, "тенюшечку". Спустя время пришёл заказчик и сказал, что тень некрасивая и надо её убрать. — Что будем делать, если промо-изображение будет светлым? — спросил я. — У нас никогда не будет таких изображений. — уверенно ответил заказчик. Прошёл месяц. У нас появилось белое промо-изображение. — Может, вернём тенюшечку?.. — робко поинтересовался я. — Нет, тенюшечка некрасивая, — припечатал заказчик, — будем на таких слайдах перекрашивать меню в чёрный! Так в системе появляются связи, за которые стыдно. Прошёл месяц. У нас появились промо-видео. А в видео нет фиксированного фонового цвета. — Тенюшечку? — с улыбкой поддел я. Заказчик морщился, пыхтел, но придумать более "красивого" решения не смог. — Хорошо, сделаем тень. Но только для слайдов с видео! Я только вздохнул. Потом было ещё много разных изображений. В том числе серых, на которых и белый, и чёрный читаются примерно никак. Маркетологи заказчика стали использовать вариант с тенюшечкой на всех слайдах, потому что он гарантированно работает. Заказчик сдался под гнётом обстоятельств. Хэппи-энд? Увы. Задачу с выпиливанием ненужных состояний заказчик не согласовал. "Пусть будет, может к этому вернёмся потом". Так и живёт система с мёртвыми, ненужными состояниями, которые нужно учитывать, тестировать, а оно и не надо никому... ➿➿➿ Цель большинства сайтов — донести информацию, а не настроение, и чаще всего функциональное решение должно иметь приоритет над утончённым и изящным. Интерфейс живёт не в обещаниях, он живёт в реальном контенте, который обязательно будет светлым, серым, пёстрым, кривым, длинным и загруженным в админку в пятницу вечером. Поэтому при проектировании системы очень полезно представлять не идеальный удобный сценарий, а самый нелепый, вычурный, странный (и даже он потом окажется далёким от реальности). Белый текст на белом фоне. 20 тегов у карточки товара. Цена товара "3 597 394 đ 4 957 400 đ" вместо удобных "10 000 ₽" при локализации. Фамилия пользователя на 30 символов без пробелов. ...и многое другое. Любите интерфейсы и ваших пользователей, аминь :)
На статью наткнулся: CSS Performance Optimizations for Grid. Интересный кейс того, что иной раз именно CSS может быть узким местом производительности. Чаще всего CSS не является бутылочным горлышком. Браузеры хорошо оптимизированы для работы со стилями, и часто более выгодно прилагать усилия для оптимизации JS, а не CSS. Однако, если речь идёт о действительно больших страницах (с точки зрения структуры DOM), а также необходимости частых обновлений, всё может поменяться. В статье показано, что время рендеринга одной и той же разметки на разных стилях может отличаться в 7 раз. Обычно это будет что-то в духе 300мс против 45мс — такая оптимизация приятна, но ничего критичного. Но в статье приводятся цифры — 7 секунд против 1 секунды. И вот 7 секунд — это уже катастрофа. ➿➿➿ Ключевые моменты: ⚫️Нужно аккуратно подходить к вычисляемым свойствам CSS Custom Properties — не бесплатные. Особенно, когда внутри используются другие функции. Бояться их не нужно, но выстраивать целую систему на этом я бы поостерёгся. Верю в то, что CSS должен быть статичным настолько, насколько это возможно для конкретного интерфейса. ⚫️Нужно стремиться к плоским селекторам Сложные селекторы вроде [part~="cell"], а также любой каскад приводит к более частому и дорогому матчингy по сравнению с классами (БЭМ опять молодец 🎉) CSS действительно может быть узким местом, когда его нужно часто пересчитывать и он сложно устроен (селекторы + вычисления). ➿➿➿ В завершение хочется сказать, что нам хочется видеть существенные цифры прироста производительности — ускорили в 5 раз, в 10 раз, но иногда ускорение и на 30% может сыграть свою роль, иногда важно пересечение порога, а не конкретные цифры. Например, если цикл перерисовки занимает 20мс, то минус 30% — это уже ~14мс, и вот мы уже попадаем в бюджет одного кадра (16.6мс) для 60Гц экрана, и ощущаться интерфейс станет ощутимо приятнее.
Вышел ролик на канале, в котором рассказываю о своём рабочем месте (кресло, столешница, подстолье, оборудование), делюсь мыслями относительно тех или иных вариантов, а также прохожусь по теме организации рабочего пространства в целом. YouTube / Rutube (1 час 20 минут) Если задаётесь вопросами в духе: ⚫️Как сидеть за ПК долго и без напряжения? ⚫️Какая глубина эргономичного выреза стола оптимальна? ⚫️Из чего делать столешницу и какой толщины? ⚫️Сколько мониторов оптимально для работы? ⚫️Сильно ли шатается стол для работы стоя и нужен ли он вообще? ...то в видео есть ответы на них. Были мысли сделать несколько отдельных роликов, но решил не мудрить и сделать одно видео. Таймкоды там все есть. Вся информация о моём оборудовании текстом есть в публичном репозитории morevm/use. ➿➿➿ Дальше планирую обновление рабочей станции: ⚫️Перетяжку кресла в алькантару с металлическими пластинами внутри для реализации магнитного крепления подушки под голову и поясницу ⚫️Добавление охлаждающего слоя к подушке под голову ⚫️Заказ столешницы большего размера по глубине ⚫️Заказ подстолья с большим диапазоном регулировок и четырьмя точками опоры ⚫️Наращивание стойки кронштейна для мониторов По завершении сделаю обзорное видео и пост. Если у вас есть практический опыт, который помогает вам в том, чтобы чувствовать себя лучше — буду рад об этом узнать и применить на себе 🙏 ➿➿➿ Если остались какие-то вопросы, или интересно мнение относительно того или иного варианта — я всегда здесь, чтобы помочь :)
О доверии к LLM Появилась у меня задачка: на вход подаётся произвольный текст с описанием мероприятия. Нужно разобрать его и привести к структурированному виду: <тип мероприятия> <название мероприятия> 🗓 <дата> | <день недели> | <время> <описание без воды и маркетингового шума> 📍 <информация об организаторе> «Ого, лингвистическая задачка для лингвистической модели!» — подумал я. В промпте примерно 200 строк текста с описанием того, что и как интерпретировать. Среди прочего: `<день недели>` - день недели на дату мероприятия, либо "сегодня", если дата совпадает с текущей. Примеры: - среда - пятница - сегодня ➿➿➿ Запускаем шайтан-машину: ... 🗓 20 марта | четверг | 17:00 ... Почти как надо. Правда, 20 марта — это пятница... сущая мелочь. ➿➿➿ Ладно, уточняем промпт: КРИТИЧЕСКОЕ ТРЕБОВАНИЕ: день недели должен быть вычислен точно по календарю для конкретной полной даты (число + месяц + год), а не взят из исходного текста и не определён по памяти. Обязательные правила: - сначала определить год; - затем вычислить день недели для полной даты; - если день недели в исходнике расходится с вычисленным, использовать вычисленный вариант; - исходный день недели считать недостоверным, пока он не проверен; - нельзя копировать день недели из текста без календарной проверки; - если дата совпадает с текущей, вместо дня недели писать `сегодня`. Примеры: - 20 марта 2026 — пятница - 28 февраля 2026 — суббота - 11 мая 2026 — понедельник Ффух... Вроде всё. Запускаем — работает. Это победа. ...10 постов спустя... ... 🗓 20 марта | четверг | 21:00 ... Спрашиваю: WTF? Дата и день недели: 20 марта 2026 года — это четверг (перепроверено по календарю). В исходнике ошибка («пятница»). ... И этой штуке можно доверить писать код?.. LGTM, пыщ-пыщ, другой агент проверил? Здорово, когда в результате 10 строк, которые легко оценить, да и точность требуется только в двух. А в коде сколько строчек, в которых точностью можно безопасно пренебречь?.. Пока, увы, продолжаю наблюдать то же, что и раньше — большие лингвистические модели хороши в решении лингвистических задач. Словами, действительно, можно жонглировать как угодно и в лингвистике это скорее хорошо, чем плохо. Но работа с большим объёмом кода... сколько таких "четвергов вместо пятницы" лежит в PR на 500 строк?.. И очень оно ведь правдоподобно всегда выглядит, не расслабишься.
видео или голосовое, без подписи
видео или голосовое, без подписи
В субботу выйдет ролик с обзором моего рабочего места на полтора часа 🖥 Полгода в столе лежал и вот нашлись силы добить и смонтировать. Спасибо всем, кто подпинывал 👍 ➿➿➿ Тем временем всё готовлю видео про Tailwind, наткнулся на статью, в которой в рамках пиара своего платного курса "Неортодоксальный Tailiwind" автор задаётся вопросом, чем же таким компонент отличается от утилитарного класса. Уровень обсуждения, который мы заслужили :) В другой статье тот же автор предлагает, если вкратце, "а давайте поверх Tailwind в отдельном слое писать нормальные компоненты с помощью обычного CSS, подпирая в HTML при необходимости !important'ами". Однако по-прежнему предлагает писать фэнтезийный синтаксис (картинка). Сейчас автор предлагает, если перевести на ортодоксальные термины, объявлять компоненты-блоки, а утилитарные классы TW использовать для описания того, что в БЭМе зовётся миксами и модификаторами. Почему он это предлагает? Во второй статье он сам об этом пишет, процитирую: I do this so I can shift these properties to CSS when they get more complex — so I don’t have to read messy utility-littered HTML that makes my heart sink. Not because utility HTML is bad, but because it takes lots of brain processing power to figure out what’s happening. Пройдёт ещё совсем немного времени и автор придёт к мысли, что миксы и модификаторы, вообще, тоже неплохо было бы разделить. Да и модификаторы наблюдать отдельно, наверное, было бы неплохо для figure out what’s happening. И изобретёт что-то БЭМоподобное со своим синтаксисом. Но БЭМ — это не модно, а вот "Unorthodox Tailwind" звучит очень современно и с вызовом 😎 У нас не пирожки, а закрытые бургеры. Не библиотеки, а коридинги... Смех смехом, но я готов поддержать движение "Неортодоксальный Tailwind", так как чем методология дальше от атомарных стилей, тем она жизнеспособнее и ближе к платформе. Tailwind — это не абстракция над CSS, это абстракция вбок от CSS. Автор идёт к тому, чтобы оставить от Tailwind дизайн-систему с токенами и писать поверх неё обычные компонент-ориентированные стили. Я и сам отмечал в своих разговорах о Tailwind, что я его автора сильно уважаю за попытку систематизации, труд проделан очень большой, и опереться на него, если нет архитектора, определённо имеет смысл. Ждём, пока из этой схемы уйдёт Tailwind и останутся одни дизайн-токены... 🍿
Егор Бугаенко поделился статистикой по своему YouTube-каналу, из которой видно, что только 2.7% его зрителей — девушки. Я, конечно, пошёл смотреть свою — и моим контентом интересуются 2.8% прекрасных дам. Очень похожие цифры — видимо, вот она, ниша :) Я девушек люблю больше, чем они меня — из моих 316 подписок на YouTube аж 16 каналов, которые ведут представительницы прекрасного пола, что составляет 5%. Впрочем, только один из них — и то с натяжкой — относится к моей профессиональной деятельности. Сегодня прекрасный день, и я хочу сделать небольшую подборку YouTube-каналов за авторством прекрасных дам, которые оказали на меня влияние 💅 ➿➿➿ 🔷Английский с Ронни — название говорящее. Эта женщина сильно повлияла на моё отношение к тому, как стоит подавать себя в публичном пространстве. Вы посмотрите, какая она естественная! Она явно хорошо знает, о чём говорит, и при этом от неё абсолютно не исходит ощущение "я — экспертный эксперт, щас вас научу, как надо жить". Замечательный пример того, как можно просто рассказывать истории и делиться опытом, а не важничать и корчить из себя важный курица — и при этом доносить смысл. Стремлюсь в своём контенте к тому, что меньше важничать и поучать. Получается не очень, но я стараюсь :) 🔷Полина Маришóва — что-то про успешный успех и коммуникацию. Честно говоря, понятия не имею, кто такая и чем знаменита — наткнулся на неё, когда занимался постановкой речи, и после просмотра нескольких роликов принял решение прекратить свои занятия (внезапно). Она говорит очень выверенно: правильные телевизионные интонации, чёткая подача, всё звучит максимально профессионально. Но я поймал себя на мысли, что, хотя форму я и считываю как профессиональную, никакой эмпатии эта манера речи у меня не вызывает. Более того — она сама по себе создаёт ненужную дистанцию между спикером и слушателем. Для себя решил, что не надо к этому стремиться, проще надо быть, ибо мне и самому гораздо интереснее слушать живых людей, чем роботов с идеально настроенными интонациями. Спотыкающихся, запинающихся, уходящих в сторону... Это ближе и доверия этому больше. 🔷авось прорвемся — вайти-вайти, девочка в красной шапке и единственный канал в этом списке, что хоть как-то связан с моей профессиональной деятельностью. Для меня пример того, как можно очень живо и без апломба доносить свои мысли. Пример того, как, имея подвешенный язык, можно из пекаря стать разработчиком, а потом и вовсе продавать воздух. Пример того, что для записи видео не обязательно иметь оборудование на сотни тысяч рублей — можно просто айфон поставить и записать, не особо переживая о том, как ты выглядишь. Я на её фоне себя чувствую заложником своего культурного воспитания (на сцене всегда должен быть профессиональный профессионал!) и экспертности (я ж 16 лет этим занимаюсь, щас вот скажу какую-то глупость — как жить-то дальше с этим?). Она очень живая и непосредственная, не строит из себя никого — и это цепляет. Надо быть собой, у неё хорошо получается. 🔷Ирина Якутенко — научный журналист Я интересуюсь популярной психологией и научпопом, и у Ирины просто очень много контента на разные темы, которые можно применить в обычной жизни, да и просто расширить своё представление о мире. На канале нет какой-то узкой специализации — она рассказывает очень о многом, делает это интересно, и в меня это часто попадает. "Будучи человеком увлечённым, но непоследовательным, он знал много бесполезных, но интересных вещей" — это моя история, я такое люблю. ➿➿➿ C праздником, дорогие дамы! Спасибо вам за то, что делаете мир интереснее, эмоциональнее и живее 🌹
Наткнулся на забавную картинку :) Но не могу же я просто картинку запостить (ПОЧЕМУ?!), поэтому расскажу о семантическом версионировании, SemVer. Само по себе версионирование библиотек — очень простая вещь, и хорошо в двух экранах описано на сайте (RU, EN), поэтому расскажу о всяком интересном сбоку. Как версионировать сайты, приложения c UI? Никак, семвер неприменим для продуктов без публичного API как основной функции. Чаще всего не версионируют вовсе, либо используют календарное версионирование (CalVer, 26.05.11), что по сути сводится к Pride Versioning как на картинке выше. Делается это преимущественно для адресации внутри команды разработки ("сломалось в версии 26.7.12"). Можно ли доверять номеру версии при обновлении библиотеки? Совсем нет, это социальный контракт. Меня, как автора библиотеки, от публикации чего-то ломающего или даже вредоносного в патч-версии останавливает только уровень инженерной культуры. Понятно, что чем более популярен пакет и чем большего размера организация за ним стоит, тем меньше этот риск, но, как известно, вероятность встретить гужевую повозку в центре города мала, но никогда не равна нулю. Я встречал ломающие изменения в патч-версиях пакетов с миллионами загрузок в неделю. Если изменение не ломающее, но болезненное — как быть? dart-sass, например, очень любит в рамках минорных релизов deprecate'ить какие-то функции. Формально всё продолжает работать, но в терминал сыпется миллион предупреждений, что делает работу настолько некомфортной, что изменения в код всё равно приходится вносить (как минимум — отключить предупреждения). Stylelint тоже таким отличался, что привело к массовому недовольству и авторам плагинов пришлось в спешном порядке вносить изменения. Хороших решений здесь нет. Никак не говорить о том, что какая-то функциональность будет изменена/не рекомендуется к использованию — плохо, в момент мажорного релиза потребителям придётся проделать очень много работы единоразово плюс переучивать наработанные паттерны. Если добавлять предупреждения — хорошо, если это можно сделать так, чтобы было только одно сообщение в консоли для каждого использования, но это архитектурно не всегда возможно. Мне видится, что авторы вышеуказанных инструментов всё делают правильно — нужно готовить сообщество заранее. А что до болезненности — да, неприятно, но автоматика не упадёт, всё продолжит работать. Вполне в духе SemVer. ➿➿➿ Тема версионирования, на самом деле, как и любая другая, очень широкая, можно много чего рассказать. Если есть какие-то вопросы на тему версионирования — напишите, расскажу :) А мог бы просто смешную картинку запостить, ну...
У меня много разных проектов, и зависимости в них управляются разными пакетными менеджерами — часть использует npm, что-то — yarn classic, некоторые — yarn berry, на последних проектах использую pnpm. Непередаваемое ощущение, когда по привычке набираешь `pnpm install` в старом проекте и по завершении обнаруживаешь, что вообще-то тут `yarn` 😳😡🤯 Чем плохо установить зависимости не тем пакетным менеджером? Во-первых, будет проигнорирован lock-файл, и версии устанавливаемых модулей разойдутся, сборка становится нестабильной — у вас одни версии, а у коллег — другие. Во-вторых, по-разному может работать разрешение зависимостей — yarn classic, например, позволяет прямое использование транзитивных зависимостей (hoisting), а pnpm (по умолчанию) — нет. ➿➿➿ Хочу поделиться инструментом, с которым я забыл о проблеме "установил не тем менеджером" — пакет ni от Anthony Fu. Просто набираешь ni, а пакет сам по lock-файлу либо полю packageManager в package.json определит, какой пакетный менеджер нужно использовать. Пользуюсь давно, работает стабильно, проблему решает — рекомендую к использованию :)
Популярные Markdown-парсеры позволяют использовать расширения, с помощью которых можно дополнять синтаксис Markdown. Одно из таких расширений — Custom Containers — позволяет использовать специальный синтаксис для создания стилизованных блоков, а также для замены полезных HTML-конструкций вроде <details> + <summary> без необходимости использовать HTML внутри Markdown-документа. Пример из документации Vitepress Использование сырого HTML внутри Markdown считается плохой практикой, так как затрудняет чтение исходника, что против философии Markdown, а ещё может привести к неверной интерпретации при использовании индентации. <!-- ❌ Плохо --> <details> <summary>Показать подробности</summary> Какой-то текст </details> <!-- ✅ Хорошо --> ::: details Показать подробности Какой-то текст ::: Но написать я хотел не об этом 🤷♂️ Иной раз возникает необходимость использовать один контейнер внутри другого, и вот здесь нужно знать о том, что вот эти три двоеточия ::: работают точно также, как и символы ``` при использовании fenced code blocks (о них уже писал ранее в блоге). А именно — их необязательно должно быть три, их должно быть не менее трёх и они должны быть парными. Это в каком-то роде очевидно, если задуматься, но информации об этом в интернете можно сказать нет, и я об этом не знал. То есть правильный вариант вложения custom containers друг в друга выглядит так: ::::: details Свёрнутый блок :::: details Вложенный блок ::: info Какой-то информационный текст ::: :::: ::::: Мне это в голову не пришло и я пошёл позориться с issue в репозиторий eslint-plugin-markdown-preferences. Вы теперь знаете и позориться не будете 🫡
Вышел новый ролик на канале, где рассказываю о том, почему БЭМ как CSS-методология всё ещё актуален, несмотря на наличие инструментов вроде CSS Modules и Scoped CSS. Приглашаю посмотреть и обсудить :) YouTube / Rutube, 20 минут. Краткая текстовая версия: CSS Modules и Scoped CSS решают проблему коллизий — они не дают стилям протекать наружу и влиять на стили других компонентов. Однако необходимость изоляции стилей — не единственная и даже не основная проблема, которая делает написание и сопровождение стилей сложной задачей. БЭМ решает эти проблемы (как и коллизии) за счёт создания соглашений, которые обеспечивают единообразие и предсказуемость, и это важно. Аналогия из JS: <!-- Вот было бы здорово сделать так, чтобы `foo.js` мог объявлять переменные, а `bar.js` мог на них повлиять, да? --> <script src="foo.js"></script> <script src="bar.js"></script> И есть ведь такой механизм — ES-модули: <script type="module" src="foo.js"></script> <script type="module" src="bar.js"></script> Счастье же? Изоляция прям из коробки. Но кто-то готов сказать, что этого механизма достаточно для того, чтобы легко писать и сопровождать код? Спрятали хаос в коробку и делаем вид, что всё хорошо. Это лучше, чем вообще ничего не сделать, но явно недостаточно. Внутри идеально изолированных модулей, если нет правил и соглашений: ⚫️Один пишет is_activeUser, другой — UserIsActive; ⚫️Один пишет function, другой — const fn = () =>, третий — всё подряд; ⚫️Один мутирует аргументы функции, другой считает это преступлением; ⚫️Один возвращает null, другой — undefined, третий — кидает исключение; ⚫️Один экспортирует в начале файла, другой — внизу, третий — вперемешку с логикой; ⚫️...продолжать можно очень долго. ➿➿➿ Изоляция даёт техническую безопасность стилей, а БЭМ — делает их предсказуемыми для людей, и это тоже очень важно. По величине влияния так и вовсе более важно.