Предисловие
Я не часть команды 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. Разве что его агрессивных пиарщиков :)
k12th
Это, конечно, удобно если в одном файле можно использовать некий libjs 1.x, а в соседнем libjs 2.x — но исключительно на стадии прототипирования. В долгосрочной поддержке это только головная боль.
vvadzim
В долгосрочной поддержке это будет запрещено линтером.
k12th
Линтер это хорошо, но по факту далеко не во всех проектах он есть.
slaFFik
Если проект долгосрочный — он обязан использовать линтер. Иначе ССЗБ.
printf
Линтер это тулинг, который тоже надо конфигурировать, встраивать в процесс CI и поддерживать. Т.е. цена этого решения ненулевая, а выигрыш, как по мне, стремится к нулю (особенно если мы всю предоставляемую такими импортами гибкость зарубаем в итоге линтером).
Еще один момент это аудит кода. В npm или yarn очень легко получить ответ на вопросы:
yarn why
)Для этого не нужно парсить никакой код, загрузил один json-файл и всё. Работает быстро в проекте любого размера.
А еще бывают devDependencies и peerDependencies, которые не присутствуют в рантайме — как это в Deno реализовано я не знаю, поэтому ничего утверждать не стану, кроме того, что это очень нужная на практике штука.
Kozack Автор
Deno как и NodeJs — это среда исполнения. Для NodeJs существует отдельная утилита — пакетный менеджер — npm. Она берет на себя роль управления всеми зависимостями, не только для рантайма, а в целом по проекту, их обновлением и всё в таком духе.
Deno не поставляется со своим аналогом npm. И хотя возможно устанавливать отдельные утилиты в директорию проекта, это сложно назвать полноценным пакетным менеджером.
Но, народные умельци уже написали несколько утилит:
printf
Одно из преимуществ Deno, которые мы тут обсуждаем — отказ от npm, package.json и node_modules, а пол-коммьюнити тем временем пишет множественные аналоги npm, да придумывает свои несовместимые форматы а-ля package.json, например dem.json. Так не победим!
Поймите правильно, мне нравится Deno. TypeScript это клёво, настройки безопасности это клёво. Но вот эта штука с импортами — не пришей нигде рукав.
Kozack Автор
Ну, не совсем.
npm — менеджер пакетов. Ряд озвученных вами вопросов, действительно стоит остро, и утилиты, для анализа всей кодовой базы или какой-то части и вывода статистики по всем зависимостям по модульно действительно не хватает. И, если будет потребность, то такие появятся. Но текущие реализации, я думаю, жертвы привычки.
package.json — Можно назвать глобальным конфигом для всего проекта. В нем и название, и версия, и зависимости, и инструкции по сборке, и имена авторов и все все все. Deno предлагает перенести список зависимостей из глобального реестра непосредственно в кодовую базу. Но, это не означает, полный отказ от глобального файла с конфигурацией проекта. Вполне может существовать какой-то package.json с названием, списком авторов, какими-то ссылками на документацию, репозиторий, лицензию, списком точек входа для запуска тестов или самого приложения.
Сейчас Deno и его сообщество в зародыше. Лучшие практики ещё не выработаны, инструменты не написаны.
Может и так. Лично я пока не вижу тут проблем. Но, справедливости ради, я и не искал особо. Мне видится тут больше гибкости. Вы пишите что-то простое? Вам не нужно заворачиваться с установкой зависимостей локально. Просто пишите код. Работаете над чем то побольше? Создайте свой реестр зависимостей. Со временем появятся инструменты для их анализа.
printf
Да, согласен, надо поработать с этим. Сам еще не переносил ничего толком на Deno, так, поглядываю в документацию немношк.
Попробую какую-нибудь мелочь портировать на выходных.
nin-jin
А зачем что-то разрешать, что потом ещё нужно запрещать отдельными линтерами?
Kozack Автор
Весь JavaScript так работает :)
nin-jin
У JS тяжёлое прошлое. Меня больше удивляет, когда сейчас разрабатывают новый язык позволяющий писать и так и эдак и тут же к нему прикладывают линтер, который не позволяет писать эдак, и форматтер, который форматирует именно так. Привет, Go.
Kozack Автор
А я вот понимаю такой подход. Сделать гибкий язык который может работать как угодно и предоставить инструмент, чтобы каждая команда могла "донастроить" его для своих нужд. Мне больше нравится когда всё строго, когда имена файлов и структура директорий жестко регламентирована интерпретатором. Но, как ты не крути, это нужно не всегда и часто в разном виде.
nin-jin
Да никто не занимается такой ерундой, как форканье гоформатера с целью "донастройки" для "своих нужд" (будто в них есть что-то особенное). Никому такой бардак не нужен.
Kozack Автор
Я имел в виде существование линтера в целом. то о чем вы писали
Есть, язык, который может работать как угодно. И есть инструмент, который можно настроить так, чтобы он ограничивал разработчика и принуждал его писать только эдак.
А вот настроить эти ограничения каждый может так как нужно именно ему. Что гораздо гибче.