NPM и left-pad: мы разучились программировать?

Автор оригинала: Дэвид Хейни
  • Перевод
Автор — Дэвид Хейни (David Haney), ведущий инженер-программист Stack Overflow

Итак, разработчики, время для серьёзного разговора. Вы уже наверное в курсе, что на этой неделе React, Babel и куча других популярных пакетов на NPM сломались. Причина довольно удивительная.

Простой пакет NPM под названием left-pad был установлен как зависимость в React, Babel и других пакетах. Модуль, который на момент написания этого поста, имеет 11 звёзд на Github (сейчас 323 — прим.пер). Весь пакет состоит из 11 простых строчек, которые реализуют примитивную функцию вставки пробелов в левой части строк. Если какие-то из ссылок когда-нибудь умрут, вот его код:

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;
}
Что меня беспокоит, так это такое большое количество пакетов, где установлена зависимость от простой функции набивки строки пробелами, вместо того чтобы потратить 2 минуты и написать эту базовую функцию самому.

Узнав о бедствии, которое случилось из-за left-pad, я начал исследовать экосистему NPM. И вот что обнаружил, среди прочего:

  • Есть пакет под названием isArray, который скачивают 880 000 раз в день, 18 млн скачиваний в феврале 2016 года. У него 72 зависимых NPM-пакета. И вот его целая 1 строчка кода:
    return toString.call(arr) == '[object Array]';
  • Есть пакет под названием is-positive-integer (GitHub), который состоит из 4 строчек и которому на вчерашний день требовалось 3 других пакета для работы. Автор с тех пор провёл рефакторинг, так что теперь у пакета 0 зависимостей, но я не могу понять, почему это не было сделано сразу.
  • Свежая установка Babel включает 41 000 файлов
  • Чистый шаблон приложения на базе jspm/npm начинается c 28 000+ файлов

Всё это заставляет задать вопрос…

Мы разучились программировать?


В каком из параллельных миров вышеперечисленные решения являются наилучшими? Как сотни зависимостей и 28 000 файлов для пустого шаблона можно назвать чем-то ещё, кроме чрезмерной сложности и безумия?

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

Функции — это не пакеты


Функции слишком малы, чтобы попасть в пакет и зависимость. У чистых функций нет связи; это случайные фрагменты кода и ничего больше. Кому нужна зависимость от косинуса? Вместо этого нам бы по-настоящему понравилась зависимость от пакета «тригонометрия», который охватывает много хитрых функций, которые мы не хотим писать сами. Это гораздо больше похоже на то, как .NET и другие фреймворки создают базовую библиотеку с основной функциональностью. Такая библиотека проверена создателями языка и обладает в значительной степени гарантированной надёжностью, с отсутствием багов.

Проблема третьих лиц


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

Во-вторых, даже если логика в пакете правильная, меня поражает тот факт, что разработчики устанавливают зависимости на однострочные функции, которые сами должны уметь писать с закрытыми глазами. Если ты не можешь написать функцию left-pad, is-positive-integer или isArray за пять минут (включая время на поиск в Google), то ты вообще не умеешь программировать. Чёрт, любая из них может быть хорошим вопросом на собеседовании как проверка, умеет ли кандидат программировать.

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

Что ещё хуже, если в вашем коде или в коде сторонней библиотеки есть баг или код некорректно работает, то вы не будете знать, как отладить или исправить его, если вы не умеете программировать.

Боремся за уменьшение зависимостей


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

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

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

