Прошло примерно 18 месяцев с внутреннего релиза Deno, вышел preview release, появилось несколько статей на Хабре, и Райан ездит по конференциям и рассказывает о нём. Однако я нигде так и не видел сколько-нибудь вдумчивого разбора этого проекта — почему-то все ограничиваются переводом документации...


Что же, давайте попробуем это сделать сейчас. Последние 5 лет я пишу на Node.JS, а компания OneTwoTrip, где я сейчас работаю, пишет проекты на ноде около 9 лет (да, это я писал историю про 9 лет в монолите на ноде). Так что анализ должен выйти неплохой. Тем более что я его уже рассказал на Moscow Node.JS Meetup 10, и было интересно. Кстати, если вам удобнее слушать, а не читать, то послушать и посмотреть можно вот тут. Моё выступление второе, я чувак в розовой рубашке.


Как ни странно, для того, чтобы понять, откуда и зачем возник проект, надо провалиться в прошлое. Так что вкидываем немного плутония, поднимаем двери нашего делореана, и пускаемся в путешествие — посмотрим на важные 10 лет, которые сделали Node.JS такой, как мы видим сейчас.



Вперёд в прошлое


2009


Райан Дал анонсирует Node.JS, вот она — самая первая презентация на JSConf 2009.


2010


Появляются express, socket.io — основные на текущий момент кирпичики почти любого сервиса.


Появляются сумасшедшие люди, которые реально пишут на этом серверный код!


2011


С Node.JS начинают заигрывать крупные ребята — в том числе Uber и Linkedin.


Релиз npm 1.0.


Node начинает работать на Windows.


2012


Райан уходит от разработки Node.JS. Запомните. Это был 2012 год. Так что Райан безусловно является создателем, и многое сделал для экосистемы — но последующие 7 лет прошли без его участия.


2013


Node в Paypal, Walmart, eBay.


Появляется Koa — помните, сколько копий было сломано о генераторы?


2014


Node в Netflix. Начинаются попытки оформить проект в что-то более взрослое, с открытой моделью управления консультативным советом. Наблюдается техническая стагнация, приведшая к появлению форка io.js.


2015


Работа над ошибками. Слияние io.js и Node в экстазе под эгидой Node Foundation и выход Node 4. Надо сказать, именно эту версию я считаю первой, на которой реально можно было что-то разрабатывать. Если кто писал на версиях 0.xx — то вы помните про var, callback hell, кучу разных библиотек для упрощения асинхронной работы (вроде step и async. Да, async — это не только async await, но ещё и npm библиотека).


2016


Инцидент с leftpad, который до сих пор злые языки припоминают экосистеме. Сколько же было статей и нападок. Ну, haters gonna hate. Однако, важные уроки из этого были вынесены.


2017


Прорывной год. Я не буду упоминать все релизы ноды и рост количества установок модулей с npm, однако именно в этом году количество сервисов на Node.JS превысило 8 миллионов, а количество установок — 3 миллиарда в неделю. Абсолютно космические цифры, которые сложно даже представить.


Так же появился N-API, и Node.JS был снова форкнут в Ayo.js. Очень смешная и поучительная история про SJW — она стоит отдельной статьи, поэтому не буду на ней останавливаться — просто рекомендую прочитать на досуге. Только проспойлерю, что форк благополучно умер.


2018


Вторая массовая истерия со времени leftpad — теперь про то как event-stream ворует биткоины. Сотни постов про небезопасность экосистемы. Посты-фантазии про то как npm пакеты воруют данные кредитных карт. Комьюнити поливают грязью как из шланга. Надо сказать, это было очень полезно, и выводы так же были сделаны — о них чуть позже.


Так же Райан внезапно взрывает комьюнити постами про то, что серьёзные сервисы стоит писать на Go, описывает 10 вещей в Node, о которых он сожалеет, и анонсирует Deno, который решает все проблемы.


2019


Deno выходит в preview release, появляется куча статей на хабре, и вот вы сейчас читаете одну из них.



Назад в настоящее


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


10 вещей в Node.JS, о которых сожалеет Райан Дал


К сожалению, я не нашёл навскидку статью с переводом доклада, так что перечислю их здесь вкратце, и здесь же откомментирую.


  1. Отсутствие поддержки промисов в начале пути. Да, всё было бы проще, если бы Райан не выпилил промисы, сочтя их за лишнее усложнение, которое не взлетало в начале разработки ноды. Потерянного времени на весь этот callback hell конечно жалко — но в 2019 году у всех вменяемых библиотек промисы являются основным интерфейсом. Более того, даже системные библиотеки наконец предоставляют промисы.
  2. Безопасность системных вызовов и обращений по сети. С одной стороны — да, хорошо когда всё безопасно. С другой стороны — непонятно, чем в этом плане нода оказалась хуже любой другой среды....
  3. Сборка нативных модулей при помощи GYP. Да, наверное, это было лишним, но кто мог знать, что хром с неё уйдёт. Опять же — если хром ушёл, значит, сможем уйти и мы....
  4. Излишество package.json. NPM как монопольное регистри. Аргумент про package.json немного странный. Например, Райан говорит, что там есть всякий мусор вроде лицензии. Но если бы её там не было — как вы могли бы быстро узнать лицензии модулей, используемых в вашем проекте?.. Аргумент насчёт NPM больше похож на правду, но остановимся на этом подробнее позже.
  5. Node modules. Сложное разрешение зависимостей, работает не так как в браузере. Да, всё так. Стабильно зависимости начали ставиться без всяких чудес только на 4-5 версии npm. Но механизм работает, и позволяет делать удивительные вещи — на текущий момент это прекрасно. Что же касается совместимостью с браузером — что бы вы ни делали, всё равно будут этапы обработки кода вроде транспиляции и сбора бандла. Так что вряд ли node modules имеет какое-то значение в данном контексте.
  6. Require без расширения и его неопределённость. Да, наверное, плохо. Но не настолько, чтобы об этом упоминать...
  7. index.js как лишнее усложнение. Тоже слишком тривиальный и скучный пункт, чтобы его описывать.

Кстати, заметьте, я говорил, что Райан сожалеет о 10 вещах, а пунктов всего 7. Это не ошибка, я несколько раз пересматривал его доклад, и обзоры доклада. То ли это была сложная шутка на тему обработки числовых значений, то ли Райан просто постеснялся назвать ещё 3 пункта...


Но ладно, поняли проблемы, поехали дальше. Логично, что в Deno Райан решил избавиться от всех проблем Node.JS. Посмотрим, что у него вышло.


Из чего состоит Deno


  1. Deno написан на Rust.
  2. В качестве Event loop в Deno используется Tokio, написанный опять же на Rust.
  3. Deno поддерживает Typescript "из коробки".
  4. Ну а код исполняется при помощи того же V8, который захватил весь мир.

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


