5 претензий к Deno +26



image

Предисловие


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

Deno — убийца NodeJs


Это не так. Таким его продвигают только «свидетели deno», безумные фанаты, либо жаждущие хайпа переводчики. Насколько мне известно, даже сам Раян Дал (автор Deno) не позиционирует свою разработку как замену или альтернативу NodeJs. Это скорее его видение «каким может быть тот же NodeJs в будущем». Концепт, если хотите (мы же не ругаем концепты авто или смартфонов за их непрактичность в современных реалиях). С точки зрения Раяна в NodeJs есть определенные проблемы. И он показал сообществу некое представление о том, как бы эти проблемы можно было бы решить. И вы можете в этом участвовать. Прямо сейчас приходите на GitHub, и описывайте те архитектурные проблемы которые вы видите. Обсуждайте их. Придумывайте решения.

Я не думаю, что Deno когда-либо заменит NodeJs. Но он может стать для него тем же чем стал TypeScript для JavaScript.

Импорт по URL


Многие смотрят на это немного не под тем углом. Идея в том, чтобы отказаться от глобального списка зависимостей на весь проект. Чтобы вместо одного большого package.json у вас в каждом вашем модуле/файле был свой, независимый список зависимостей. Я вижу в этом несколько плюсов.

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

Но для такого подхода нужна возможность описывать зависимости для каждого модуля. Название, версию и откуда эту зависимость взять. Как следствие — import с указанием URL. И это даже не придумка Deno. Это часть стандарта. Просто все привыкли работать так как привыкли. Но это не единственный путь.

Но как мне теперь работать без интернета?


Точно так же как бы вы работали с NodeJs. Что Deno, что NodeJs скачивают зависимости в отдельную директорию. Только в NodeJs для этого вы запускаете npm install, а Deno делает это автоматически при первом запуске.

Звучит интересно, но я отказываюсь!


Не проблема. Есть такой пропозал — import maps. И Deno его поддерживает, хоть и не в полной мере. Таким образом вы можете описать синонимы для всех зависимостей придя к аналогу package.json. Но вы не будете ограничены этим:

  • Отдельные модули всё ещё могут использовать собственные версии зависимостей, по необходимости, игнорируя import map.
  • Спецификация import maps предполагает возможность указать несколько источников для загрузки. Сейчас Deno это не поддерживает. Но технически это возможно. Вы могли бы указывать несколько источников и в случае если один не доступен — зависимость будет скачано из другого.

    {
       "imports": {
          "moment/": [
             "https://deno.land/x/moment/",
             "https://raw.githubusercontent.com/lisniuse/deno_moment/master/"
          ]
       }
    }
    

Без npm я не могу поставить консольную утилиту глобально!


Ну, вообще можете. deno install это аналог npm install --global. Deno скачает, скомпилирует требуемую библиотеку в бинарник и сохранит глобально. Отличие в том, что вы обязаны выдать библиотеке какие-то разрешения. То есть, установленный глобально пакет не получит доступа к сети, или к файлам, или ещё куда без вашего согласия.

Странное чувство дежавю


И оно не без основательно. Deno это тот же NodeJs. Я вижу лишь несколько отличий:

  • Автор Deno отбросил обратную совместимость. Что позволило ему реализовать те же вещи, с использованием не собственного велосипеда, а велосипеда описанного в спецификации языка. Уверен, если бы вышел какой-то «Node-next» без обратной совместимости, мы бы получили примерно то же самое, что предлагает Deno. И NodeJs постепенно двигается в этом направлении: все новые фишки ES (как то: ES-модули, top-level-await, и т.п.) постепенно внедряются в NodeJs.
  • Отказ от общего списка зависимостей. Это может быть как плюсом так и минусом. Зависит от конкретных случаев. Но нельзя отрицать, что такая архитектура имеет право на существование.
  • Идея запрещать скрипту доступ к системе без явного разрешения.