Комментарии 273

    –6
      +4
      Перевод на Хабре
      Small modules: it’s not quite that simple

      Ну и даже в комментариях к самой статье много разумных аргументов.
        +32
        Ситуацию с npm мне всегда хочется проиллюстрировать этой чудесной фотографией:
        image
          0
          А что на этом фото происходит? Хотя бы приблизительно? Кто это? Чем они тут занимаются?
            +4
            Программируют же! Вы разве не видите ноутбук у самого главного?
            • НЛО прилетело и опубликовало эту надпись здесь
                0
                Да, это индийский военный парад, там много разных «фигур высшего пилотажа» было кроме той, что на фотографии. И вишенка на торте: индийцы этот парад еще Обаме с его женой с гордостью демонстрировали, видео гуглится.
                  +2
                  Код, фильмы, парады — во всём чувствуется целостный неповторимый стиль)
                    0
                    Ага, древняя культура, религиозный отпечаток, все такое. :)
                      0
                      Я даже не побоюсь этого слова: «скрепы»!
                    0
                    А ещё есть видео где Обама с какими-то чуваками смотрят парад. Но российский. Так что непонятно, что там на самом деле Обама смотрит
              +13
              Не первый раз натыкаюсь на эту ссылку и вот очень странное всё-таки впечатление от этого комментария на ГитХаб, sindresorhus пишет:
              For example. I have this module negative-zero. Its job is to tell me if a number is -0. Normally you wouldn't have to care about this, but it could happen. How do you figure out if a number is -0. Well easy x === 0 && 1 / x === -Infinity. Or is it? Do you really want to have to know how and why this works?
              Такой вроде риторический вопрос, мы вроде как должны поникнув головой ответить автору «No, it is not, we don't» и пойти дальше добавлять кучу зависимостей в код для каждого чиха. Но во-первых, на самом деле весь модуль действительно выглядит так:
              'use strict';
              module.exports = function (x) {
              return x === 0 && 1 / x === -Infinity;
              };
              А во-вторых очень странно всё-таки не хотеть хотя бы примерно знать как это должно работать, хотя бы одним глазком взглянуть на исходник, особенно если нам намекают, что там творится какая-то магия! И дальше ещё один неудачный, на мой взгляд, пример:
              Another example. Chalk is one of the most popular modules on npm. What you might not realize is that it's actually a collection of modules. It depends on a module for detecting if the terminal supports color, for getting the ansi escape codes, etc.
              Посмотрите на модули, которые используются в Chalk, про которые пишет автор комментария. Да, с одной стороны они довольно просты, но требуют не самых распространённых знаний ANSI кодов для цвета\стиля или того, как определить их поддержку в терминале. Можно ли это сравнивать с toString.call(arr) == '[object Array]'? Моё мнение, что нет, совсем нельзя. И Девид Хейни в оригинальном посте пишет про то, что для сложных вещей имеет смысл использовать модули, а для однострочных сравнений всё-таки нет
                –8
                очень странно всё-таки не хотеть хотя бы примерно знать как это должно работать, хотя бы одним глазком взглянуть на исходник, особенно если нам намекают, что там творится какая-то магия!
                Хочется — взгляните, кто ж вам мешает? Мне, например, не хочется. Мне хочется, чтобы работало и бизнесовая логика быстрее писалась.
                  +4
                  Никто не мешает, понятное дело. Но, цитируя Девида, "stringing APIs together and calling it programming doesn’t make it programming". Ну и вот всё-таки isArray вам действительно бизнесовую логику позволит быстрее писать? Ну вот прямо буквально, что быстрее:
                  сначала в терминал:
                  npm install isarray --save
                  подождали установку
                  потом в ide:
                  const isArray = require('isarray');
                  теперь наконец можем использовать функцию isArray и в нашем проекте появилось теоретически уязвимое место, ура
                  или знаем/загуглили про Array.isArray/[object Array], сразу пишем в коде Array.isArray/[object Array] не тратя время на поиск модуля, установку и объявление? И теперь сборка проекта не сломается, если вдруг этот модуль куда-нибудь денется или автор по ошибке закомитит в него что-нибудь с косяком
                  PS: я дико извиняюсь за этот жуткий вид моих комментариев, маркдаун в "предпросмотре" нормально отображался, но для r&c пользователей видимо никакое форматирование текста не доступно
                    0
                    знаем/загуглили про Array.isArray/[object Array], сразу пишем в коде Array.isArray/[object Array]

                    А где именно вы это пишете? В отдельном файле utils.js? И в следующем проекте вы тоже будете его копипастить? Это как-то не очень здорово, если честно.
                    У меня для таких вещей стоит зависимость от lodash, а у кого-то она будет излишней и зависимость от конкретного isArray будет весьма кстати.
                    P. S. Это же Unix-way в чистом виде.
                      +1
                      Конкретно у меня все подобные утилиты собраны в один модуль в локальном npm и в проект подтягиваются сразу все, а потом rollupjs при билде убирает лишнее. А isArray там просто нет, потому что всё, подо что мне надо писать код уже давно имеет Array.isArray
                      Я понимаю, что "small is beautiful", но должен же быть разумный предел этому, на мой взгляд isArray уже за гранью, на ваш это ок, ну и вот тут мы явно друг друга не переубедим, спасибо за диалог :)
                      +5
                      Ок. В одном проекте написали от руки свой привычный однострочник, повторили его в другом, в третьем, в пятом, в десятом. А в одиннадцатом обнаружили вдруг в этом привычном однострочнике баг. Ваши действия?
                        0
                        Ок. Подключили в зависимость однострочник, использовали его в одном, другом, в третьем, в пятом, в десятом. А в одиннадцатом обнаружили что вдруг в этом привычном однострочнике баг, и автор выпустил новую версию. Ваши действия?
                        Идти обновлять зависимости сопоставимо с обновлением кода этого однострочника. Если разработчик не понимает что он пишет, то проще нагуглить готовое решение, чем городить велосипед. Такому коду место в gist.github.com, но никак не в пакетах.
                        • НЛО прилетело и опубликовало эту надпись здесь
                          +1
                          /весело/
                          Создать новый npm пакет (… богу NPM...)
                            +1
                            Исправить один раз и дополнить юнит-тесты. Тем более он уже много лет как в utils.js или аналоге, если, конечно, это не первый Hello, World! программиста.
                              +1
                              Пишу код, который ищёт все вхождения выражения и заменяет на другое. Многие IDE имееют такую функциональность изкоробки. Пишу жалобный (хабра)пост о мудаках в комитетах стандартизации, которые при переходе на новую версию js поломали обратную совместимость.
                              Примерно такой алгоритм действий был при переходе со второго на третий питон.
                            0
                            Проблема в том, что документация к пакету занимает больше места, чем содержимое пакета. Лучше было бы эту строчку разместить в документации, и пусть все желающие утаскивают её к себе в проект.
                              0
                              Да пусть занимает, на что это влияет?
                                0
                                На время, которое потратит программист, использующий этот пакет. Вы же не будете использовать пакет, не прочитав документации?
                                  0
                                  А что быстрее – прочитать документацию, или написать документацию? Вы же не будете писать свою функцию без документации?
                                    +2
                                    Буду, конечно. Нет нужды комментировать очевидные вещи.
                                      0
                                      Тогда к чему ваш вопрос про документацию?
                                        0
                                        Чтобы использовать пакет, надо прочитать документацию. Потому что если ты всё знаешь о тонкостях js, ты сам напишешь этот кода, а если не знаешь, то должен откуда-то узнать, что есть сложности. То есть что-то прочитать, скорее всего ту самую документацию.
                                        Тогда гораздо проще в документации сразу указать нужный однострочник, чем давать ссылку на установку пакета.
                                          +1
                                          Нет нужды комментировать очевидные вещи.
                                          Чтобы использовать пакет, надо прочитать документацию

                                          Странная логика. Для очевидных вещей документацию писать не надо, но читать надо. Откуда же она будет браться, если её не надо писать?
                                          • НЛО прилетело и опубликовало эту надпись здесь
                                              0
                                              А что не понятного? Если бы мне была эта вещь очевидной, я бы не использовал пакет, а сразу бы писал однострочник. Но если мне нужно откуда-то однострочник позаимствовать, значит я его не знаю. Значит он не очевиден для меня, и мне нужно его читать.
                          +5
                          toString.call(arr) == '[object Array]' — неужели так некрасиво в js определяется тип? Что будет если в будущем поменяется функция преобразования объекта в строку?
                            0
                            В ES5 Array.isArray, поэтому и существуют шимы/полифиллы/мини-модули.
                              +2
                              Возможно это просто костыль, ввиду особенностей поведения typeof:
                              typeof ''
                              «string»
                              typeof []
                              «object»
                              typeof {}
                              «object»

                              toString.call('')
                              "[object String]"
                              toString.call([])
                              "[object Array]"
                              toString.call({})
                              "[object Object]"
                                +3
                                arr instanceof Array. Не?
                                  +1
                                  Да, и это будет быстрее.
                                  Call to function isArray1(obj)
                                  {
                                  return obj instanceof Array;
                                  } took 10.195000000000022 milliseconds.

                                  Call to function isArray2(obj)
                                  {
                                  return (typeof obj == «object»);
                                  } took 12.25 milliseconds.

                                  Call to function isArray3(obj)
                                  {
                                  return Array.isArray(obj);
                                  } took 26.909999999999968 milliseconds.

                                  Call to function isArray4(obj)
                                  {
                                  return toString.call(obj) == '[object Array]';
                                  } took 1597.9850000000001 milliseconds.

                                  Вариант typeof в данном случае реализован не корректно, но тем ни менее.
                                    +2
                                    Функция
                                    function isArray2(obj) {
                                    return (typeof obj == «object»);
                                    }
                                    бесполезна чуть более чем полностью. isArray2({}) //true
                                      0
                                      Я об этом дважды написал выше, да. Но спасибо что ещё раз уточнили, во всех тонкостях JS я не силён.
                                      +1
                                      С фреймами не пройдет. Если необходима универсальная проверка то либо toString() либо isArray(). (
                                        0
                                        Дли тех, кто не понял что имеется в виду или почему не пройдёт (вроде меня), вот в деталях: http://perfectionkills.com/instanceof-considered-harmful-or-how-to-write-a-robust-isarray/
                                        Там еть и некоторые другие странные способы проверить имеем ли мы дело с массивом или нет.
                                        Хотя стоит заметить, что лично мне проще проверить существование необходимых мне в последующем коде методов.
                                          0
                                          После прочтения этого лишь укрепилась вера в убогость языка, где приходится так извращаться ради простых вещей, включая is-positive-integer.
                                          Даже на php это делается проще и логичнее — if ((int) $value == $value && $value > 0)
                                          Банально, padding во многих языках решается через sprintf, но его почему-то в javascript нет.
                                            +1
                                            isArray() работает как надо, не нужно извращаться.
                                            is-positive-integer можно также записать в вашем стиле и на js (parseInt(val) === val && val > 0)
                                            но это не значит что это единственное и главное всеобъемлющее решение.
                                            Безусловно js не лишен проблем, как и любой язык, впринципе, особенно если пытаться использовать его не по назначению.
                                            Но убог? Както через чур, мне кажется.
                                              0
                                              var isPosInt = (val) => val + 0 === val && val > 0
                                                0
                                                Чёрт, забыл, что нужно ещё и на int проверить. :)
                                                var isPosInt = (val) => Math.trunc(val + 0) === val && val > 0
                                                  0
                                                  Bitwise приведение к int: var isPosInt = (x) => (~~x) === x && x > 0
                                                  Есть даже чистый bitwise:
                                                  http://stackoverflow.com/questions/3912375/check-if-a-number-x-is-positive-x0-by-only-using-bitwise-operators-in-c
                                                    0
                                                    Чёрт, это же С и тип заранее задан. Там только проверка на positive, без int. У кого-нибудь есть идеи как сделать чистый bitwise is int на JS? -_-
                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                        0
                                                        И от "&&", и от "===".
                                                          0
                                                          Кстати, вариант без "&&".
                                                          var isPosInt = (x) => x === ~~x & !(~(-1 >>> 1) & (x & -1) | !x)
                                                            0
                                                            Ах да, можно было вот так: var isPosInt = (x) => x === ~~x & !(~(-1 >>> 1) & ~~x | !x)
                                                        0
                                                        Не совсем понимаю что вы хотите, сами же пример привели чуть выше. Если целиком у меня вышло както так:
                                                        var isPosInt = (val) => ~~val === val && !(((val >> 31) << 1) | !val)
                                                          0
                                                          Чистый bitwise подразумевает полное отсутствие каких-либо иных логических операторов. С === и && я и сам могу. :)
                                                          Кстати, alexkunin выше дал более коректное решение для проверки на положительное значение. Оно не привязано к разрядности переменной.
                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                              0
                                                              Ну стандарт-то стандарт, а в реализации могут и начудить. «Волшебные» числа я тоже не люблю.
                                                        0
                                                        isPosInt(2147483648)
                                                        false
                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                            +1
                                                            В JavaScript нет Int32, можно сказать, что есть Int54, и от функции is*Int(eger) ожидаешь проверки именно на Int54. Если ограничиваться Int32, то и именовать нужно соответствующе.
                                                              0
                                                              На счёт именования согласен. Решение не универсальное и тут уже играет роль важна ли нам скорость или работа с большими числами. Ещё стоит заметить, что числа больше Number.MAX_SAFE_INTEGER не целые по-определению.
                                                                0
                                                                Ну так Number.MAX_SAFE_INTEGER и есть "Int54.MaxValue" (в .Net нотации)
                                                                  0
                                                                  Я, кагбэ, и не говорил, что это не оно. Просто более крупные значения в JS представляется в формате double-precision floating-point и тут уже результат проверки скорее зависит от точки зрения. Данные хранятся в не целочисленном формате, но число получается целое так-как дробная часть с такой точностью не влезает и в этот формат.
                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                      0
                                                                      Именно это я и имел в виду, когда сказал, что результат зависит от точки зрения. Значение-то целочисленное получается, хоть и хранится в формате для дробных значений и часть данных теряется просто потому, что их негде хранить. И да, я в курсе, что там есть специальная функция для проверки, только именуется она просто isSafeInteger.
                                                                      Кстати, со строгим ограничением на SafeInteger (и без bitwise, естественно) можно вот так вот:
                                                                      var isSafePositiveInteger = x => Number.isSafeInteger(x) && x > 0;
                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                          0
                                                                          Я думаю для понимания автора модуля достаточно взглянуть на это вот:
                                                                          var MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991
                                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                                              0
                                                                              А разве у isSafeInteger не та же беда? https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger
                                                                              Вот и изобретает велосипеды.
                                                                              Ну и раз сделал isPositiveInteger, то нужно ж было этот велосипед как-то задействовать? Запихивать Number.isSafeInteger?: и, тем более if в isSafePositiveInteger явно не хотелось, а через || этот isSafeInteger всунуть некуда так-как isPositiveIngeter оно не заменит, а для проверки x <= MAX_SAFE_INTEGER будет избыточным.
                                                                              Вот в isPositiveInteger и правда можно (и нужно, наверное) было бы попробовать воспользоваться Number.isInteger если есть в наличии.
                                                                                0
                                                                                Если кратко, то это ES6 :)
                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                    0
                                                    {
                                                    
                                                    const src = [1,2,3,4,5];
                                                    const wrong = { foo: 1 };
                                                    
                                                    const arr1 = it => typeof it[Symbol.iterator] === 'function';
                                                    const arr2 = it => it instanceof Array;
                                                    const arr3 = it => Array.isArray(it);
                                                    const arr4 = it => toString.call(it) == '[object Array]';
                                                    
                                                    Array.prototype.forEach.call([ arr1, arr2, arr3, arr4 ], (f, i) => {
                                                      const fname = `arr${i+1}`;
                                                      console.log(`----- ${fname} -----`);
                                                      console.time(fname);
                                                      const result = f(src);
                                                      console.timeEnd(fname);
                                                      console.assert(result === true);
                                                      console.assert(f(wrong) === false);
                                                    });
                                                    
                                                    }
                                                    /*
                                                    ----- arr1 -----
                                                    arr1: timer started
                                                    arr1: 0.63ms
                                                    ----- arr2 -----
                                                    arr2: timer started
                                                    arr2: 0.55ms
                                                    ----- arr3 -----
                                                    arr3: timer started
                                                    arr3: 0.53ms
                                                    ----- arr4 -----
                                                    arr4: timer started
                                                    arr4: 1.2ms
                                                    */
                                                      +1
                                                      Извините за глупый вопрос, но не могу не переспросить:
                                                      Определение типа таким способом "toString.call(obj) == '[object Array]';" занимает больше 1.5 секунд?
                                                        +1
                                                        Выполнение таким способом проверки сто тысяч раз для обычного массива, ассоциативного массива и строки займёт полторы секунды на моём ноутбуке в хроме какой то версии близкой к последней стабильной.
                                                      +2
                                                      Этот вариант не сработает, если массив был создан в другой глобальной области видимости.
                                                        –1
                                                        typeof obj[Symbol.iterator] === 'function'
                                                          0
                                                          Для строки так же вернёт true, но можно объединить с typeof obj == "object".
                                                          0
                                                          это работает не всегда — если, скажем, массив создан в web-worker'e, то это дело вернёт false.
                                                            0
                                                            Сколь я помню, это не гарантирует истинности. Если arr пришел из другого окна например, то будет false.
                                                          +2
                                                          Типы — это давняя боль. В первой версии языка вообще не было массивов (поэтому arguments — не массив), их эмулировали с помощью объектов с ключами 0..n. Отсюда все эти ноги растут. А еще вот такое счастье: typeof null === 'object'.
                                                          Ну а вообще в 2016 есть Array.isArray. В крайнем случае, для легаси окружений, можно и полифилл поставить.
                                                            –4
                                                            А если так?
                                                            return !![].forEach(или любая другая функция, имеющаяся только у массива)
                                                              +1
                                                              Это очень странная и неочевидная конструкция, которая сильно ухудшает читаемость кода. Поэтому такие штуки выносят в или библиотеки или отдельные пакеты.
                                                              –2
                                                              (нервно) хахаха. Как вы далеки от этого криволикого языка...
                                                              –2
                                                              Ну, прям крайность GNU ) Вырожденная модульность, чтобы в любой момент пользователь мог заменить зависимую библиотеку на более любимую)
                                                                +20
                                                                Ну а вообще проблема в бедной стандартной библиотеке. Вместо того, чтобы починить, например, Date и принять String#padLeft и прочее, что можно легко заполифиллить и снять эти идиотские проблемы, TC39 занимается… чем-то другим.
                                                                  +1
                                                                  Им уже предлогают String.prototype.padStart и String.prototype.padEnd: github.com/tc39/proposal-string-pad-start-end
                                                                    +4
                                                                    Предложено было уже давно, в ES2015 и 16 не попало. Поэтому я и сказал, что занимаются невесть чем вместо вещей которые нужны каждый день.
                                                                  +5
                                                                  Мне кажется, что подобное(втягивание пустяковых зависимостей) происходит в первую очередь из-за того, что кодерам не до перфекционизма. Цель — выкатить решение.
                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                      +5
                                                                      Так это ж три этапа развития разработчика (на правах полу-шутки):
                                                                      1) Копипастишь.
                                                                      2) Не копипастишь, а переиспользуешь.
                                                                      3) Понимаешь, когда копипастить можно, а когда не нужно.
                                                                      Много разработчиков остаются на втором уровне понимания (отчасти, я думаю, из-за перфекционизма, типа модули, переиспользование кода, красота же).
                                                                      +1
                                                                      Именно, когда (возможно этого и не случится) вдруг бизнес повернет на курс создания надёжных, продуманных продуктов то ситуация сама собой исправится. Сейчас все гоянятся как на скачках не понятно куда.
                                                                      0
                                                                      Чистить зависимости вручную, то еще удовольствие, особенно когда их набирается с десяток. Выход, нужен инструмент для выявления неиспользуемых зависимостей, иначе эта куча будет только расти.
                                                                        +1
                                                                        https://github.com/dylang/npm-check Весьма неплохо справляется.
                                                                        Есть еще https://github.com/depcheck/depcheck но мне лично он нравится меньше.
                                                                          0
                                                                          1. Спасибо за ссылку, обязательно проверю.
                                                                          2. Ну тогда осталось только чтобы npm запускал проверку перед публикацией и не разрешал публиковать "загрязненные" пакеты
                                                                        +5
                                                                        Нет ничего плохого в маленьких модулях, в модулях из 1 строки и даже из 0 строк (модуль без кода, представляет собой коллекцию полезных зависимостей, например). Это очень хорошо, что люди используют проверенные решения даже для примитивных задач, потому как есть немало шансов, что даже модуль из трёх строк спасет программистов от багов, возможныз при самописной реализации той же проверки на массив, встречающихся в очень редких ситуациях, т.к. "у меня же работает!".
                                                                        Плохо в npm и во всей этой экосистеме с фреймворками друг на друге это их огромнейшая раздутость, 28000 файлов, вот это вот всё. Реально нужный и используемый код из всего этого — это доли процентов чаще всего. Но кому до этого есть дело, в смартфонах уже по 8 ядер, анимация почти не тормозит!)
                                                                          +17
                                                                          >люди используют проверенные решения даже для примитивных задач

                                                                          к сожалению, большинство npm-модулей отнюдь не проверенные решения.
                                                                            +12
                                                                            Именно так. Приведённая функция leftpad крайне неоптимальна: она имеет сложность O(N^2). Но на это обратили внимание только сейчас, когда поднялась шумиха:
                                                                            github.com/azer/left-pad/issues/15
                                                                            То есть автор написал функцию для своих нужд. Возможно, ему требовалось быстрое и надёжное решение для строк небольшой длины, а оптимизацию для длинных строк он решил оставить на потом, о чём благополучно забыл. А другие взяли и стали его функцию использовать, не особо вникая в то, как эта функция работает.
                                                                              0
                                                                              И это аргумент, почему лучше использовать готовый модуль, а не самописную функцию (или, вообще копипаст).
                                                                              Вот смотрите:
                                                                              1. Народ обратил внимание на то, что сложность O(N^2).
                                                                              2. Грамотный чувак сделал из неё оптимизированную O(N) и бросил пулл-реквест.
                                                                              3. Автор принял пулл-реквест и обновил репозиторий.
                                                                              4. С этого момента миллионы чуваков делают npm update (или как там) и у них код начинает работать быстрее и эффективнее, без усилий и рефакторинга с их стороны. И пролетают те, кто вместо использования готового лепит велосипеды и забивает на них. Тут можно возразить, что без тестов может что-то поломаться. Ну те, кто не пишут тесты на свой код — ССЗБ.

                                                                              Вся мощь модулей в том, что вы можете отдать части логики на опенсорс-аутсорс, где она дотачивается и оптимизируется. И иметь возможность быстро обновиться до актуальных версий. Чего не скажешь о самопале, глубоко зарытом в коде проекта. Даже маленьких модулей, которые вынуждены покрывать крайнюю нищету и скудость стандартной библиотеки. Непонятно, чем занимаются авторы ES-стандартов, если такие нужные каждый день в быту однострочные вещи приходится подтягивать из npm-репы.
                                                                                +8
                                                                                Народ обратил внимание на это только после привлечения внимания к этому модулю. Из-за чего у меня сразу возникают вопросы:
                                                                                1. Что мешало грамотному чуваку это сделать на год-два раньше?
                                                                                2. Почему все бездумно используют модули, но не смотрят, что у них находится под капотом?
                                                                                3. Почему принято считать, что велосипед всегда будет хуже, чем ранее написанный код? Кстати, в велосипеде проблемы нет: ведь тесты-то уже написаны!
                                                                                4. Что делать, если автор умер и не больше не поддерживает свои библиотеки?
                                                                                  0
                                                                                  Ну а к самописной функции вообще никогда внимание бы не обратилось.
                                                                                  1. ровно то же, что может помешать разработчику велосипеда увидеть более оптимальное решение
                                                                                  2. потому что, по-идее, для обычного использования достаточно смотреть документацию. Вот когда вопрос стоит в оптимизации/дебаггинге – тогда да, без ковыряния в коде не обойтись (если затык в конкретном модуле).
                                                                                  3. потому что "ранее написанный код" уже работает и так или иначе проверен, а велосипед – нет. Вместо написания велосипеда лучше обновить "ранее написанный код" (пулл-реквесты и т.д.)
                                                                                  4. форк сделать, например. В чём проблема?
                                                                                    +2
                                                                                    Есть люди, которые занимаются написанием, вылизыванием и поддержкой стандартных библиотек. Это их основная задача. Их код можно и нужно использовать.
                                                                                    А когда дело касается модулей, которые представляют из себя точно такие же самописные велосипеды, только выложенные в репозиторий, в качестве кода возникают сомнения. Но всегда находятся программисты, которые считают, что пусть и плохой, но выложенный в репозиторий код — это благо.
                                                                                    1. Автор модуля пулл-реквест может не принять или принять не сразу, а изменения нужно внести прямо сейчас, что делать?
                                                                                    2. Проблема в том, что миллионам разработчиков придётся переправлять зависимости на новый форк.
                                                                                    0
                                                                                    Что мешало грамотному чуваку это сделать на год-два раньше?
                                                                                    А зачем?
                                                                                    Почему все бездумно используют модули, но не смотрят, что у них находится под капотом?
                                                                                    Потому что люди так устроены. Они не роботы и не хотят делать то, чего можно не делать.
                                                                                    Почему принято считать, что велосипед всегда будет хуже, чем ранее написанный код?
                                                                                    Потому что велосипед нужно написать, очевидно же.
                                                                                    +9
                                                                                    Суть в том, что пункт 1 произошел, в общем-то, случайно. У сотен и тысяч подобных модулей (а у более сложных — так тем более) это не случится никогда.
                                                                                      0
                                                                                      Неправда. Если это действительно такое тормозное и отъедающее много времени место, то первый же сеанс профилирования покажет, что именно в этом месте алгоритм надо оптимизировать, и при достаточной чистоплотности — выложить в open source форк/pull request.
                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                          0
                                                                                          Обычно да, так всё и происходит. :) Неоптимальный код заливают баблом на железо. Но это бывате только там, где что железо дешевле времени разработчика. Если было бы наоборот — сидели бы все безвылазно в профайлерах. :)

                                                                                          Ну и если совсем уж всё плохо и пара часов времени разработчика дешевле двух сотен серваков для хайлоад-проекта — то запустят-таки и исправят. Вон, фейсбук и вконтакт дальше пошли — то компилируемый PHP изобретут, то из этого PHP всё тормозящее ООП повыкидывают, то на C++ с ассемблерными вставками перепишут критичные сервисы.
                                                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                                                          0
                                                                                          Конкретный практический пример показал, что не случился ни у кого "первый же сеанс профилирования". А если и случился, то скорее всего, никто не стал заморачиватся доработками и пулл-реквестами, а просто нашел что-то другое.
                                                                                      0
                                                                                      Да, но бонус в том, что если в этой библиотеке починят и оптимизируют — вы тоже будете в выигрыше, если обновитесь.
                                                                                        –3
                                                                                        На самом деле, там O(N) и предложено решение O(log(N)).
                                                                                      +3
                                                                                      > потому как есть немало шансов, что даже модуль из трёх строк спасет программистов от багов,
                                                                                      > возможныз при самописной реализации той же проверки на массив,
                                                                                      Точно так же есть немало шансов (мне сдаётся, что их там даже больше), что найденный по потребности и добавленный в зависимости модуль — это нифига не проверенное решение, и имеет свои подводные камни, фичи и баги. Как по мне, если кусок кода тривиален и прост, его нужно иметь в своём решении, а не тянуть как зависимость. По крайней мере, скопировать, а не переписать с нуля, раз уж он такой хороший.
                                                                                        –2
                                                                                        То, что используют миллион программистов всяко более оттестированно, чем то, что вы напишете сами.
                                                                                          +1
                                                                                          … и любая проблема, сознательно или несознательно вносимая автором, сразу ломает миллион проектов.
                                                                                            –1
                                                                                            Зафиксируйте версию и обновляйтесь только по мере надобности. Зависимости вида * или 1.* или ^1.2 — это все дурной тон.
                                                                                            +3
                                                                                            Я бы не был настолько уверен насчёт качества тестов. Программист написал какие-то тесты и забыл. А миллионы программистов смотрят на модуль: код есть, тесты есть, можно пользоваться.
                                                                                              0
                                                                                              Если их миллион — раз не жалуются и не заводят баги, то велика вероятность, что все окей. Миллионы мух не могут ошибаться ;)
                                                                                        +7
                                                                                        Напомню про платную программу под ms-dos, состоявшую из 0 байт и позволявшую быстро запустить предыдущую запущенную программу (трюк состоял в том, что вызывался предыдущий загруженный в память код).
                                                                                        Вопрос не в размере кода, а его продуманности и удобстве. Переиспользование кода — благо.
                                                                                          +10
                                                                                          Уточнение интересующимся про программу: https://habrahabr.ru/post/147075/
                                                                                            0
                                                                                            Да, спасибо, не мог найти.
                                                                                            +2
                                                                                            Переиспользование кода — благо

                                                                                            С некоторыми уточнениями:
                                                                                            1. В общий код легко добавлять новые вещи, очень тяжело менять существующие и совсем тяжело, что то удалять. Что бы обеспечивать обратную совместимость, этот код обычно замусоривается.
                                                                                            2. Любое изменение в коде, даже баг фикс требует регрессионное тестирование в коде, который переиспользует этот общий код. Почему? потому что даже если это баг, возможно, что бы его обойти, пристроили костыль и теперь, без бага, этот код не будет работать корректно.
                                                                                              Конкретный пример из npm, есть проект который использует angular2 и для него нужно поставить еще несколько пакетов, у всех пакетов стояла версия с префиксом ^ (версия такая то или совместимая) после npm update апликация перестала работать, выдавая странные ошибки, пришлось вручную перебирать версии, пока не нашли работающую комбинацию.
                                                                                              +1
                                                                                              "переиспользование кода" должно иметь разумную границу.
                                                                                              Не вчитывался в каждый комментарий тут, но вроде только в одной ветви люди задались вопросом — почему такие элементарные и настолько массово используемые вещи, не внесены в стандартную библиотеку до сих пор?
                                                                                                0
                                                                                                Стандартная библиотека в данном случае — тянущаяся с собой каждый раз или встроенная в браузер?
                                                                                                Если первое — тут я тоже не понимаю, что мешает.
                                                                                                Если второе — ну, у каждого разработчика браузеров будет своё видение "стандартной библиотеки", пока они согласуют свои представления, пока заимплементят, пока вся юзер-база перейдёт на версии, которые имеют в себе эту самую библиотеку...
                                                                                                  +1
                                                                                                  "с собой или в браузере" — не знаю. Не настолько глубоко погружен в JS, что бы даже версию выдвинуть.
                                                                                                  Но очевидно, что наиболее популярные вещи не должны оставаться "независимым пакетом", и кто-то, кто близок к разработке стандарта языка, должен следить и за содержимым стандартной библиотеки, втягивать их "внутрь", покрывать тестами, оптимизировать и так далее. От этого прямо зависит популярность и удобство инструмента.
                                                                                                  Что там у нас сейчас самое популярное — java? Сколько сил вложено в стандартную библиотеку и в наиболее популярные библиотеки/фреймворки? Следующее C++? Тоже не нужно искать примеры, насколько лучше, когда язык и стандартная библиотека идут за потребностями разработчиков.
                                                                                                    +1
                                                                                                    Но очевидно, что наиболее популярные вещи не должны оставаться «независимым пакетом», и кто-то, кто близок к разработке стандарта языка, должен следить и за содержимым стандартной библиотеки, втягивать их «внутрь», покрывать тестами, оптимизировать и так далее. От этого прямо зависит популярность и удобство инструмента.
                                                                                                    Они как раз начали этим заниматься и теперь довольно плодотворны на обновления языка.

                                                                                                    Что там у нас сейчас самое популярное — java?
                                                                                                    JavaScript
                                                                                              +11
                                                                                              Фам Нювен несколько лет провел, обучаясь программировать и исследовать. Программирование восходило к началу времен. Как та навозная куча за замком отца. Когда ее промыло ручьем на десять метров в глубь, обнаружились искореженные корпуса машин – летающих машин, как говорили крестьяне, еще от тех великих дней колонизации Канберры. Но та навозная куча была чистой и свежей по сравнению с тем, что лежало в локальной сети «Репризы». Были программы, написанные пять тысяч лет назад, когда человечество еще не покинуло Землю. И самое чудесное (самое ужасное, как говорила Сура) было то, что, в отличие от бесполезных обломков прошлого Канберры, эти программы все еще работали! И через миллион миллионов запутанных нитей наследования многие из старейших программ все еще выполнялись во внутренностях системы Кенг Хо. Например, методы слежения за временем у торговцев. Поправки вносились неимоверно сложно – но на самом дне лежала крошечная программа, которая гоняла счетчик. Секунду за секундой отсчитывала система Кенг Хо с того момента, как нога человек ступила на Луну Старой Земли. Но если приглядеться еще пристальнее… начальный момент был миллионов на сотню секунд позже; момент «ноль» одной из первых компьютерных операционных систем Человечества.

                                                                                              // Виндж, «Глубина в небе».
                                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                  +9
                                                                                                  >> мы разучились программировать?
                                                                                                  >> return toString.call(arr) == '[object Array]';
                                                                                                  Скорее, не научились программировать на JS. Конкретный пример — исключительно фактологическое знание, не фундаментальное.
                                                                                                    +13
                                                                                                    Напоминает http://youmightnotneedjquery.com/, где предлагают заменить
                                                                                                    $.getJSON('/my/url', function(data) {});

                                                                                                    на
                                                                                                    var request = new XMLHttpRequest();
                                                                                                    request.open('GET', '/my/url', true);
                                                                                                    
                                                                                                    request.onload = function() {
                                                                                                      if (request.status >= 200 && request.status < 400) {
                                                                                                        // Success!
                                                                                                        var data = JSON.parse(request.responseText);
                                                                                                      } else {
                                                                                                        // We reached our target server, but it returned an error
                                                                                                    
                                                                                                      }
                                                                                                    };
                                                                                                    
                                                                                                    request.onerror = function() {
                                                                                                      // There was a connection error of some sort
                                                                                                    };
                                                                                                    
                                                                                                    request.send();

                                                                                                    или
                                                                                                    
                                                                                                    $(el).fadeIn();

                                                                                                    на
                                                                                                    function fadeIn(el) {
                                                                                                      el.style.opacity = 0;
                                                                                                    
                                                                                                      var last = +new Date();
                                                                                                      var tick = function() {
                                                                                                        el.style.opacity = +el.style.opacity + (new Date() - last) / 400;
                                                                                                        last = +new Date();
                                                                                                    
                                                                                                        if (+el.style.opacity < 1) {
                                                                                                          (window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
                                                                                                        }
                                                                                                      };
                                                                                                    
                                                                                                      tick();
                                                                                                    }
                                                                                                    
                                                                                                    fadeIn(el);

                                                                                                    То бишь я сажусь писать новый проект и пишу 10000 строк кода с хелперами потому что умею прогать, зашибись.
                                                                                                      +1
                                                                                                      Думается приведенные в статье примеры скорей нужно если и вендорить то путем копирования кода под реп.
                                                                                                        +2
                                                                                                        Вот конкретно данный функционал нет смысла писать самому, так как эти функции не являеются отдельными зависимостями, но частью одного целого.
                                                                                                          +1
                                                                                                          Т.е. если на все приложение нужно сделать в 3 местах запросы на получение JSON, то правильнее будет загружать jQuery?
                                                                                                            +4
                                                                                                            Ну, если ваше время и время тех, кто это будет потом поддерживать, бесконечно, то — нет, не правильнее.
                                                                                                            Если это одноразовое приложение, у которого не будет поддержки по каким-либо причинам, то тоже — нет, не правильнее.
                                                                                                            В остальных случаях — да, правильнее загрузить jQuery.
                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                +1
                                                                                                                А где граница между чужим проверенным кодом, который точно будет лучше (быстрее и/или надежнее) чем свой, и кодом непонятно откуда взятых NPM модулей с зависимостями от других непонятных модулей?

                                                                                                                Она ведь у каждого своя? И основана на собственном опыте/умениях/целях?

                                                                                                                По ссылке выше прямо в адресе сказано «вы _можете_ обойтись без». :)
                                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                  0
                                                                                                                  А не лучше тогда уже 1 раз написать код, который будет выдёргивать из необходимых вам либ реально используемый вами код и выгружать это всё дело в какой-нибудь deps.min.js? Многие и так держат у себя локальную копию того же jQuery, так что следить за обовлениями локальных копий не должно составить труда.
                                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                      0
                                                                                                                      Догадываюсь, видимо потому живых примеров такого ещё ни разу не видел. Хотя мне это кажется вполне реалистичным (если все забудут о существовании "eval").
                                                                                                                      А вот дёргать отдельные модули идея действительно здравая.
                                                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                      0
                                                                                                                      https://developers.google.com/closure/compiler/ — уже проделано до нас. Скажем спасибо корпорации зла.
                                                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                          0
                                                                                                                          Разумеется, в документации указаны требования к стилю кодинга, соблюдение которого гарантирует безопасность преобразований. ИЧСХ, эти требования очень часто соблюдаются, если js код генерирует не человек, а транслятор из программы, написанной на другом языке программирования.
                                                                                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                            0
                                                                                                                            Доброго времени суток
                                                                                                                            Использую Closure Compiler как корректор, иногда полезно :)

                                                                                                                            А корекцию вашего примера я понимаю так.
                                                                                                                            Переменные локальны и в именах нет особой необходимости он и сделал их анонимными.

                                                                                                                            Если хотите оставить имена используйте, --compilation_level=SIMPLE, правда и коррекция будет послабей.

                                                                                                                            Имена переменным, еще до Closure, давал a, b и т.д.
                                                                                                                            • слишком много времени уходит, на подбор лаконичного имени,
                                                                                                                            • после оптимизации или тестирования, часть их вовсе не нужны.
                                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                0
                                                                                                                                Содержимое
                                                                                                                                не являющиеся элементами цикла
                                                                                                                                — пример можно о таком не слышал
                                                                                                                                Не массив, объект

                                                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                  0
                                                                                                                                  Содержимое
                                                                                                                                  Так это, привычка?
                                                                                                                                  От вредных привычек можно избавляться, если счетчик задается задолго до цикла например: параметром функции, или в другом цикле?
                                                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                      0
                                                                                                                                      Содержимое
                                                                                                                                      Простите но вы не ответили, на вопрос.
                                                                                                                                      но однобуквенные переменные, не являющиеся элементами цикла, вам не удастся протащить через линтер

                                                                                                                                      — пример можно о таком не слышал

                                                                                                                                      Иначе мы просто повторим комментарии к вашим публикациям с тем же нулевым результатом.

                                                                                                                                      Я думал мы обсуждаем, Google® Closure Compiler, а не переходим на личности, или у Вас есть аргументы по поводу
                                                                                                                                      с тем же нулевым результатом

                                                                                                                                      Тогда лучше в приват.
                                                                                                                                      • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                    0
                                                                                                                                    Содержимое
                                                                                                                                    Вот эти вот «параметром функции» и «в другом цикле» — это признаки «кода с душком».

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

                                                                                                                                    Если я плыву против течения, это не значит что я не прав, может мне просто нужно в другую сторону
                                                                                                                                    А Google® Closure может потому у меня не вызывает вопросы, что умею читать переменные по разному если нужно и без привязки.
                                                                                                                                    На личности я не переходил. До меня уже перешли, вроде, а я сразу открестился от дальнейшего обсуждения

                                                                                                                                    Грубить даже не пытался, поправил, насчет массива? Но и я мог описаться и не раз.

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

                                                                                                                                    Думаю, что ответил на ваш вопрос о Closure.

                                                                                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                        0
                                                                                                                                        Содержимое
                                                                                                                                        Спасибо, за предложение, обращусь.
                                                                                                                                        Насчет моего мнения о ваших комментариях, это вы зря, как еще проще узнать, если не спросить, я и сам такой и за приглашение в личку спасибо, но уже поздно, хотя я и на работе.
                                                                                                                                        Спасибо, было приятно пообщаться.
                                                                                                                                0
                                                                                                                                А я-то гадал чем они генерируют свои адовы скрипты для GMail и всего остального.
                                                                                                                      0
                                                                                                                      Тссс, строго между нами
                                                                                                                      $.getJSON('/my/url', function(data) {});
                                                                                                                      уже можно заменить на
                                                                                                                      fetch('/my/url').then(function (response) {});
                                                                                                                        0
                                                                                                                        fetch ещё не вошёл ни в один стандарт ecmascript
                                                                                                                          –1
                                                                                                                          И не войдёт, он часть стандарта HTML
                                                                                                                          https://fetch.spec.whatwg.org/
                                                                                                                            0
                                                                                                                            Хм, стандарт html это в смысле стандарт DOM API?

                                                                                                                            И может это для кого-то элементарно, но всё же: по ссылке https://fetch.spec.whatwg.org указано что это «living standard».
                                                                                                                            Что это вообще значит? Означает ли это что стандарт ещё не стабильный в будущем в нём могут произойти изменения ломающий обратную совместимость?
                                                                                                                              0
                                                                                                                                0
                                                                                                                                Это значит что WhatWG — это не W3C и они немного иначе относятся к тому что есть стандарт.
                                                                                                                            +1
                                                                                                                            Согласно MDN IE и Safari пока не поддерживают
                                                                                                                            Скрин оттуда
                                                                                                                            IE и Safari пока не поддерживают fetch
                                                                                                                            +1
                                                                                                                            Тссс, ещё нельзя. Ах да, в полифил нельзя, иначе ты "типа разучился программировать и лах" ©.
                                                                                                                          +3
                                                                                                                          Вполне закономерная ситуация, и проблеме не в npm, сотнях однострочных модулях и зависимостях, а в том, что у js очень бедная стандартная библиотека, люди начали решать ее отсутствие такими вот костылями чтобы не писать в каждом проекте isArray вручную, в конечном счете как это обычно и бывает, костыль поднялся и ударил людей по лбу.
                                                                                                                            +2
                                                                                                                            Мне кажется, что вся работа программиста в экосистеме NPM сводится к написанию как можно меньшего количества кода, чтобы связать вместе существующие библиотеки, чтобы создать нечто новое, функционирующее уникальным образом для личных или коммерческих нужд.
                                                                                                                            А разве это не цель, для которой пишутся программы? Не Ваша цель, как программиста, а цель написания программы?
                                                                                                                              +1
                                                                                                                              Честно говоря, я именно так и пишу программы. И пару лет назад писал о том, что современному программисту для выполнения типичных задач достаточно взять какой-нибудь фреймворк и связать несколько вещей между собой, за что меня побили.
                                                                                                                              • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                0
                                                                                                                                Мы не разучились программировать, просто сейчас программирование выглядит именно так, что ты должен выпустить продукт как можно быстрее. Поэтому моя работа скатилась из программиста в собирателя модулей, это нормально сейчас на js проектах, устанавливаешь bower/npm пакет, и просто вставляешь его, своего кода в проекте 20%-30% и то половина этого это в целом работа с пакетами. В целом я уже забыл когда я хотя бы часов 5 программировал, а не имплементил пакеты. Что грусно.
                                                                                                                                  +1
                                                                                                                                  Ситуацию бы исправили более-менее вменяемые библиотеки наиболее востребованных функций. Чтото вроде Glibc (из linux) или stdlib…
                                                                                                                                    0
                                                                                                                                    Они есть, но никому не нужны, т.к. всем важен размер яваскрипта. Сильно влияет на юзабилити сайта.
                                                                                                                                    Что действительно нужно яваскрипту — так это оптимизирующий минификатор, способный выкидывать неиспользующийся код. Вопрос в том, как это сделать в таком языке, как яваскрипт...
                                                                                                                                      0
                                                                                                                                      Внешняя утилита? Или как часть статического анализатора кода (Который тож будет не лишним).
                                                                                                                                        0
                                                                                                                                        Как-то компилятор/линковщик умудряется вставлять в окончательный бинарник прошивки для микроконтроллера не вообще всю библиотеку, а только реально используемые функции. Это что, принципиально невозможно в JS?
                                                                                                                                          +3
                                                                                                                                          Малость мешает отсутствие статической строгой типизации. Никогда нельзя точно сказать, что реально используется, а что нет.
                                                                                                                                            0
                                                                                                                                            Именно! Приведу очень простой пример:
                                                                                                                                            if (false){
                                                                                                                                            var x = 0;
                                                                                                                                            }

                                                                                                                                            «x» in window; // true
                                                                                                                                            Вот, есть ветка которая вообще никогда не выполнится, так как проверяется литеральная константа. Если мы её выпилим, то получим в выражении снизу уже не «true», а «false»!
                                                                                                                                              +1
                                                                                                                                              Это неправильный пример, все var переносятся в начало функции независимо от места объявления.
                                                                                                                                               
                                                                                                                                              Главные враги статического анализа — eval и конструкции вроде
                                                                                                                                              library['fun'+'ction']()
                                                                                                                                              

                                                                                                                                          0
                                                                                                                                          C ES-модулями это возможно. Погуглите rollup и tree-shaking.
                                                                                                                                          +1
                                                                                                                                          Уже есть Underscore и Lodash
                                                                                                                                          +7
                                                                                                                                          Мне кажется, проблема с маленькими модулями в том, что никогда не знаешь, как они поведут себя друг с другом и в каком стиле они вообще сделаны. Что будет, если вместо входной строки подать undefined? Или null? Будет ли исключение или молча превратится в "undefined"/"null"? Вы взяли left-pad и привыкли к одному поведению. Завтра вам понадобится right-pad, а его написал другой человек, у которого другие представления о граничных случаях. И ещё окажется, что порядок аргументов другой. Другое дело, если есть какой-нибудь string-utils, где сто функций с общим стилем, где всегда знаешь, как библиотека отреагирует на нетривиальный ввод и даже используя функцию первый раз можешь предположить, в каком порядке передавать параметры.
                                                                                                                                          Ещё важный момент — это тестирование. В нашем воображаемом string-utils все функции покрыты тестами и нормально совместимы друг с другом: вывод одной можно подать на вход другой без всякого нежданчика. А если что-то случится, то фиксать будет одна команда разработчиков. А не так, что «совместимость с чужим пакетом пусть обеспечивают они, а не я».
                                                                                                                                            +2
                                                                                                                                            А потом конечный JS бандл раздуется до 10 мб.
                                                                                                                                              0
                                                                                                                                              А делов-то: нужно всего-навсего написать программу, которая будет выбрасывать неиспользуемый код, как это делают линкеры компилируемых языков.
                                                                                                                                              Но, боюсь, для JS это будет совсем нереально из-за особенностей саомго языка.
                                                                                                                                                0
                                                                                                                                                webpack --optimize-minimize

                                                                                                                                                Вам в помощь
                                                                                                                                                  0
                                                                                                                                                  Достаточно использовать микромодульный подход к написанию библиотек. Тогда в пакет включаются исключительно те микромодули, что реально необходимы. При этом размер самой библиотеки может быть сколь угодно большим.
                                                                                                                                                  0
                                                                                                                                                  Да ладно! Пять лет назад никого не беспокоило подклеить к проекту весь jQuery ради какой-нибудь одной шняги типа $(".blahblah").height("100%"). Теперь каналы стали меньше? Вы таки уверены, что в собранном бандле каждая строчка вам приносит пользу и строго необходима?
                                                                                                                                                  Опять же если остро стоит такой вопрос, можно делать зонтичные проекты. Типа string-utils — это список зависимостей на string-utils-core, string-utils-regex, string-utils-formatting и т. д. Не надо всё — укажите, что конкретно надо. Суть в том, что всё под одним именем, пишется одной командой в одном стиле и тестируется вместе.
                                                                                                                                                +6
                                                                                                                                                Странно, что у автора этой заметки, ведущего инженера Stack Overflow, нет претензий к дичайшему гавнокоду в указанном "ключевом модуле" и что никто до сих пор его не выправил. Делать в цикле конкатенации по количеству необходимых символов с генерацией каждый раз нового String объекта на каждой итерации вместо "return ch.repeat(len — str.length) + str" — это какой-то эпикфейл.
                                                                                                                                                  +1
                                                                                                                                                  String.prototype.repeat() поддерживается только в ES6+
                                                                                                                                                    0
                                                                                                                                                    Можно и без String#repeat сделать более оптимально.
                                                                                                                                                      +3
                                                                                                                                                      Да, Вы правы. Тогда push в массив и join. Но никак не тот лютый трындец в сырце.
                                                                                                                                                        +2
                                                                                                                                                        Вот тут уже подсуетились — https://github.com/azer/left-pad/pull/11
                                                                                                                                                        В волшебной стране javascript даже join тормозит, на самом деле.
                                                                                                                                                          +2
                                                                                                                                                          Ух жесть. Битовый сдвиг и конкатенация строки на себя же чтобы немного уменьшить алгоритмическую сложность и нагрузку на GC, но оставив по-сути проблему треша на своём месте… Мир JS жесток и беспощаден. )))
                                                                                                                                                            +1
                                                                                                                                                            Никто не говорил, что фронтенд — это легко.
                                                                                                                                                              +1
                                                                                                                                                              Если бы только фронтэнд, а то ведь его же везде пытаются пропихнуть
                                                                                                                                                            0
                                                                                                                                                            Я тут побенчмаркал слегка (clickable):

                                                                                                                                                      0
                                                                                                                                                      Ладно ещё когда пользуются left-pad, это можно понять, и велосипеды строить действительно не надо. Больше раздражает, когда собирают пакет, вкомпилировав туда кучу полифиллов, например, node.js Buffer, любезно подставляемый вебпаком, в результате чего пакет становится размером 50-100кб, хотя можно было бы всё сделать тремя строчками кода.
                                                                                                                                                        +9
                                                                                                                                                        вместо того чтобы потратить 2 минуты и написать эту базовую функцию самому
                                                                                                                                                        Если бы я занимался переписыванием базовых функций, на основную работу времени бы не оставалось.
                                                                                                                                                        Плюс этим пришлось бы заниматься каждому разработчику, вместо использования уже готового решения.
                                                                                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                                            +3
                                                                                                                                                            результат стратегии NPM по решению проблемы dependency hell — каждому модулю своя копия всех зависимостей, нужной версии. (ничего ж не путаю? оно так устроено?)
                                                                                                                                                            Нет, ужé не «копия всех зависимостей»: npm, начиная с третьей версии, складывает все зависимости в кучу в подкаталог node_modules первого уровня до тех пор, пока два модуля не потребуют одну и ту же зависимость разных версий (и тогда она, и только она, достанется каждому такому модулю в виде своей копии нужной версии). Экономия.
                                                                                                                                                              +1
                                                                                                                                                              А если 3 модуля хотят зависимость одной версии, а еще 3 — другой. Данная зависимость будет в 2х или в 6и копиях?
                                                                                                                                                                +1
                                                                                                                                                                Выходит что в 4х, так что всё равно плохо.
                                                                                                                                                            0
                                                                                                                                                            Объясните пожалуйста, где можно применить модуль leftpad и для каких задач он вобще нужен? Что-то нигде не нашёл...
                                                                                                                                                            • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                                                0
                                                                                                                                                                Спасибо) Как-то даже не подумал в таком ключе...
                                                                                                                                                                • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                                                    0
                                                                                                                                                                    А никакого аналога sprintf() там тоже нет что ли? А то sprintf(target, "INV-%07i", inv_no).
                                                                                                                                                                    • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                                                      +1
                                                                                                                                                                      Ну в статье правильно говорится — лучше подумать головой. Задача очень простая для нормального программиста.
                                                                                                                                                                0
                                                                                                                                                                Правда где-то посередине.
                                                                                                                                                                  +5
                                                                                                                                                                  Нет, микромодули это замечательно. Пусть в модуле будет всего одна строка, но
                                                                                                                                                                  — эта строка не дублируется в каждом проекте
                                                                                                                                                                  — эта строка просматривается бòльшим числом глаз чем она просматривалась бы в одном проекте
                                                                                                                                                                  — эта строка имеет меньшую вероятность внести ошибку в проект нежели написанная с нуля, особенно неискушённым разработчиком
                                                                                                                                                                  — при нахождении бага в этой строке он будет исправлен сразу во всех проектах, использующих модуль
                                                                                                                                                                  Кроме того, не надо забывать что эта строка вполне может развиться в сотню.

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

                                                                                                                                                                  Проблема npm и других новомодных пакетных менеджеров в другом — зависимости никак не верифицируются, а зачастую даже не фиксируются по версиям. В лучшем случае любое обновление или новая установка может всё сломать (что и было успешно продемонстрировано, хотя на деле происходит постоянно), а если задуматься то по npm|pip|bower|cargo|… прилетает вообще неизвестно что — код может быть подменён в любой точке от автора до последней мили и вы об этом не узнаете, нет никакой возможности убедиться что сейчас прилетело то же что неделю назад, или вам прилетело то же что и Васе. Или Пете, который провёл аудит кода. И постфактум, когда катастрофа уже случилась, концов не найти.
                                                                                                                                                                    0
                                                                                                                                                                    Резюме: микромодули помогают избавиться от включения неиспользуемого кода в JavaScript, тем самым уменьшив размер файла. Но иногда это может привести к проблемам.
                                                                                                                                                                      0
                                                                                                                                                                      Контр-резюме: Любое решение иногда может привести к проблемам.
                                                                                                                                                                      0
                                                                                                                                                                      К сожалению часто микромодуль противоречит вот этому:
                                                                                                                                                                      — эта строка просматривается бòльшим числом глаз чем она просматривалась бы в одном проекте
                                                                                                                                                                      — эта строка имеет меньшую вероятность внести ошибку в проект нежели написанная с нуля, особенно неискушённым разработчиком

                                                                                                                                                                      такие вещи начинают использовать не задумываясь. Кроме того у JS есть серьёзные проблемы со сборкой и получением JS нужных размеров и нарезанных нужным образом… (1 Mb JS файл часто не вариант качать, как и 50-60 мелких файлов)
                                                                                                                                                                      Я короче в JS для Frontend отказался от любых сборочных систем, текущая ситуация меня не устраивает.
                                                                                                                                                                        0
                                                                                                                                                                        И как показала ситуация все это не шибко работает. Никто особо не просматривал этот left-pad, не считал оптимальность и не искал баги. Просто взяли и использовали. Потому что люди, которые готовы это делать обладают квалификацией, что написать самостоятельно. Остальные просто подключают.

                                                                                                                                                                        И источник проблемы указан верно: слабая стандартная библиотека. И тут силами коммьюнити объединять общепринятые решения в библиотеки, как например Underscore, но многие предпочитают решать конкретную проблему и делать микромодули.
                                                                                                                                                                        0
                                                                                                                                                                        Вот только к этому и стремились в сообществе node.js: не нужно писать свои велосипеды используй уже готовое. Поэтому сама ситуация не на столько ужасна, и первая на моей памяти. Единственное — раньше была проблема с папкой node_modules и то, что вес и вложенность превышала все разумные пределы.
                                                                                                                                                                          0
                                                                                                                                                                          С каких это пор «переиспользование кода» = «разучился программировать»? Очередное нытьё на тему «мы разучились программировать, мы все умрём». С какой стати использующие простой 11-строчный модуль по умолчанию приравниваются к тупым индусам? Вполне нормальный сценарий: человеку надоело копипастить эти 11 строк из проекта в проект, вот и заюзал модуль. «Проблема третьих лиц»? Что мешает проверить код этого микромодуля? Тем более всего 11 строк! А вот то, что у вас всё ломается при исчезновении какого-либо модуля из центрального репозитория — это проблема совсем не модулей-в-одну-строчку.
                                                                                                                                                                            0
                                                                                                                                                                            Да ладно вам, дайте людям поныть — повод же есть.
                                                                                                                                                                              +1
                                                                                                                                                                              Проблема не в микросервисах и не в повторном использовании, просто в ноде нет качественной стандартной библиотеки. Нет скелета, который мог бы обрастать сторонними модулями. Была в начале года такая резонансная статья https://medium.com/@wob/the-sad-state-of-web-development-1603a861d29f, автор мог бы сейчас сказать "а я вас предупреждал"
                                                                                                                                                                              +5
                                                                                                                                                                              Сегодня вышел комментарий от сотрудника компании Kik (я его перевел).
                                                                                                                                                                                0
                                                                                                                                                                                вместо того чтобы потратить 2 минуты и написать эту базовую функцию самому
                                                                                                                                                                                Если каждый разработчик сэкономит эти 2 минуты при решении своей задачи, то вся индустрия в целом сэкономит много человеко-часов. А таких функций может быть довольно много. На мой взгляд, автор просто не хочет замечать других проблем: отсутствие стандартизированной процедуры для верификации/ревью пакетов и ненадежная политика хранения пакетов.
                                                                                                                                                                                  +5
                                                                                                                                                                                  И эти люди еще косо смотрят на PHP.
                                                                                                                                                                                  В node_modules иногда и вовсе страшно заглядывать.
                                                                                                                                                                                    +1
                                                                                                                                                                                    А зачем вы туда заглядываете?
                                                                                                                                                                                      +1
                                                                                                                                                                                      По своему опыту, к сожалению, время от времени туда приходится заглядывать. Иногда нахожу баги в зависимостях или в зависимостях зависимостей, иногда просто пытаюсь понять, что же пошло не так и почему сборка не работает, либо код ведет себя плохо.
                                                                                                                                                                                      0
                                                                                                                                                                                      Всё же лучше злоупотреблять микромодулями на JavaScript из-за небольшой стандартной библиотеки, нежели злоупотреблять массивами на PHP из-за невозможности написать простой код (наподобие «{a: "b", c: 0xd}») для создания объекта на лету. (Да и удобство стандартной библиотеки PHP настолько не на высоте, что уж лучше она была мала и поощряла создание микромодулей.)
                                                                                                                                                                                        +1
                                                                                                                                                                                        new class { public a = "b" }
                                                                                                                                                                                        • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                                                                        +9
                                                                                                                                                                                        Есть мнение, что JS это новый PHP.
                                                                                                                                                                                        0
                                                                                                                                                                                        Доброго времени суток
                                                                                                                                                                                        Некогда не понимал зачем писать обертку для того, что есть и/или пишется одной строкой.
                                                                                                                                                                                        На мой взгляд подобный код не имеет смысла оборачивать в функции.
                                                                                                                                                                                        function isArray(a){
                                                                                                                                                                                         return a && a.constructor === Array;
                                                                                                                                                                                        }
                                                                                                                                                                                        
                                                                                                                                                                                        function pading(a, b) {
                                                                                                                                                                                         return Array(b).join(" ") + a;
                                                                                                                                                                                        }
                                                                                                                                                                                          +1
                                                                                                                                                                                          Вот вы и ошиблись, isArray не все тесты проходит отсюда. Код для проверки возвращает:
                                                                                                                                                                                          true true true true undefined false null undefined false false false false true
                                                                                                                                                                                          Вместо четырёх true и остальных false.
                                                                                                                                                                                            0
                                                                                                                                                                                            Возможно, но первые четыре true, а остальные false, просто не boolean, но false.
                                                                                                                                                                                            А если нужно boolean, хотя это и не имеет смысла, допишите:
                                                                                                                                                                                            function isArray(a){
                                                                                                                                                                                             return a && !!(a.constructor === Array);
                                                                                                                                                                                            }
                                                                                                                                                                                              0
                                                                                                                                                                                              Извиняюсь забыл сказать о последней проверке:
                                                                                                                                                                                              ==> 5 // Небольшой факт: Array.prototype сам является массивом:
                                                                                                                                                                                                +1
                                                                                                                                                                                                Кажется, вы хотели написать выше:
                                                                                                                                                                                                function isArray(a){
                                                                                                                                                                                                    return !!(a && a.constructor === Array);
                                                                                                                                                                                                }

                                                                                                                                                                                                Последний тест этот: Array.isArray({ __proto__: Array.prototype }); не пройден. У правильной функции там false. Единственно верный способ там указан:
                                                                                                                                                                                                if (!Array.isArray) {
                                                                                                                                                                                                  Array.isArray = function(arg) {
                                                                                                                                                                                                    return Object.prototype.toString.call(arg) === '[object Array]';
                                                                                                                                                                                                  };
                                                                                                                                                                                                }

                                                                                                                                                                                                Это собственно говорит, что не всё так просто.
                                                                                                                                                                                                  0
                                                                                                                                                                                                  Извините, наверное мы говорим о разном, в стандартных ситуациях хватает и запроса к свойству 'constructor'
                                                                                                                                                                                                  В не стандартных ситуациях, для получения значения 'class' тоже использую '{}.toString.call()':
                                                                                                                                                                                                  function getTypeOf(a) {
                                                                                                                                                                                                   return (void 0 === a || null === a ? String(a) : {}.toString.call(a).replace(/\[.+?(\w+)\]/, '$1').toLowerCase()) || '';
                                                                                                                                                                                                  }

                                                                                                                                                                                                  Но сути дела это не меняет:
                                                                                                                                                                                                  зачем писать обертку для того, что есть и/или пишется одной строкой.
                                                                                                                                                                                                  • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                                                                                                      0
                                                                                                                                                                                                      Спасибо
                                                                                                                                                                                                      Спасибо, за внимание, не понял вашего совета.
                                                                                                                                                                                                      function isArray(a){
                                                                                                                                                                                                       return !!(a &a