Rust. Не, прошу понять меня правильно — я считаю, что Rust и Go это прекрасные языки, и я искренне рад, что они есть. Они дают возможность писать низкоуровневый код быстрее и безопаснее, чем на С++. Однако, есть нюанс — в лучшем случае он будет не медленнее реализации на С++. Так что смысла писать полный аналог системных обвязок и ивент лупа лично я не вижу — вряд ли это может принести какую-то реальную пользу, поскольку это те вещи, которые в какой-то момент просто доходят до оптимального состояния, и дальше фактически не оптимизируются.


TypeScript. Опять же — я ничего не имею против TS. Его использует огромное количество компаний и разработчиков, и он уже показал свою состоятельность. Но Deno всего лишь прячет транспилятор в бинарник, а транспилированный код — в особые директории. То есть под капотом происходит всё то же самое, и выгоды в этом нет, за исключением эстетической. Зато есть минус — версия транспилятора оказывается намертво прибита к версии Deno. Не уверен, что это хорошо — легко представить себе ситуацию, когда вам хочется обновить либо транспилятор либо рантайм. Но не и то и другое сразу.


Так что пока ничего вкусного не видно. Пойдём дальше, заглянем в основные фичи.


Основные отличия Deno и Node.JS


Deno не использует npm. Нет централизованного реестра. Модули импортируются по URL. Нет package.json.


То есть, код выглядит примерно так:


import { test, runIfMain } from "https://deno.land/std/testing/mod.ts";
import { assertEquals } from "https://deno.land/std/testing/asserts.ts";

test(function t1() {
  assertEquals("hello", "hello");
});

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


  1. Всё пойдёт так как того хочет Райан. Разработчики будут заливать код компонентов на личные веб сайты, создавать папки с версиями, и все будут качать пакеты оттуда. Гмм. Мне кажется, это решительный скачок в прошлое:
    1.1. Любой код, в том числе с указанной версией, может бесконтрольно меняться на сервере автора.
    1.2. Не будет никакого источника, из которого можно узнать о стабильности пакета, о количестве его переиспользований, о наличии в нём закладок и проблем.
    1.3. Автору пакета придётся самому заботиться о том, чтобы его сервер держал нагрузку от скачивающих пакеты разработчиков. Неужели мы этого не наелись около 2012 года, когда npm чаще лежал, чем работал? Как говорят наклейки на автомобилях, "можем повторить"?
  2. Другой вариант, более реальный. Разработчики будут класть пакеты на github, gitlab, или любой другой репозиторий, который держит нагрузку и прозрачен для комьюнити. Вроде всё хорошо. Остаётся один вопрос. От npm мы, предположим, откажемся — но какая разница, какой именно будет централизованный репозиторий? Будет всё ровно то же самое — просто вид сбоку. Даже проект децентрализованных репозиториев Entropic, который, кажется, тихо скончался — и то выглядел интереснее.

Отдельного рассмотрения стоит вопрос воспроизводимых билдов. Поскольку никто не гарантирует, что вы скачаете с какого-то левого сервера одно и то же (в особенности если не указали в урле версию) — то Райан предлагает… Хранить исходный код импортируемых пакетов в репозитории проекта… На дворе точно 2019? Может, Райан не в курсе, что с 2012 года в Node.JS появился сначала shrinkwrap, а потом lock file? Которые решают эту проблему гораздо проще, нагляднее и экономичнее?


На мой взгляд, загрузка модулей по URL — очень странное и спорное решение, основное достоинство которого — вау эффект для джуниор разработчиков.


Все асинхронные операции в Deno возвращают Promise.


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


Deno всегда завершает работу на Uncaught Errors


Странно видеть это в списке значимых отличий. В Node.JS вы можете делать ровно то же самое. Если вам это нужно.


Используются ES Modules, а не require


Да, хорошо, что бэк и фронт переходят на один формат. Но знаете, в Node.JS сейчас тоже есть поддержка ES Modules...


Deno требует разрешения на работу с сетью, файлами и переменными окружения.


Звучит классно! Но реализация… Реализация — это просто набор флагов allow-read, allow-net, allow-run, allow-env. Выглядит это как-то так:


deno --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd

Это опять же вызывает у меня вопросы:


  1. В большом приложении скрипт запуска превратится в помойку флагов.
  2. Скорее всего, эти ограничения просто превратятся в практику запуска с флагом --allow-all.
  3. Практически ни в какой другой среде нет подобных ограничений. И все отлично с этим живут. По той простой причине, что уже много лет как правами на доступ к файлам можно управлять на уровне разрешений пользователя, от которого запущен процесс. А вопрос сетевого взаимодействия отлично решается файрволами. Почему Райан решил, что это вопрос рантайма — мне глубоко непонятно.
  4. Ну и последнее. Контейнеры не только появились, они прочно вошли в употребление, и даже перестали быть хайповой темой. И они отлично решают эти вопросы. Появляется ощущение, что Райан вошёл в 2019 год на машине времени прямо из 2012, и только это всё объясняет — тогда до релиза докера был ещё целый год...

Наше время. Наши дни. NPM.



Ну и в целом мне хотелось напомнить, что произошло с npm с 2012 года:


  1. Пакеты не исчезают. Удаление и изменение загруженной версии запрещено.
  2. Lock file обеспечивает воспроизводимые сборки.
  3. Есть аудит безопасности. Причём с помощью github, snyk и самого npm.
  4. Есть статистика использования и зависимостей.
  5. Есть альтернативные клиенты.
  6. Есть возможность ставить пакеты из иных источников — гит, гитхаб, что угодно.
  7. Есть прокси регистри.

А главным достоинством npm я считаю… То, что его в любой момент можно выкинуть из экосистемы. Есть протокол, есть клиенты, есть другие регистри… Как только "Акела промахнётся", любая большая компания может поднять альтернативный регистри — facebook, google, microsoft, gitlab… Пока что этого не случалось ровно по той причине, что npm работает достаточно стабильно и отвечает потребностям сообщества.


Подводя итоги


Пройдём по пунктам:


  1. Rust — не преимущество.
  2. TypeScript — не преимущество.
  3. Загрузка модулей по URL без NPM — скорее два шага назад.
  4. Улучшения безопасности — выглядит ужасно.
  5. Остальные отличия непринципиальны. Разве что лого. Лого офигенное. Люблю динозавров!


В итоге я просто не вижу смысла в использовании Deno. Терпеть не могу позицию "не пробовал, но осуждаю" — но, пока что даже Райан говорит, что Deno ещё сырой — поэтому пробовать я его не стал.


Однако я очень хотел найти антагониста, который бы сказал мне, что я не прав, что Райан сделал крутую штуку, и что я не понял её применения. Я много обсуждал Deno с коллегами, друзьями, и рассказывал всё это на Moscow Node.JS Meetup — и никто не высказал мне альтернативного мнения. Отчасти поэтому я пишу статью на хабр — скажите, может я всё же что-то не понял или не заметил?

