Deno: время Node.JS уходит?
- суббота, 23 ноября 2019 г. в 00:28:57
Прошло примерно 18 месяцев с внутреннего релиза Deno, вышел preview release, появилось несколько статей на Хабре, и Райан ездит по конференциям и рассказывает о нём. Однако я нигде так и не видел сколько-нибудь вдумчивого разбора этого проекта — почему-то все ограничиваются переводом документации...
Что же, давайте попробуем это сделать сейчас. Последние 5 лет я пишу на Node.JS, а компания OneTwoTrip, где я сейчас работаю, пишет проекты на ноде около 9 лет (да, это я писал историю про 9 лет в монолите на ноде). Так что анализ должен выйти неплохой. Тем более что я его уже рассказал на Moscow Node.JS Meetup 10, и было интересно. Кстати, если вам удобнее слушать, а не читать, то послушать и посмотреть можно вот тут. Моё выступление второе, я чувак в розовой рубашке.
Как ни странно, для того, чтобы понять, откуда и зачем возник проект, надо провалиться в прошлое. Так что вкидываем немного плутония, поднимаем двери нашего делореана, и пускаемся в путешествие — посмотрим на важные 10 лет, которые сделали Node.JS такой, как мы видим сейчас.
Райан Дал анонсирует Node.JS, вот она — самая первая презентация на JSConf 2009.
Появляются express, socket.io — основные на текущий момент кирпичики почти любого сервиса.
Появляются сумасшедшие люди, которые реально пишут на этом серверный код!
С Node.JS начинают заигрывать крупные ребята — в том числе Uber и Linkedin.
Релиз npm 1.0.
Node начинает работать на Windows.
Райан уходит от разработки Node.JS. Запомните. Это был 2012 год. Так что Райан безусловно является создателем, и многое сделал для экосистемы — но последующие 7 лет прошли без его участия.
Node в Paypal, Walmart, eBay.
Появляется Koa — помните, сколько копий было сломано о генераторы?
Node в Netflix. Начинаются попытки оформить проект в что-то более взрослое, с открытой моделью управления консультативным советом. Наблюдается техническая стагнация, приведшая к появлению форка io.js.
Работа над ошибками. Слияние io.js и Node в экстазе под эгидой Node Foundation и выход Node 4. Надо сказать, именно эту версию я считаю первой, на которой реально можно было что-то разрабатывать. Если кто писал на версиях 0.xx — то вы помните про var, callback hell, кучу разных библиотек для упрощения асинхронной работы (вроде step и async. Да, async — это не только async await, но ещё и npm библиотека).
Инцидент с leftpad, который до сих пор злые языки припоминают экосистеме. Сколько же было статей и нападок. Ну, haters gonna hate. Однако, важные уроки из этого были вынесены.
Прорывной год. Я не буду упоминать все релизы ноды и рост количества установок модулей с npm, однако именно в этом году количество сервисов на Node.JS превысило 8 миллионов, а количество установок — 3 миллиарда в неделю. Абсолютно космические цифры, которые сложно даже представить.
Так же появился N-API, и Node.JS был снова форкнут в Ayo.js. Очень смешная и поучительная история про SJW — она стоит отдельной статьи, поэтому не буду на ней останавливаться — просто рекомендую прочитать на досуге. Только проспойлерю, что форк благополучно умер.
Вторая массовая истерия со времени leftpad — теперь про то как event-stream ворует биткоины. Сотни постов про небезопасность экосистемы. Посты-фантазии про то как npm пакеты воруют данные кредитных карт. Комьюнити поливают грязью как из шланга. Надо сказать, это было очень полезно, и выводы так же были сделаны — о них чуть позже.
Так же Райан внезапно взрывает комьюнити постами про то, что серьёзные сервисы стоит писать на Go, описывает 10 вещей в Node, о которых он сожалеет, и анонсирует Deno, который решает все проблемы.
Deno выходит в preview release, появляется куча статей на хабре, и вот вы сейчас читаете одну из них.
Надеюсь, после этой экскурсии стало более понятно, какие были больные места у экосистемы, и как она развивалась — имея данный контекст, гораздо проще понимать, что происходит сейчас.
К сожалению, я не нашёл навскидку статью с переводом доклада, так что перечислю их здесь вкратце, и здесь же откомментирую.
Кстати, заметьте, я говорил, что Райан сожалеет о 10 вещах, а пунктов всего 7. Это не ошибка, я несколько раз пересматривал его доклад, и обзоры доклада. То ли это была сложная шутка на тему обработки числовых значений, то ли Райан просто постеснялся назвать ещё 3 пункта...
Но ладно, поняли, какие проблемы, поехали дальше. Логично, что в Deno Райан решил избавиться от всех проблем Node.JS. Посмотрим, что у него вышло.
На первый взгляд звучит неплохо, однако рассмотрим эти пункты ближе.
Rust. Не, прошу понять меня правильно — я считаю, что Rust и Go это прекрасные языки, и я искренне рад, что они есть. Они дают возможность писать низкоуровневый код быстрее и безопаснее, чем на С++. Однако, есть нюанс — в лучшем случае он будет не медленнее реализации на С++. Так что смысла писать полный аналог системных обвязок и ивент лупа лично я не вижу — вряд ли это может принести какую-то реальную пользу, поскольку это те вещи, которые в какой-то момент просто доходят до оптимального состояния, и дальше фактически не оптимизируются.
TypeScript. Опять же — я ничего не имею против TS. Его использует огромное количество компаний и разработчиков, и он уже показал свою состоятельность. Но Deno всего лишь прячет транспилятор в бинарник, а транспилированный код — в особые директории. То есть под капотом происходит всё то же самое, и выгоды в этом нет, за исключением эстетической. Зато есть минус — версия транспилятора оказывается намертво прибита к версии Deno. Не уверен, что это хорошо — легко представить себе ситуацию, когда вам хочется обновить либо транспилятор либо рантайм. Но не и то и другое сразу.
Так что пока ничего вкусного не видно. Пойдём дальше, заглянем в основные фичи.
То есть, код выглядит примерно так:
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");
});
При первом запуске код загружается и кешируется, а потом используется кеш. Версионность поддерживается при помощи указания версии в урлах. Не знаю, почему это вызывает у всех столько восторга. Я вижу всего два варианта развития событий:
Отдельного рассмотрения стоит вопрос воспроизводимых билдов. Поскольку никто не гарантирует, что вы скачаете с какого-то левого сервера одно и то же (в особенности если не указали в урле версию) — то Райан предлагает… Хранить исходный код импортируемых пакетов в репозитории проекта… На дворе точно 2019? Может, Райан не в курсе, что с 2012 года в Node.JS появился сначала shrinkwrap, а потом lock file? Которые решают эту проблему гораздо проще, нагляднее и экономичнее?
На мой взгляд, загрузка модулей по URL — очень странное и спорное решение, основное достоинство которого — вау эффект для джуниор разработчиков.
В целом круто, да. Но с 2012 года утекло реально много воды — и в ноде все вменяемые библиотеки давно работают на промисах. И даже системные библиотеки на них почти переползли. Поэтому это сложно считать каким-то конкурентным преимуществом.
Странно видеть это в списке значимых отличий. В Node.JS вы можете делать ровно то же самое. Если вам это нужно.
Да, хорошо, что бэк и фронт переходят на один формат. Но знаете, в Node.JS сейчас тоже есть поддержка ES Modules...
Звучит классно! Но реализация… Реализация — это просто набор флагов allow-read, allow-net, allow-run, allow-env. Выглядит это как-то так:
deno --allow-read=/etc https://deno.land/std/examples/cat.ts /etc/passwd
Это опять же вызывает у меня вопросы:
Ну и в целом мне хотелось напомнить, что произошло с npm с 2012 года:
А главным достоинством npm я считаю… То, что его в любой момент можно выкинуть из экосистемы. Есть протокол, есть клиенты, есть другие регистри… Как только "Акела промахнётся", любая большая компания может поднять альтернативный регистри — facebook, google, microsoft, gitlab… Пока что этого не случалось ровно по той причине, что npm работает достаточно стабильно и отвечает потребностям сообщества.
Пройдём по пунктам:
В итоге я просто не вижу смысла в использовании Deno. Терпеть не могу позицию "не пробовал, но осуждаю" — но, пока что даже Райан говорит, что Deno ещё сырой — поэтому пробовать я его не стал.
Однако я очень хотел найти антагониста, который бы сказал мне, что я не прав, что Райан сделал крутую штуку, и что я не понял её применения. Я много обсуждал Deno с коллегами, друзьями, и рассказывал всё это на Moscow Node.JS Meetup — и никто не высказал мне альтернативного мнения. Отчасти поэтому я пишу статью на хабр — скажите, может я всё же что-то не понял или не заметил?