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

http://www.haneycodes.net/npm-left-pad-have-we-forgotten-how-to-program/
  • Перевод
Автор — Дэвид Хейни (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 строк для набивки строки слева пробелами.
Поделиться публикацией
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 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».
                                                                                                                            Что это вообще значит? Означает ли это что стандарт ещё не стабильный в будущем в нём могут произойти изменения ломающий обратную совместимость?
                                                                                                                      • +1
                                                                                                                        Согласно MDN IE и Safari пока не поддерживают
                                                                                                                        Скрин оттуда
                                                                                                                        IE и Safari пока не поддерживают fetch
                                                                                                                      • +1
                                                                                                                        Тссс, ещё нельзя. Ах да, в полифил нельзя, иначе ты "типа разучился программировать и лах" ©.
                                                                                                                    • +3
                                                                                                                      Вполне закономерная ситуация, и проблеме не в npm, сотнях однострочных модулях и зависимостях, а в том, что у js очень бедная стандартная библиотека, люди начали решать ее отсутствие такими вот костылями чтобы не писать в каждом проекте isArray вручную, в конечном счете как это обычно и бывает, костыль поднялся и ударил людей по лбу.
                                                                                                                      • +2
                                                                                                                        Мне кажется, что вся работа программиста в экосистеме NPM сводится к написанию как можно меньшего количества кода, чтобы связать вместе существующие библиотеки, чтобы создать нечто новое, функционирующее уникальным образом для личных или коммерческих нужд.
                                                                                                                        А разве это не цель, для которой пишутся программы? Не Ваша цель, как программиста, а цель написания программы?
                                                                                                                        • +1
                                                                                                                          Честно говоря, я именно так и пишу программы. И пару лет назад писал о том, что современному программисту для выполнения типичных задач достаточно взять какой-нибудь фреймворк и связать несколько вещей между собой, за что меня побили.
                                                                                                                          • НЛО прилетело и опубликовало эту надпись здесь
                                                                                                                        • 0
                                                                                                                          Проблема описываемая автором обратная сторона велосепедо строения.
                                                                                                                          • 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