Как разработчик сломал интернет, отменив публикацию своего пакета в 11 строк кода

1
1243
views

Перевод статьи «How a developer broke the internet by un-publishing his package containing 11 lines of code».

Всем Javascript-разработчикам приходится рано или поздно использовать npm. Это менеджер пакетов для node.js, принятый по умолчанию. Само название npm — аббревиатура Node Package Manager. Компания NPM является дочерней компанией GitHub.

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

Теперь, когда мы разобрались, что такое npm и как он работает, давайте вспомним, что произошло 22 марта 2016 года. Тогда внезапно сломались массово используемые пакеты, такие как React, Node, Babel, а множество JavaScript-разработчиков по всему миру, пытаясь запустить свой код, получили странное сообщение об ошибке.

Предыстория

Азер Кочулу (Azer Koçulu) — разработчик, участник движения open source. Он публиковал и поддерживал свои проекты на npm. Другие разработчики пользовались этими пакетами и включали их в свои проекты. В общей сложности у Кочулу на npm было примерно 270 пакетов. Один из них, предназначенный для помощи разработчикам в настройке шаблонов для их проектов, назывался kik.

Так уж случилось, что то же имя — Kik — было у бесплатного мобильного приложения-мессенджера для Android и iOS. Выпускала его компания Kik interactive, базирующаяся в Канаде (Онтарио).

E-mail

Однажды Кочулу получил электронное письмо от Боба Страттона — одного из агентов, занимающихся патентами для Kik. Страттон просил Кочулу сменить название его пакета kik, поскольку компания Kik планировала опубликовать на npm свой пакет с тем же именем, что могло привести к путанице. Всю переписку можно посмотреть здесь, но если говорить коротко, тон письма Страттона напоминал наезд был не слишком дружелюбным, и Азер отклонил требование компании Kik.

Страттон упирал на то, что «kik» — это зарегистрированная торговая марка, а кроме того, наличие двух пакетов с одинаковым названием может сбивать с толку пользователей. Те же доводы он привел, обратившись в переписке к команде NPM.

В NPM решили встать на сторону Kik и «отдать» спорное имя компании.

Освобождение модулей

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

Спустя два дня после этого письма к NPM, во вторник, 22 марта 2016 года, программисты по всему миру с удивлением наблюдали, как у них ломаются сборки и падают инсталляции. Среди множества ошибок была и такая строчка:

npm ERR! 404 'left-pad' is not in the npm registry.

Эта ошибка означает, что для кода, который вы пытаетесь собрать или запустить, нужен пакет под названием left-pad, а этого пакета нет в npm-реестре. Куда же делся этот пакет left-pad?

Кочулу сделал то, о чем писал в своем письме. Он отменил публикацию всех своих пакетов в npm, и left-pad был одним из них. Кочулу написал пост в блоге, в котором объяснял, почему отменил публикацию всех своих модулей. «Эта ситуация заставила меня осознать, что NPM — это чья-то частная земля, на которой корпорации имеют больше прав, чем люди. А я занимаюсь open source, потому что власть должна принадлежать людям (англ. Power To The People)», — сказал Кочулу в своем блоге.

https://t.me/thingsprogrammersdo/

Отмена отмены публикации left-pad

Чтобы исправить ситуацию со внезапно сломавшимися пакетами по всему миру, 23 марта Лори Восс, директор и соучредитель NPM, поступил «не по уставу»: он восстановил отмененную публикацию пакета left-pad 0.0.3, от которого зависели приложения на NPM. Он написал в Twitter: «Отмена отмены публикации это беспрецедентная акция, на которую мы решились из-за серьезности и масштаба поломки, и это решение далось нам нелегко».

После этого все упавшие пакеты стали успешно собираться и запускаться и таким образом интернет был спасен.

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

Чем по сути был left-pad?

Давайте посмотрим на содержимое left-pad и попробуем понять, почему так много пакетов по всему миру использовали этот пакет. Как следует из самого названия, left-pad забивает левые части строк символами или пробелами (left — «слева», pad — «набивать», — прим. перев.). Весь пакет состоит из 11 строк кода. Вот все содержимое left-pad:

module.exports = leftpad; 
function leftpad (str, len, ch) {
   str = String(str);
   var i = -1;
   if (!ch && ch !== 0) ch = ' ';
   len = len - str.length;
   while (++i < len) {
     str = ch + str;
   }
   return str;
}

Почему же из-за этого сломалось так много пакетов на NPM?

React, Babel и многие другие популярные проекты на NPM сломались 22 марта 2016 года, потому что во всех этих проектах и пакетах была зависимость от простой функции из пакета left-pad. Большинство программистов, столкнувшихся с этими ошибками сборки, могли даже и не слышать о таком пакете, но их код сломался, потому что их приложения зависели от каких-то пакетов, которые, в свою очередь, зависели от других пакетов, и одной из зависимостей оказался left-pad.

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

Почему для забивания левой части строки в таком огромном количестве пакетов использовался left-pad?

Пакет left-pad с его 11 строками кода — всего лишь функция, экспортируемая в виде модуля. И многие разработчики предпочли взять готовую функцию вместо того чтобы написать ее самостоятельно. У опытного программиста на написание подобного кода ушло бы всего несколько минут, но все равно многие решили положиться на чью-то чужую работу.

Связывание множества сторонних зависимостей или пакетов и разработка проекта с минимальным количество кода не должно считаться идеальным вариантом. Любые проблемы в этих сторонних зависимостях приведут к поломке вашего кода. Кроме того, в исправлении ситуации вы будете тоже зависеть от другого разработчика: пока он не исправит свой код, ваш не заработает нормально. Когда такие веб-сервисы, как например Facebook, начинают косвенно зависеть от кода, написанного сторонними программистами, это следует рассматривать как серьезную проблему. Особенно с учетом того, что эти сторонние программисты могут и не догадываться, какое влияние их код может иметь на чужие продукты.

Photo by Lala Azizli on Unsplash

«Слишком много зависимостей» — это сколько?

Если у нас есть специальный пакет для проверки, является ли объект массивом, не значит ли это, что мы стали слишком ленивы? В этом пакете всего одна строчка кода, а он загружается 39 001 468 раз в неделю (на момент написания этого поста). Нам правда необходимо публиковать пакеты, содержащие всего одну функцию? И нужно ли создавать зависимости от пакетов с несколькими строчками кода, которые мы вполне могли бы написать сами?

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

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

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

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

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

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

1 КОММЕНТАРИЙ

  1. Вся проблема в том. что в мира JavaScript отсутствует нормальный вендоринг. Есть пакет в репе, нет пакета в репе… Если этот пакет завендорен — это уже не важно. А новый проект если вы начинаете — оно с самого начала будет понятно, что такого пакета нет (и его можно будет подтащить из проекта, в котором этот пакет завендорен).
    Короче, закопайте жабаскрипт во Христе. Труп уже воняет))

ОСТАВЬТЕ ОТВЕТ

Please enter your comment!
Please enter your name here