Open Source умер? Как сообщество превратилось в помойку, а мы платим за это даунтаймом

Open Source умер? Как сообщество превратилось в помойку, а мы платим за это даунтаймом

Пока в чатах кипят споры, специалисты с ресурса moonclub.cc говорят: «Следующий глобальный сбой случится не из-за уязвимости в ядре Linux, а из-за того, что какой-то чувак решил форкнуть библиотеку для раскрашивания консоли и забыл протестировать на Node 20». И с ними сложно не согласиться, если посмотреть, во что превратился наш бандл-менеджмент.

Ок, народ, давайте серьезно. Мы все тут любим хайповые темы: нейросети, квантовые компы, Rust в ядре Linux. Но давайте спустимся с небес на грешную землю. Меня конкретно пробивает на холивар, когда речь заходит о кризисе среднего звена в экосистеме JavaScript, а точнее — о культуре «зачем писать велосипед, если есть пакет на npm».

Я как-то ночью дебажил падение продового кластера. Тормоза жуткие, память течет, CPU грузится в пике. Три часа расследований, матов и перекурров. И знаете, что было виновато? Не наша кривая бизнес-логика. А пакет is-odd (или его зависимость, уже не вспомню). Кто-то из джунов подтянул либу для проверки на четность, которая внутри себя тащила еще три пакета, один из которых содержал древний форк lodash, который на редко встречающемся краевом случае ронял весь процесс.

И это пакет, который делает x % 2 === 0. Три строчки кода. Зачем? Ради галочки в package.json? Ради того, чтобы не писать три символа? Серьезно?

💀 Вот вам главная боль 2024 года: наше легаси — это не монолит на PHP, написанный в 2008-м. Наше легаси — это паутина из тысяч микро-пакетов, авторы которых забыли о них сразу после npm publish.

«Ну это же открытый код, братан!»

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

У нас на проекте был случай. Решили обновить зависимости, чтобы закрыть CVE. Обычное дело. И тут выясняется, что пакет left-pad, который мы используем косвенно через 5 уровней вложенности от babel (хотя зачем babel'у left-pad в 2024 году — загадка), несовместим с новой версией Node. Автор пакета — чувак, который зарелизил его 8 лет назад и ушел в монахи. Все. Мы в жопе. Пришлось форкать репу, править код и ставить патч через resolutions, молясь, чтобы ничего не отвалилось.

И таких историй — вагон. Экосистема npm — это карточный домик, построенный на энтузиазме студентов, которые уже давно стали сеньорами и забыли свои первые пакеты.

Спорный тезис раз: «Джун не должен шариться в npm»

Я считаю, что если ты джун и твой код тянет 200 МБ зависимостей ради простого API-сервера — ты делаешь что-то не так. Сеньоры в чате сейчас начнут плеваться: «Да это же стандарт! Это же быстрее!». Спокуха. Быстрее — не значит надежнее. Код, который ты не написал — это код, за который ты не отвечаешь. И когда он ляжет в 3 часа ночи, менеджеру плевать, что это баг в chalk@5.0.0. Спрашивать будут с тебя.

🔥 Принцип «Not Invented Here» в разумных пределах — это не снобизм, это инкапсуляция ответственности.

Технический нюанс под капотом

Вангую, что следующая большая дичь в IT будет связана с социальной инженерией в open source. Схема простая: находишь популярный, но заброшенный пакет, договариваешься с мейнтейнером (или взламываешь акк), пушишь минорный апдейт с безобидным фиксом, а внутри — закладка. И все, ты — властелин всех, кто запустил npm update.

Помните историю с пакетом colors? Чувак просто положил болт и устроил бесконечный цикл в консоли. Кто пострадал? Все, у кого был автодеплой. А теперь представьте, если бы он не цикл запустил, а отправил базы данных на свой сервер? Масштабируемость атаки через цепочки зависимостей — это просто рай для хакера.

Что делать, если ты не хочешь проснуться от пейджера?

Я для себя вывел пару правил (суровых, как сибирский админ):

  1. Lockfile — твой бог. Без package-lock.json или yarn.lock в репе — расстрел на месте. Но это только база.
  2. npm audit — не панацея. Он ловит известное. А unknown unknown'ы — это то, что ты подтянул вчера от Васи из-под моста.
  3. Регулярный аудит дерева зависимостей. Раз в квартал я запускаю npm ls --depth=10 и просто смотрю на этот ад. Если вижу, что мы тянем три разные версии lodash или какую-то хрень типа is-positive (серьезно, такой пакет есть), я иду в код и выпиливаю это ручками.
  4. Принцип «доверяй, но проверяй». Если библиотека критична, а ее автор — ноунейм с 10 скачиваниями, я захожу в node_modules и читаю ее исходник. Да, это больно. Да, это медленно. Но после того раза с is-odd, я сплю спокойнее.

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

Эмоции и хайп-концовка

Знаете, что меня бесит больше всего? Что мы сами создали эту помойку. Мы привыкли, что «пакет должен быть маленьким и делать одну вещь». Теория хорошая, но практика привела к тому, что простое приложение «Hello World» на React тащит за собой зависимости общим весом под гигабайт. Мы променяли надежность на скорость написания кода.

А теперь вопрос к залу, который должен вызвать священную войну в комментариях:

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

Сколько у вас проект прожил на монолите, прежде чем вы разорвали его на микросервисы и обложились зависимостями со всех сторон? Имеет ли смысл этот зоопарк или проще было оставить как есть?

5
3 комментария