Комментарии (140)


  1. Zenitchik
    22.11.2019 17:25

    Поскольку никто не гарантирует, что вы скачаете с какого-то левого сервера одно и то же (в особенности если не указали в урле версию) — то Райан предлагает…

    Хранить исходный код импортируемых пакетов в репозитории проекта… На дворе точно 2019?

    Ну видите ли,
    никто не гарантирует, что вы скачаете … одно и то же

    Рухнуть может всё что угодно. А критичные для проекта зависимости от этого не должны стать недоступными.


    1. jehy Автор
      22.11.2019 17:30
      +2

      Для этого есть прокси регистри и артефакты сборки. Да и если уж на то пошло — можно точно так же упороться и класть в гит node modules, deno для этого не нужен.


      Опять же, чтобы потерять исходники npm пакета — нужно, чтобы одновременно упал npm и github.


      1. deksden
        22.11.2019 19:14

        Ещё одновременно нужно чтобы рухнули локальные git репозитории пакета у его разработчика. Git же децентрализованный


      1. sumanai
        23.11.2019 19:37
        +1

        нужно, чтобы одновременно упал npm и github.

        То есть достаточно РКН.


        1. jehy Автор
          23.11.2019 20:51

          От ркн загрузка по урлам и из репозитория тоже не поможет. Благо решается это легко — проходили.


  1. CoreTeamTech
    22.11.2019 17:42
    +3

    Очень подробное и интересное мнение, спасибо. Возразить по вашим тезисам мне особо нечего. Я только хочу указать, что сравнение, мне кажется, не уместно. Тысячи статей из прошлого сочли NodeJS какой-то неудачной шуткой — разрабатывать бэкенд на JavaScript, вы серьезно? Я и сам имея опыт ASP + JScript в то время был настроен весьма скептически. Но какие-то «упоротые» ребята продолжали его использовать. Потом подключились спонсоры и все закрутилось с еще большей скоростью вокруг Ноды. А это просто был эксперимент одного программиста. Вот и сейчас, тот же самый программист экспериментирует. Завтра кто-то из рядовых разработчиков большой компании, просто ради эксперимента реализует проект на Deno. На гитхаб-странице проекта появится лого и кейс, другие разработчики подумают, что может и стоит попробовать… И оно начнет расти.
    С точки зрения энтерпрайза, наличие Rust и TypeScript дает хороший маркетинг. Обновлять рантайм просто так не принято, только со стабильной версии на стабильную и с отдельным бюджетом. Поэтому тут все нормально.
    Единственное, что действительно пугает — импорт зависимостей, но может мы чего-то не знаем пока?


    1. deksden
      22.11.2019 19:16
      +1

      Typescript легко реализуется через Babel, который нынче есть у любого js проекта среднего возраста! Зачем deno?


      1. CoreTeamTech
        22.11.2019 20:03

        Я могу лишь спекулировать на эту тему, но давайте пофантазируем… выбор TypeScript, скорее всего, это принуждение к унификации кода, но не так жестко как Go. Я думаю, что там не только TS прибит гвоздями, но и со временем будут вшиты конкретные правила eslint. Имея подобную предсказуемость можно делать более оптимизированный инструментарий, да и рантайм можно лучше оптимизировать.
        Это что касается TypeScript и расширения библиотеки модулей, другой аспект — расширяемость рантайма, где Deno использует Rust. Возможно, и это все ещё мои фантазии на тему, выбор пал на «ржавого» из-за обещанной безопасности, а значит можно позволить другим расширять рантайм и иметь хоть какие-то гарантии.
        Но основной ответ на ваш вопрос — а почему бы и нет!?


      1. jehy Автор
        22.11.2019 20:05

        А ещё для эстетов есть ts-node.


    1. proninyaroslav
      22.11.2019 23:18
      +2

      Единственное, что действительно пугает — импорт зависимостей, но может мы чего-то не знаем пока?

      Скорее влияние Go на Райана. Там это практиковалось изначально, но подвергалось критике по многим причинам, поэтому недавно перешли на концепцию модулей.


    1. biziwalker
      23.11.2019 10:09

      Импорт зависимостей напрямую имеет один плюс и рассчитан на то что это будет делаться с гитхаба или чего-то подобного. Плюс заключается в том что исходники и репозиторий в одном месте. Сейчас в npm можно опубликовать один код (например с эксплойтом), а на гитхаб другой. Большинство разработчиков будет читать гитхаб исходники и не найдут там ничего проблемного и поставят себе зависимость.


      1. jehy Автор
        23.11.2019 10:21

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


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


        1. biziwalker
          23.11.2019 23:03

          Как это Deno не узнает что его обманули? А для чего проверку загружаемых ресурсов в нем вводили (я про флаги —lock и —lock-write)?


          1. jehy Автор
            23.11.2019 23:08
            +1

            Гмм, и то правда, вроде месяц назад добавили. Ну можно поздравить ребят — они заново изобрели лок файлы....


      1. DarthVictor
        23.11.2019 13:09

        Но сейчас ничего не мешает писать в package.json вместо номера пакета из npm ссылку на коммит или ветку в git репозитории. Просто это редко используют.


      1. Lodin
        23.11.2019 14:45
        +1

        Кстати, сообщество тоже пытается решить эту проблему. Например, буквально на днях вышла бета Pika Registry, который обязуется взять на себя build-step, чтобы сделать реестр пакетов более защищённым.


      1. CoreTeamTech
        23.11.2019 17:02

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


    1. justboris
      23.11.2019 18:48
      +1

      И оно начнет расти

      Рост популярности Node можно объяснить отсутствием хороших альтернатив для серверного Javascript. Если нужно было писать на JS – брали Node. Сейчас эта ниша уже занята, и Deno придется отвоевывать кусок рынка, на что требуются большие усилия, более привлекательные ништяки. Текущие плюшки в виде Typescript недостатков пока не перевешивают.


      С точки зрения энтерпрайза, наличие Rust и TypeScript дает хороший маркетинг.

      Давайте еще ML прикрутим, неважно зачем, но маркетинга еще больше даст /s


  1. Lodin
    22.11.2019 17:48

    Всё пойдёт так как того хочет Райан. Разработчики будут заливать код компонентов на личные веб сайты, создавать папки с версиями, и все будут качать пакеты оттуда. Гмм. Мне кажется, это решительный скачок в прошлое.

    Мне это как-то это подозрительно напоминает Go, который так нравится Райану.


    1. SirEdvin
      22.11.2019 17:57

      Уже даже в Go догадались до go mod


  1. dark_ruby
    22.11.2019 18:39

    я правильно понял что они полностью отказались от v8 под капотом, и переписали JS движок на расте?


    1. jehy Автор
      22.11.2019 18:53
      +1

      Не, тот же самый v8. На расте ивент луп, системные функции и прочая обвязка.


      1. dzsysop
        22.11.2019 20:14

        возможно потом сделают обвязку для обратной совместимости с пакетами npm? :-)


  1. Gorthauer87
    22.11.2019 18:51
    +1

    Мне кажется, что круто взлетит что то в стиле node.wasm. Тогда можно будет много языков юзать без боли и страдания.


    1. megahertz
      22.11.2019 23:26
      +1

      Тут опять встает вопрос о том, а зачем городить что-то новое, если оно и сегодня работает в node.


      1. Arris
        23.11.2019 01:05

        Разве что из любви к искусству.


      1. Gorthauer87
        23.11.2019 13:25

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


    1. vanxant
      23.11.2019 02:16
      +2

      Как-то не понял смысла в node.wasm. Ну ладно браузер, там убивать жабаскрипт пытаются все кому не лень. Но вот есть у меня серверная прога на расте, плюсах или го. Зачем мне её сувать в wasm и пускать на ноду? чтобы что?..


      1. humbug
        23.11.2019 02:23

        Чтобы она работала в песочнице и не портила людям жизнь. https://medium.com/wasmer/running-webassembly-on-the-kernel-8e04761f1d8e


        1. Lodin
          23.11.2019 03:06
          +1

          Так её и так уже можно в какой-нибудь Docker-контейнер запихать?


          1. humbug
            23.11.2019 03:45

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


            1. creker
              23.11.2019 15:29

              docker имеет около нулевой оверхед и защищает от «прострела по памяти и чужим ресурсам». Так зачем нужно эту хренотень в ядро тащить?


              1. humbug
                23.11.2019 16:19

                Околонулевой оверхед хуже 10% спидапа, не?


                https://www.zdnet.com/article/doomsday-docker-security-hole-uncovered/


                1. creker
                  23.11.2019 23:17

                  Ценой вот этой фигни в ядре и усилий по ее поддержке? Ну нафиг. Не видно причин, чтобы эту вундервафлю городить. Тем более, когда речь о жалких процентах в бесполезных бенчмарках, которые ничего толкового не измеряют. Хочется оверхед ядра для сети убрать — вон, DPDK есть.


          1. Gorthauer87
            23.11.2019 13:25

            docker как мне кажется проще обходится, чем изоляция на уровне wasi.


        1. vanxant
          23.11.2019 03:20

          А в докере забанили или что?
          Если вы уж дали сервису определённые права на доступ к системе, то песочница nodejs поможет примерно никак. Про shared-хостинги для node я как-то не слышал.


        1. Viceroyalty
          23.11.2019 13:13

          Вроде бы тот же NGINX UNIT позволяет изолировать серверные процессы, или я не прав?


      1. justboris
        23.11.2019 14:05
        +2

        WASM получается кроссплатформенный. Например, libsass на плюсах можно собрать в один wasm бандл под все платформы и положить его в npm, вместо того чтобы собирать бинарник под каждую платформу.


        1. vanxant
          23.11.2019 15:21

          Ну вот это достойный пример. А то действительно, установка libsass под той же вендой довольно стрёмное занятие.


        1. creker
          23.11.2019 15:26

          Для го так себе аргумент, он кроссплатформенный по-умолчанию.


          1. justboris
            23.11.2019 15:45

            У вас собранный бинарник сможет на любой платформе запуститься, или у вас есть потенциальная возможность его под любую платформу собрать?


            Скорее всего в Go возможно второе, а с node.wasm – первое.


            1. creker
              23.11.2019 23:18

              Да, надо пересобрать. Для меня и подавляющего большинства нет никакого преимущества, что бинарник не надо пересобирать. И будет оно собираться гарантированно. Компилятор поддерживает множество комбинаций ОС и архитектур процессора.


              1. justboris
                23.11.2019 23:41

                То, что пересборка не для вас является проблемой, не означает что это работает для всех. "Подавляющее большинство" как считали?


                1. creker
                  23.11.2019 23:54

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

                  А вы сами придумайте реалистичный кейс, который потребует необходимости что-то запустить без пересборки и вот прям по-другому никак. Вопрос сам и отпадет. Я вот кроме проприетарного пакета, для которого нет исходников, ничего придумать не могу. Времена другие нынче, опен сорсные. У меня и очевидно большинства других в работе для всего есть исходники и возможность собрать так, как хочу я. Будь это C#, Go, Obj-C, swift.


                  1. justboris
                    24.11.2019 00:08

                    Я уже приводил в пример libsass: https://github.com/sass/libsass


                    Сейчас для его использования в node нужна обертка node-sass, которая во время установки модуля лезет в интернет за готовым бинарником под платформу или собирает, если бинарника не нашлось.


                    А в ситуации с WASM можно было бы просто положить бандл в npm, и он будет работать и на Windows, и на Mac, и Linux.



    1. vitaliy2
      23.11.2019 20:37

      Такое уже есть (ссылка на статью в блоге разработчиков V8 от 21.11.2019, 2 дня назад).


  1. apapacy
    22.11.2019 19:43

    Вспомнил об одном интересном движке для серверного JS https://www.nexusjs.com/
    К сожалению последний коммит в январе был.


    1. jehy Автор
      22.11.2019 20:02

      Ага. Ещё был chakra core node и spider node. Но они оба RIP.


      1. Enmar
        24.11.2019 10:55

        chakra core вроде жив.
        Коммит последний 8 дней назад:
        github.com/nodejs/node-chakracore


        1. jehy Автор
          24.11.2019 10:57

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


          На и в node-chakracore то же самое видно.


        1. sumanai
          24.11.2019 15:34

          Edge похоронили, больше некому поддерживать альтернативный движок JS.


  1. wert_lex
    22.11.2019 20:50

    А вот интересно, у них там свой компилятор тайпскрипта? Язык же довольно динамично развивается. Или внутри по-прежнему JS?


    1. anurbol
      23.11.2019 09:02

      В статье написано что в Deno встроен компилятор (он же транспайлер) тайпскрипта.


  1. humbug
    22.11.2019 21:10
    +1

    Rust. Однако, есть нюанс — в лучшем случае он будет не медленнее реализации на С++.

    А у вас есть подтверждение ваших слов, что ивент луп на расте будет медленнее? У меня есть опровержение ваших слов: https://www.techempower.com/benchmarks/#section=data-r18&hw=ph&test=fortune


    Actix на tokyo практически в два раза быстрее всех своих конкурентов.


    1. jehy Автор
      22.11.2019 21:42
      +2

      У меня есть здравый смысл. А у вас есть бенчмарк по фреймворкам, который не имеет отношения к скорости ивент лупа.


      И я не писал, что Rust реализация будет медленнее. Я писал, что в лучшем случае она будет не медленнее.


      1. humbug
        22.11.2019 21:47
        +2

        Я писал, что в лучшем случае она будет не медленнее.

        И вы ошиблись.


        Что вам говорит ваш здравый смысл? Что если раст "использует" сишный код, то он не может быть быстрее? Тогда как вы оправдаете результаты actix'а, который практически в два раза быстрее всех конкурентов?


        1. jehy Автор
          22.11.2019 21:57
          +1

          Зачем мне оправдывать результаты бенчмарки фреймворка?


          Это не имеет никакого отношения к ивент лупу.
          Даже такой бенчмарк ближе к истине.


          1. humbug
            22.11.2019 22:13

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


            1. jehy Автор
              23.11.2019 00:57
              +3

              Зато мой бенчмарк имеет хоть какое-то отношение к вопросу.
              И я его не искал, а взял первый попавшийся. В данном случае у меня просто нет "желаемого".


              Серьёзно — как на основании фреймворков можно сравнивать ивент лупы? Сравнение на основании длины бороды авторов было бы и то более релевантным.


              И ещё пара вещей, которые мне кажутся весьма очевидными.
              Вы код libuv или tokio видели?
              Там просто недостаточно простора, чтобы rust успел себя показать.
              И даже если случится алгоритмическое чудо, и растовый вариант станет быстрее, то огромное комьюнити быстро заберёт это чудо и в libuv, после чего скорость сравняется обратно.


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


              1. humbug
                23.11.2019 02:32

                Но на практике вебсервера на токио самые быстрые.
                И на практике ripgrep быстрее grep в 10 раз, но никто не спешит втаскивать изменения в grep.


                1. vanxant
                  23.11.2019 03:27

                  Ну тут еще есть такая мелочь, что сам по себе веб-сервер, если речь про динамику, отрабатывает где-то за 0.0001% времени общей обработки запроса.
                  Там по сути 2-3 syscall, расшифровка через одинаковую для всех библиотеку tls/ssl, одно обращение к структуре типа список для маршрутизации и всё — что тут можно ускорить?..
                  Всё остальное время работает программа за сервером. А для раздачи статики примерно все ставят nginx или аналог, а не пишут свой костыль (независимо от языка).


                  1. humbug
                    23.11.2019 03:52

                    через одинаковую для всех библиотеку tls/ssl

                    Почитайте https://jbp.io/2019/07/01/rustls-vs-openssl-performance.html, там результаты интересных бенчей.


                    Вот понимаете, вся проблема в том, что вы считаете, что на расте пишут обертки для готовых сишных библиотек. На самом деле на расте много чего пишут, в том числе и rustls, который быстрее openssl. Пример вкусых результатов: rustls is 30-70% quicker to resume a client connection.


                    что тут можно ускорить?..

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


                    1. jehy Автор
                      23.11.2019 10:40
                      +1

                      Насчёт грепа — скорость грепа особо не волнует, пока она приемлима. Он не создаёт нагрузку на продакшн сервера, знаете ли.


                      Пример с openssl более релевантен, хотя там тоже могут быть свои подводные камни вроде безопасности и совместимости — не готов про это говорить, тема сложная. Но рад если всё так.


                      Ну и просто хочу напоминить, что холиварю не по поводу Rust vs C++, а по поводу преимуществ Deno над Node. В конце концов, если Tokio окажется быстрее, чем libuv, или будет более быстрый любой другой компонент — его заберут в Node. Например, там недавно поменяли http parser, получив заметный прирост скорости. Правда, поломав при этом обратную совместимость, по этому поводу сейчас идёт срач, в котором даже я отметился.


                      Кстати, сравнение ивент лупов — отличная идея для поста. Напишете — сразу готов поставить плюсов, вне зависимости от результата. А пока есть только мало связанные бенчмарки. В том числе бенчмарк, который говорит, что Deno пока медленнее.


                      1. humbug
                        23.11.2019 13:33

                        Однако, есть нюанс — в лучшем случае он будет не медленнее реализации на С++.

                        Не холиварите, да?


                        1. jehy Автор
                          23.11.2019 13:36

                          Вы игнорируете 90% того, что я пишу, и спорите с вырванными из контекста кусками. На этом, пожалуй, закончу.


                          1. ZaMaZaN4iK
                            23.11.2019 15:39
                            -2

                            Да это просто у очередного растомана полыхнуло, что кто-то Rust не боготворит и не соглашается со мнением, что надо всё на Rust переписывать в 2019 году :)


                            1. codemafia
                              23.11.2019 16:11

                              То же самое говорят о PHP каждый год, а он пахнет и цветет.


                              1. 0xd34df00d
                                23.11.2019 17:08
                                +2

                                Сосед по общаге как-то борщ оставил на окне на все летние каникулы, так борщ тоже пах и цвёл.


                  1. apapacy
                    23.11.2019 12:31

                    https://github.com/fukamachi/woo ускоряют довольно существенно. На уровне когда из tcp получают http


            1. miraage
              23.11.2019 06:17

              Синтетические тесты не имеют прямого отношения к производительности реальных приложений.


      1. SirEdvin
        22.11.2019 23:00
        +1

        И я не писал, что Rust реализация будет медленнее. Я писал, что в лучшем случае она будет не медленнее.

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


        Поэтому выражение "программа на rust не будет быстрее С++" сильно похоже на софистику, так как вы никто не будет дословно переписывать написанное на С++ на Rust.


        1. prostofilya
          23.11.2019 06:34

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


          1. sumanai
            23.11.2019 19:48

            И вообще не важно какой там код.

            Но ведь важно. А то я на асме напишу код медленнее и прожорливее, чем на PHP.


            1. prostofilya
              23.11.2019 20:38

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


    1. QGorbovsky
      22.11.2019 21:52
      +2

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

      А так — автор все правильно сказал, растовая реализация будет такой же производительной как на С++, но никак не быстрее.


      1. humbug
        22.11.2019 21:58
        +3

        Почему не может быть быстрее? :) какие ваши аргументы кроме личного мнения?


        1. defuz
          22.11.2019 22:36
          +5

          Многие искренне верят что не может быть ничего быстрее C/C++ просто по определению.


        1. QGorbovsky
          22.11.2019 22:53
          +2

          На одном из С++ Russia и на Code Hard выступал представитель России в кометете по стандартизации С++ — Антон Полухин и там он показывал сгенерированый ассемблер для одинаковых программ написаных на Rust в растовом стиле и на С++ в стиле С++, и получалось, что Rust добавляет больше инструкций чем С++. Были включены флаги оптимизации для обоих компиляторов, потому есть смысл им доверять.

          Потому пока С++ будет не медленнее от Rust. Что будет потом — посмотрим.


          1. slonopotamus
            22.11.2019 23:07
            +3

            Для каждой программы на Rust можно написать по меньшей мере настолько же быструю программу на C++ потому что некто Полухин показал одну программу на Rust, которая была медленнее программы на C++? В этом нет логики.


            1. QGorbovsky
              22.11.2019 23:25

              Возможно, не сильно знаком с Rust, но тогда будет вопрос: а сколько там будет unsafe, и на сколько это будет Rust-way?

              И он рассматривал, как генерится асм для С++ и Rust, и объяснял что к чему, вот ссылка на момент доклада: где он рассказывает об этом.

              На истину я не претендую, но ему доверяю.


              1. vintage
                23.11.2019 10:30
                +1

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


                1. за сохранени/восстановление регистров отвечает вызывающая функция.
                2. за сохранени/восстановление регистров отвечает вызываемая функция.
                3. часть регистров сохраняет/восстанавливает вызывающая функция, а часть вызываемая.

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


                Про сборщики мусора у него тоже какое-то очень поверхностное представление. Банально, он даже не понимает, что основная задача сборщика мусора, — это именно обнаружение недостижимой памяти с циклическими зависимостями. Без циклических зависимостей и обычный ARC замечательно справляется.


              1. ZaMaZaN4iK
                23.11.2019 15:52
                +1

                Я бы на Вашем месте не полагался на этот доклад в качестве пруфов в спорах вида «Rust vs C++ с точки зрения производительности генерируемого кода» в виду того, что это некачественный материал просто :)

                Меня всегда расстраивает, что в спорах подобного вида мы бенчим один и тот же бэкенд. Зачем так делать? Гораздо полезнее с практической точки зрения делать бенчи вида «rustc vs gcc (vs ещё что-нибудь — можно icc и aocc попробовать)». И смотреть результаты уже.


          1. humbug
            22.11.2019 23:18
            +1

            У нас с ним был диалог, в котором мы выяснили, что Антон написал не совсем аналогичный код. Можно написать и 1в1:


            https://t.me/ProCxx/343422


            Опять же, если раст не может быть быстрее, почему actix обогнал всех в бенчах? Вы не чувствуете противоречие?


            1. Gorthauer87
              23.11.2019 13:43
              +1

              Он там не только в этом месте чушь несет, например про Send Synс он похоже вообще не в курсах.


          1. DarthVictor
            23.11.2019 13:31

            Мне сомнительно, что сейчас компилятор Rust обходит C++ в задроченности на числодробильные оптимизации, но

            Rust добавляет больше инструкций чем С++

            Так себе аргумент. Один промах мимо всех кешей — это примерно сотня инструкций. В то время как всякие проверки за выход из массива — это ноль инструкций (причем не примерно) в современных предсказателях ветвлений.


            1. creker
              23.11.2019 15:19

              С учетом общего бэкэнда разницы особо не должно быть наверное.


              1. ZaMaZaN4iK
                23.11.2019 15:47

                Это если мы говорим про один бэкенд — LLVM. Не стоит забывать, что у плюсов так-то есть ещё как минимум один нормальный, который GCC.

                Но даже на одном и том же бэкенде мы можем получить разные результаты на казалось бы аналогичном коде за счёт того, что фронтенд прокидывает больше информации бэкенду, что позволяет ему лучше оптимизировать. Типичный пример: alias analysis, который в Rust намного легче сделать за счёт правил самого языка, что очень неплохо помогает в оптимизации. А вот C++ до сих пор (и это просто отвратительно) не имеет ничего подобного на уровне языка (не считая strict aliasing) — там нельзя ручками по стандарту разметить restrict.


                1. creker
                  23.11.2019 23:23

                  Последний раз, когда я смотрел, разница между LLVM и GCC была пренебрежимо мала.

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


                  1. 0xd34df00d
                    24.11.2019 03:30
                    +1

                    Но изначальный пост был о числодробильных оптимизациях, где выхлоп IR не особо должен быть принципиален. Трюки и оптимизации раст и С++ должны получить одинаковые.

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


                    1. creker
                      25.11.2019 12:42
                      +1

                      habr.com/ru/company/otus/blog/442554 вот это? Я бы сказал, что тут не алиазинг сам по себе виноват, а ущербная система типов С++ и формулировки в стандарте. Как следствие этого сработали правила алиазинга, не позволив компилятору оптимизировать код.

                      А так да, вполне пример, что скорее С++ получит меньше оптимизаций, чем раст, из-за своего С наследия.


                  1. ZaMaZaN4iK
                    25.11.2019 03:43

                    Последний раз, когда я смотрел, разница между LLVM и GCC была пренебрежимо мала.

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

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

                    Это не совсем правда. На числодробление (а конкретно работу с памятью) алиасинг очень даже может повлиять. А ещё этот самый алисинг может мешать проведению других оптимизаций (тут мне сложно говорить со знанием дела, так как я не являюсь разработчиком GCC/LLVM и не разбираюсь в зависимостях между проходами компилятора сильно).

                    Но если мы говорим за пределами алиасинга, то скорее всего оптимизационные способности должны быть более-менее идентичны.


                  1. erlyvideo
                    25.11.2019 09:52

                    > изначальный пост был о числодробильных оптимизациях,

                    числодробильные оптимизации очень давно делают, используя специальную аппаратуру.

                    Например, блок SSE/AVX инструкций или что-нибудь типа CUDA.

                    Роль центрального процессора с его обобщенной системой команд не числа молотить, а логику проворачивать. А её сложнее писать, чем исполнять.


                    1. creker
                      25.11.2019 12:26

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


      1. 0xd34df00d
        23.11.2019 03:27

        Я периодически на работе развлекаюсь тем, что пишу всякую низкоуровневую ерунду на C++, и… Ну, короче, приходится полагаться на компилятор почти как в хаскеле, если я хочу писать код без UB. В частности, полагаться на


        • элайдинг memcpy для преобразования репрезентаций объектов
        • элайдинг placement new + memcpy для правильного начала времени жизни объекта, представление которого считано из файла
        • элайдинг вызова деструкторов для trivially destructible-типов (который надо делать для корректного завершения их лайфтайма)

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


  1. jehy Автор
    22.11.2019 21:41

    Не туда ответил.


  1. titulusdesiderio
    22.11.2019 22:36
    +6

    про зависимости расскажу историю из go
    получил я в поддержку проект в котором зависимость на удалённую github библиотеку. и всё эта особенность полностью парализует работу над проектом и его поддержку.
    отсутствие npm как преимущество? это огромный недостаток!


    1. vintage
      23.11.2019 10:37

      Почему парализует-то?


      1. titulusdesiderio
        23.11.2019 10:59

        а как сбилдить код, если пакета, от которого он зависит, не существует?


        1. vintage
          23.11.2019 11:16
          -2

          Ну так, форкнуть надо было. А то и включить в свой репозиторий, через git-subtree.


          1. titulusdesiderio
            23.11.2019 11:24
            +5

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

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


            1. vintage
              23.11.2019 11:40
              -4

              И форкаю, и даже пулреквесты постылаю. А вы пулреквесты без форканья делаете? Или только пользуетесь чужими трудами?


              В любом случае, вы зря прицепились к самому слабому решению и проигнорировали нормальное.


              1. titulusdesiderio
                23.11.2019 11:42
                +1

                форкаю тогда, когда нужно внести изменения (например фиксы). и да, пулреквесты шлю.
                а какое нормальное решение я проигнорировал?


                1. Nikelandjelo
                  23.11.2019 12:02

                  Насколько я понял нужно послать по пулреквесту во ВСЕ зависимости. Тогда все зависимости будут форкнуты на предыдущем шаге и останется только обновить проект указав на форки. Вуаля...


                  1. titulusdesiderio
                    23.11.2019 12:12
                    +2

                    Авторы пакетов которые мы так форкнем сами ничего не форкают. А значит нужно форкнуть ещё и все зависимости зависимостей. А потом и зависимости зависимостей зависимостей (:


                    Скажите честно вы так делаете? Вам не кажется что это забивание гвоздей микроскопом? У разработчиков давно есть инструменты которые решают проблему зависимостей без этого ручного геморроя — npm.


                1. vintage
                  23.11.2019 12:10
                  -2

                  Там все два предложения написано. Не поленитесь, перечитайте.


                  1. titulusdesiderio
                    23.11.2019 12:48

                    Как включить в свой репозиторий, репозиторий которого нету?


                    1. vintage
                      23.11.2019 12:55
                      -4

                      Теперь-то уже никак. А как leftpad установить, которого уже нет?


                      1. titulusdesiderio
                        23.11.2019 13:59
                        +6

                        npm install left-pad


                        как раз эта проблема и была решена после случая с left-pad. а автор Deno предлагает отказаться от этого решения и вернуть себе старую боль


                    1. Alexufo
                      23.11.2019 13:17

                      Неужели форка нет? Случайно их много кто делает


                      1. titulusdesiderio
                        23.11.2019 14:00

                        конкретно в тот раз решилось через обращение к автору удалённой либы. он порылся у себя на компе и выслал мне код


            1. vsb
              23.11.2019 14:38

              Я пишу на Java с Maven и есть требование собирать проект без интернета. Поэтому вместе с проектом есть сохранённая копия ~/.m2/repository которую можно развернуть на любой машине. В том числе там есть архивы с исходниками, если вдруг нужда будет, можно пересобрать. Возможно в Go можно использовать подобный подход — просто сохранить все кеши как артефакт вместе с релизом.


              1. titulusdesiderio
                23.11.2019 16:46
                +2

                ваше решение = исключить node_modules из .gitignore
                но серьёзные дяди используют более серьёзное решение — локальное зеркало npm с необходимыми пакетами.


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


                1. vintage
                  23.11.2019 17:12
                  -1

                  1. titulusdesiderio
                    23.11.2019 17:28
                    +1

                    сразу оговорюсь, что я искренне надеюсь что этот сервис взлетит. Но он только-только появился (2019 год) и не имеет серьёзного проникновения в индустрию. говорить о нём всерьёз рано


                    Но Deno не предлагает github packages в качестве хостинга пакетов. он как и го, предлагает отказаться от хостинга пакетов в пользу хостеров репозиториев.


                    кстати, а гитхпакеты защищены от удаления репы? нашёл ответ сам


                    To avoid breaking projects that may depend on your packages, you cannot delete an entire public package or specific versions of a public package.

                    кстати github packages ничем не отличается от npm в плане защиты от расхождения между кодом репы и кодом пакета. так что это те же яйца только в профиль


                1. creker
                  23.11.2019 23:26
                  +1

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


              1. creker
                23.11.2019 23:28

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


                1. titulusdesiderio
                  24.11.2019 15:18

                  если я правильно вас понял, вендорить — исключить node_modules из .gitignore


                  1. creker
                    24.11.2019 15:26

                    Я не знаком с тонкостями ноды, но да, наверное это примерно похожие вещи. Так то и в Go с менеджером пакетов вроде godep можно было vendor добавить в игнор, но тогда каждый билд бы тащил все с интернета с угрозой сломать билд, если что-то где-то исчезнет. Поэтому принято было vendor папку все таки включать в репозиторий. Так получаются стабильные offline билды. Да и медленно каждый раз качать все зависимости. С модулями разработчики собрались полностью исключить поддержку vendor папки, но сообщество таки убедило, что людям это нужно.


  1. funca
    23.11.2019 00:46

    Как говорится Make it work, make it right, make it fast — нормальное решение выходит с третьего раза. Мне кажется подход Райна к разработке состоит в том, чтобы соединив вместе несколько хорошо зарекомендовавших себя технологий из разных областей, получить новое абсолютно бомбическое решение.


    Первым была Node.js, собранная из того, что было: asyncio, libuv, V8, commonjs, streams. Много, что работает, но все сложно. Ацкий комбайн с кучей тех.долга. Как говориться — не пытайтесь повторить.


    Dyno это попытка сделать удобный инструмент. Node.js сильно провязан с V8, отсюда проблемы с портированием на другие движки и обновлением рантайма. В Dyno весь такой низкоуровневый интим живёт в отдельном загончике — "ядре" — с которым остальной мир — "юзер спейс" — общается лишь протобуфами. Отсюда полный контроль над IO и вообще всем тем, что делает программа. По аналогии с браузерами, весь API четко специфицирован и доступен через общий объект Dyno. Адресация зависимостей декларируется с помощью URI как в XML, есть возможность контролировать мапинг на физические ресурсы. Встроенный бандлер для сборки приложения в исполняемый файл или модуль, как в go. Тайпскрипт, форматтер кода, куча отладочных флажков и данных — все как любят разработчики.


    1. evocatus
      23.11.2019 01:55
      +2

      У него комплекс Тараса Бульбы («я тебя породил, я тебя и убью») и непонимание того, что если один раз повезло и Node.JS «выстрелил», то это не значит, что «выстрелит» снова; что успех Node ему не принадлежит, им не определяется, и, возможно, случился не по тем причинам, по которым он думает сейчас или думал тогда. И т.д. и т.п. А в общем это всё также смешно как нынешние попытки Тима Бернерса Ли и Роба Пайка (см. upspin) воевать с тем, во что превратился Интернет, Джимми Уэлса — с Facebook и пр.


      1. jehy Автор
        23.11.2019 10:08
        +1

        Мне кажется, всё прозаичнее — Райан фактически продал ноду в Joyent, а сейчас хочет повторить успех, и продать снова или себя или движок, пользуясь культом личности себя.


        1. funca
          24.11.2019 12:34
          +1

          Есть люди, которые придумывают концепты, а есть те, кто доводит до ума. Первые версии node.js на практике тоже были полным отстоем. Что за привычка искать везде культ личности? Есть просто парень, который не прекращает генерировать идеи даже после того, как несколько из них оказались успешными.


  1. arvitaly
    23.11.2019 02:27

    NPM как монопольное регистри.

    Это уже не так.


    1. jehy Автор
      23.11.2019 10:06
      +1

      Да, голосом я про это говорил, а в статье не упомянул. Но в целом появление гитхаб регистри мало что поменяло — можно было и до этого прекрасно ставит пакеты с гитхаба, используя теги или в худшем случае кеши. Минус только один — это не прокатывало для пакетов с этапом prepublish.


  1. vintage
    23.11.2019 09:18
    -3

    Lock file обеспечивает воспроизводимые сборки.

    Расскажу вам несколько страшных историй про "воспроизводимость":


    1. Для корпоративного скоупа был прописан приватный репозиторий, доступный только через корпоративный VPN. Но через корпоративный VPN недоступен публичный репозиторий. В результате работая удалённо невозможно поставить модули, так как оба репозитория не доступны одновременно.


    2. В одной ветке был установлен один модуль, в другой — другой. Обе ветки смержили в мастер без конфликтов. Билд упал. Разработчику пришлось выкачивать к себе и обновлять лок-файл.


    3. Добавили новую зависимость. Это вызвало каскадное обновление непредсказуемого набора непрямых зависимостей. В результате сборка сломалась. На выяснение что там с чем не совместимо потребовалось пол дня. Как итог — полный откат.


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



    В гробу я видал это "элегантное" решение.


    1. Gugic
      23.11.2019 09:33

      Мне кажется Райан, как гугловец, безнадежно «укушен» логикой монорепозитория. В котором каждый конкретный CL действительно описывает весь «мир» со всеми зависимостями и в котором воспроизводимость сборки поставлена на одно из первых мест. Собственно вся специфика работы с модулями раннего Go происходит ровно из этого же монорепозитория.


    1. slonopotamus
      23.11.2019 10:01
      +3

      2, 3 и 4 не являются спецификой локфайлов и всё то же самое могло произойти с любым другим файлом. Решение — проверять что код работает перед пушем.


    1. jehy Автор
      23.11.2019 10:03
      +4

      Чисто для справки — в одном из моих проектов сейчас 10.000 транзитивных зависимостей. Так что я знаю, о чём говорю.


      Относительно ваших кейсов:


      1. NPM виноват в настройке вашего VPN? А чем бы вам помог другой менеджер пакетов? Так проблема хотя бы решается при помощи переключения, прокси регистри или локального кеша нужного пакета. А вот в случае с deno — я не уверен, что проблему вообще было бы возможно решить — возможно, приложение бы падало, ничего не установив… Ну а в лучшем случае точно так же пришлось бы переключаться.


      2. Ну так стандартная проблема мерджа. С кодом случается ровно то же самое.


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


      4. Опять же это обычно сразу видно на код ревью — ты мгновенно замечаешь, что был закоммичен левый пекедж лок. Хотя нет. Даже раньше. Если пользуешься npm ci на билд сервере, то он сразу расскажет про расхождение package.json и package-lock.json.



      Ну и главное. Я не говорю, что решение идеально. Просто всё познаётся в сравнении. И из всего того дерьма для управления зависимостями, с которым я работал последние 10 лет, npm — просто конфетка. А в данном посте я говорю даже не про это, а про сравнение npm с тем, что придумали в Deno.


    1. ratijas
      23.11.2019 10:09
      +2

      1. Используйте локальное корпоративное зеркало npm, куда выкачиваются все зависимости из настоящего npm по необходимости.


      2. Проблемы git merge не уникальны для npm lock file :)


      3. Всё так. К сожалению, нет вменяемых способов подключить две разные версии одной либы сразу.


      4. Проблемы git submodules не уникальны для npm lock file :)



      1. titulusdesiderio
        23.11.2019 10:38

        3. разве через алиасы это не решить?


      1. vintage
        23.11.2019 10:46
        -2

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

        Есть: https://habr.com/ru/post/456288/


  1. justboris
    23.11.2019 14:26
    +1

    6) Require без расширения и его неопределённость. Да, наверное, плохо. Но не настолько, чтобы об этом упоминать…
    7) index.js как лишнее усложнение. Тоже слишком тривиальный и скучный пункт, чтобы его описывать.

    Стоит заметить, что эти аспекты пофиксили в режиме ES-модулей. В них убрали автоподстановку расширения и index.js файлов. Нужно теперь указывать явный путь до файла с раширением:


    https://nodejs.org/api/esm.html#esm_differences_between_es_modules_and_commonjs


    P.S. ну и в принципе в этом списке нет таких пунктов, которые нельзя было бы пофиксить без переписывания всего с нуля


  1. jamak
    24.11.2019 18:38
    -2

    Автор, у меня горит с твоих рассуждений,
    и так, начну сначала,

    Однако я нигде так и не видел сколько-нибудь вдумчивого разбора этого проекта — почему-то все ограничиваются переводом документации...

    Эта статья, так же как и твои доклад, является таким же переводом, в которые ты вложил свои додумки, реально, очень много ошибок,

    Кстати, заметьте, я говорил, что Райан сожалеет о 10 вещах, а пунктов всего 7. Это не ошибка, я несколько раз пересматривал его доклад, и обзоры доклада.


    Пересмотри ещё раз, и обрати внимание на пункты в package.json и index.js, особенно посмотри доклад, который был в бруклине.

    В итоге я просто не вижу смысла в использовании Deno. Терпеть не могу позицию «не пробовал, но осуждаю» — но, пока что даже Райан говорит, что Deno ещё сырой — поэтому пробовать я его не стал.


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

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

    Автор, жирный минус за статью.

    Могу развеять твои сомнения и додумки в чатике, t.me/denoland


    1. jehy Автор
      24.11.2019 20:45

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


      1. jamak
        24.11.2019 21:36
        -5

        Да, и по всей видимости вы молоды для написания статей, но уже стары для их обсуждения.

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


        1. murzilka
          24.11.2019 22:48
          +4

          Просветите других. Напишите статью, правда. Заодно десять пунктов укажете вместо семи. Искренне надеюсь в ближайшие дни увидеть статью от вас


          1. jamak
            25.11.2019 02:52

            К сожалению, готовлю сейчас другую статью, но тем не менее, думаю после него приступлю к Deno.
            ну а пока могу оставить ссылку на gist 9 месячной давности, в котором я собирал материалы
            gist.github.com/irustm/fe60d7d91238ba3d30d5ddd7320309aa


          1. amakhrov
            25.11.2019 03:24

            Или хотя бы кратко в комментариях тут.
            Аргументы автора против Дино звучат разумно. Я был бы рад ознакомиться с аргументами ЗА Дино, пусть и тезисно.


  1. Grikdotnet
    26.11.2019 12:15

    По статье делаю вывод, что Deno — это именно та эволюция ноды, которая стала интересной.
    Все аргументы сводятся к тезису «Это неправильная нода, она делает неправильный мед».

    Я смотрю с точки зрения enterprise. Как это в Java, Python, Golang, даже в PHP.

    1. NPM — это SPF, это просто не проходит по SLA. С прямым импортом удобно делать свой репозиторий. Будет обертка, как composer в PHP.
    2. NPM за периметром безопасности, исходящий трафик за фаервол открывать никто не будет. Без вариантов, никаких скачиваний пакетов со стороны при сборке.
    3. TypeScript хорош. Никто не хочет писать на JS после Java или Golang, а на TS — вполне.
    4. Никого не смущает связь парсера Java с Runtime — это самая популярная в мире платформа. Наоборот, такую связку проще поддерживать, меньше невоспроизводимых багов.
    5. Кеширование результата компиляции в файлах или в памяти — детали реализации. Python и Java не страдают.

    И так далее. Каждый тезис в этой статье — в пользу Deno.