Вот и все отличия на мой взгляд. Так что не вижу причин ненавидеть Deno. Разве что его агрессивных пиарщиков :)

Теги:




Комментарии (50):

  1. k12th
    /#21689570

    Если вам нужно написать какую-то фичу, вы не обязаны смотреть какие зависимости уже используются в проекте. Вы не ограничены ими. Вы используете то, что вам нужно.

    Это, конечно, удобно если в одном файле можно использовать некий libjs 1.x, а в соседнем libjs 2.x — но исключительно на стадии прототипирования. В долгосрочной поддержке это только головная боль.

    • vvadzim
      /#21689616

      В долгосрочной поддержке это будет запрещено линтером.

      • k12th
        /#21689668

        Линтер это хорошо, но по факту далеко не во всех проектах он есть.

        • slaFFik
          /#21689694

          Если проект долгосрочный — он обязан использовать линтер. Иначе ССЗБ.

      • printf
        /#21689722 / +2

        Линтер это тулинг, который тоже надо конфигурировать, встраивать в процесс CI и поддерживать. Т.е. цена этого решения ненулевая, а выигрыш, как по мне, стремится к нулю (особенно если мы всю предоставляемую такими импортами гибкость зарубаем в итоге линтером).

        Еще один момент это аудит кода. В npm или yarn очень легко получить ответ на вопросы:

        • Какие пакеты являются моими прямыми / транзитивными зависимостями?
        • Какие из моих зависимостей устарели и нуждаются в обновлении?
        • Зачем нужна эта конкретная транзитивная зависимость? (yarn why)
        • Какие лицензии у моих зависимостей?

        Для этого не нужно парсить никакой код, загрузил один json-файл и всё. Работает быстро в проекте любого размера.

        А еще бывают devDependencies и peerDependencies, которые не присутствуют в рантайме — как это в Deno реализовано я не знаю, поэтому ничего утверждать не стану, кроме того, что это очень нужная на практике штука.

        • Kozack
          /#21689822

          Deno как и NodeJs — это среда исполнения. Для NodeJs существует отдельная утилита — пакетный менеджер — npm. Она берет на себя роль управления всеми зависимостями, не только для рантайма, а в целом по проекту, их обновлением и всё в таком духе.


          Deno не поставляется со своим аналогом npm. И хотя возможно устанавливать отдельные утилиты в директорию проекта, это сложно назвать полноценным пакетным менеджером.


          Но, народные умельци уже написали несколько утилит:


          • velociraptor — An alternative to npm scripts for Deno
          • denox — Script runner and workspace configuration for Deno
          • dpm — deno package manager
          • dem — A module version manager for Deno.
          • Trex — package management like npm for deno

          • printf
            /#21690052 / +3

            Одно из преимуществ Deno, которые мы тут обсуждаем — отказ от npm, package.json и node_modules, а пол-коммьюнити тем временем пишет множественные аналоги npm, да придумывает свои несовместимые форматы а-ля package.json, например dem.json. Так не победим!

            Поймите правильно, мне нравится Deno. TypeScript это клёво, настройки безопасности это клёво. Но вот эта штука с импортами — не пришей нигде рукав.

            • Kozack
              /#21690162

              Одно из преимуществ Deno, которые мы тут обсуждаем — отказ от npm, package.json

              Ну, не совсем.


              npm — менеджер пакетов. Ряд озвученных вами вопросов, действительно стоит остро, и утилиты, для анализа всей кодовой базы или какой-то части и вывода статистики по всем зависимостям по модульно действительно не хватает. И, если будет потребность, то такие появятся. Но текущие реализации, я думаю, жертвы привычки.


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


              Сейчас Deno и его сообщество в зародыше. Лучшие практики ещё не выработаны, инструменты не написаны.


              Но вот эта штука с импортами — не пришей нигде рукав.

              Может и так. Лично я пока не вижу тут проблем. Но, справедливости ради, я и не искал особо. Мне видится тут больше гибкости. Вы пишите что-то простое? Вам не нужно заворачиваться с установкой зависимостей локально. Просто пишите код. Работаете над чем то побольше? Создайте свой реестр зависимостей. Со временем появятся инструменты для их анализа.

              • printf
                /#21692672

                Да, согласен, надо поработать с этим. Сам еще не переносил ничего толком на Deno, так, поглядываю в документацию немношк.

                Попробую какую-нибудь мелочь портировать на выходных.

      • nin-jin
        /#21691338

        А зачем что-то разрешать, что потом ещё нужно запрещать отдельными линтерами?

        • Kozack
          /#21692840 / +1

          Весь JavaScript так работает :)

          • nin-jin
            /#21693564

            У JS тяжёлое прошлое. Меня больше удивляет, когда сейчас разрабатывают новый язык позволяющий писать и так и эдак и тут же к нему прикладывают линтер, который не позволяет писать эдак, и форматтер, который форматирует именно так. Привет, Go.

            • Kozack
              /#21693622

              А я вот понимаю такой подход. Сделать гибкий язык который может работать как угодно и предоставить инструмент, чтобы каждая команда могла "донастроить" его для своих нужд. Мне больше нравится когда всё строго, когда имена файлов и структура директорий жестко регламентирована интерпретатором. Но, как ты не крути, это нужно не всегда и часто в разном виде.

              • nin-jin
                /#21693860

                Да никто не занимается такой ерундой, как форканье гоформатера с целью "донастройки" для "своих нужд" (будто в них есть что-то особенное). Никому такой бардак не нужен.

                • Kozack
                  /#21693872

                  Я имел в виде существование линтера в целом. то о чем вы писали


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

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


                  А вот настроить эти ограничения каждый может так как нужно именно ему. Что гораздо гибче.

  2. Nikolyansky
    /#21689622

    хейтеры для всего найдутся, надо стараться адекватно на все реагировать

  3. SirEdvin
    /#21690092 / +3

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

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

    • Den-V
      /#21691998

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

      • SirEdvin
        /#21692846 / +3

        Я, конечно, все понимаю, но сейчас уже 2020 год и как бы отсутствие менеджмента зависимостей это как отсутствие, например, типа bool в языке.

  4. Tantrido
    /#21690496

    Но для такого подхода нужна возможность описывать зависимости для каждого модуля. Название, версию и откуда эту зависимость взять. Как следствие — import с указанием URL.

    Но это могут быть десятки и сотни зависимостей!!! Всё вручную прописывать?!

  5. dmz9
    /#21690504

    очередной пример синдрома фатального недостатка

    • barkalov
      /#21690520

      Кто был автором node? А кто автор deno?

      • dmz9
        /#21690542

        т.е. когда свой собственный проект переписываешь заново — это не считается? )

        • Kozack
          /#21690548

          Это называют "Переосмысление" :)

        • barkalov
          /#21690562

          Загуглите «фатальный недостаток».

  6. artemmalko
    /#21692148

    Подскажите, я может не до конца понял этот момент.

    Представим ситуацию, что какой-то сервис деплоится автоматом в полночь. Использует Deno. Итак, проект используется import по URL. Владелец этого URL ровно в полночь подменяет контент по этому URL на вердоносный. В момент деплоя пакеты скачиваются заново, качается вредоносная версия. На бой также попадает пакет с плохим кодом. Через. 5 минут, владелец URL меняет код обратно на хороший.

    На каком этапе Deno защитит от такой атаки?

    • Kozack
      /#21692522 / +1

      Deno, как и Node, умеет создавать lock.json. В нем будет список ссылок и хэш. Если при восстановлении зависимостей, хэш измененного файла не будет соответствовать сохраненному — Deno выдаст ошибку "Subresource integrity check failed"
      https://deno.land/manual/linking_to_external_code/integrity_checking

      • weslyg
        /#21693352

        Не совсем понял, даже если я соберу контейнер с Deno, и описанная выше ситуация произойдет, у меня не будет локально в контейнере всех зависимостей, а они заново подтянутся из интернета?

  7. Kroid
    /#21692260

    Если подытожить, deno создан для криворуких copy-paste девелоперов. Нашёл на стаковерфлоу кусок кода, скопировал себе в проект и дальше пошёл. А то, что в 10 файлах будет 10 импортов разных версий одной либы — да кого это волнует?


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


    Единственный плюс deno — возможность явно указывать разрешения при запуске скрипта.

  8. abar
    /#21692500 / +4

    Вот у меня вопрос по поводу этого пункта:

    Но для такого подхода нужна возможность описывать зависимости для каждого модуля. Название, версию и откуда эту зависимость взять. Как следствие — import с указанием URL. И это даже не придумка Deno. Это часть стандарта. Просто все привыкли работать так как привыкли. Но это не единственный путь.

    Возьмем maven. Вот хочу я скачать новую зависимость: указываю название (в двух частях), версию, и откуда скачать (активирую нужный репозиторий — вот вам и import maps, кстати).

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

    Мне такой подход кажется максимально логичным, так как позволяет как делать что угодно, так и разделять обязанности и ответственности. При скачивании же модулей по URL у нас получается какая-то каша в которой зависимости качаются как попало, откуда попало, по совету левых чуваков со stackoverflow, и никто на это не сможет повлиять без дополнительных усилий. Соответственно, вопрос: а нафига такое надо, и в чем польза такого подхода.

    • MadHacker
      /#21693394

      У меня по этому пункту вопрос ко всей инфраструктуре JS.
      У меня ушло много времени, чтоб заставить npm работать в изолированной от интернета среде.
      Нет, справедливости ради — заставить сам npm это одна переменная окружения или один параметр к нему. Но вот подготовить зеркало репозиториев NPM и так чтоб он был не кеширующим самостоятельно бегающим в интернет, а нормальным зеркалом с ручным управлением — это была боль.
      А если разработчику на той же ноде с тем же NPM задать вопрос «как с этим работать без интернета?» у них картина мироздания рушится.

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

      Это какая-то глобальная тенденция современной разработки. Системы управления зависимостями не представляют современный мир без интернета.

      • printf
        /#21694380 / -1

        Не рушится никакая картина мироздания, зачекинил всю папку node_modules в git и вот, полностью воспроизводимый билд без интернета. (Есть нюансы с модулями на С++, но это детали.)

        А если нужен новый модуль, тогда да, или интернет, или настроенное зеркало. Но так работают любые репозитории, JS из общей массы по-моему не выделяется.

  9. Fuckin_butcher
    /#21693262

    Учитывая то, как бурно обсуждают и критикуют deno, эта штука всё-таки, уже начинает выстреливать и становиться популярной. Что мешает JS иметь ещё один серверный интерпретатор?

    • YuraGolomb
      /#21693362

      Откуда информация что он начинает выстреливать? Пока Deno просто хайпит на том что "это как года только лучше". Интерес к нему у большинства (имхо) скорее академический, интересно посмотреть что да как.
      Выстреливать он начнет (если начнет) когда выйдет полноценный релиз и на нем будут делать коммерческие проекты.
      А вообще конкуренция это хорошо

      • Fuckin_butcher
        /#21693886

        Deno уже релизнулся в этом месяце и, в принципе, для домашних хотелок и петов его хватает за глаза, ну а энтерпрайз естественно к себе не потащит в ближайшее время необкатанный временем deno, с нодой так же было.

    • printf
      /#21694420

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

  10. weslyg
    /#21693332

    Я наверное ничего не понимаю, но блин, npm же, это удобно! Установка зависимостей по умолчанию в локальную папку, И возможность поставить в global. Кастомные скрипты, единая точка входа, dev/prod Зависимости, возможность указать платформу запуска и тд. Я искренне восхищаюсь идеями npm. А шутки про размер node_modules и скорость их доставки, с появлением Yarn + nvme ssd как то теперь не парят. К слову в питоне, это пришло только с появлением venv, до этого было трешово. А кастомные скрипты до сих пор только в setup.py и их вызов из командной строки очень не удобен.
    Не понимаю, почему npm надо избегать…

    • printf
      /#21694442

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

    • Kozack
      /#21701968

      Да, npm — это очень удобный инструмент. Но, я вижу некоторое недопонимание у сообщества. Хотя, не исключено, что ошибаюсь именно я.


      Deno — это "переосмысление" Node. Именно Node. Не смешивайте с npm. Node — это среда исполнения, npm — менеджер пакетов и появился он примерно через пол года после первых выпусков Node. Сейчас они поставляются вместе из-за исторической необходимости. Ну, и вы сами видите реакцию сообщества на идею работы среды исполнения без комплектного менеджера пакетов.


      Deno — именно прокачанная среда исполнения. Разница в том, что во времена создания модульной системы Node в языке не было ничего. А в Deno просто реализованы все современные возможности языка. Даже больше чем сейчас поддерживается в Node или в браузерах. Даже компиляторы по типу babel или typescript ограничены возможностями той среды в которой будет запускаться итоговый код.


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

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

  11. DMP7
    /#21693366

    Преимущество node и js, как раз в отсутствии типов, быстрой и удобной разработке. Нужны типы — берите go и не переделывайте лёгкую авиацию в тяжёлую, у каждого инструмента своё предназначение.

    • Fuckin_butcher
      /#21693856

      Так ничего же не запрещает deno скармливать es код в ts файле, разве нет?:D

      • Kozack
        /#21693876

        Deno ж и с .js спокойно работает, разве нет?:D

        • Fuckin_butcher
          /#21695092

          Я просто не пробовал, а оно, оказывается, работает:D

      • DMP7
        /#21698270

        Deno рассчитан на работу с TS, который по сути не имеет смысла — нужны типы возьми другой язык, JS не для этого сделан.

        • Fuckin_butcher
          /#21700708

          Чисто к примеру, я испытываю дискомфорт из-за нехватки интерфейсов, типов и прочего при использовании react без тайпскрипта. выбрать другой язык не могу, т.к. альтернативы джаваскрипту в вебе нет, по-этому приходится писать на тайпскрипте, ts экономит время на понимании кода спустя время(хоть и отнимает его на указание типов и тд). Именно по-этому ентерпрайз полюбил ts, потому что он позволяет экономить время при решении задач бизнеса, я вижу в этом суть ts, не зависимо от того, где ts используется.

          • DMP7
            /#21703432

            Когда занимался фронтом не мог понять зачем там вообще всё это надо — всё настолько просто пишется и тестируется, что хз…
            Энтерпрайз любит, т.к. те кто перешли на фронт, раньше писали на чём то типизированном и им так привычней.
            Но в данной статье речь про бек, а не про фронт.

    • VolCh
      /#21694776 / +1

      для go надо мозг свой переделывать.

  12. defusioner
    /#21695410

    управление зависимостями вернулось в 2005 год, когда в head импортили все подряд

  13. Blaurt
    /#21698074 / +1

    Добрый день!
    Я, как и многие, всё таки не оценил новую систему с модулями.
    Вот например мне понадобились 5 часто используемых пакетов. В npm я прописал их имена, которые я помню наизусть, попил чаю, и пакеты уже ждут меня. В deno я должен помнить URL этих пакетов? И из проекта в проект либо руками копировать эти URL, либо сидеть и тратить n времени на повторный поиск этих URL?

    • Kozack
      /#21701756

      Как обычно работаю я. Я просто пишу код. Когда использую какую-то функцию — моя IDE сама вставляет import. Если бы я работал с Deno, то этого было бы достаточно. Но работая с node, моя IDE должна ещё проверить установлен ли нужный пакет, и если нет — установить.


      Я думаю, что большинство подобных вопросов — это дело привычки и отсутствия инструментов.