Несколько лет назад на JSConf 2018 выступил Райан Даль, создатель Node.js. Его доклад вызвал сенсацию, он затронул много актуальных проблем и поднял громкий хайп, не оставив равнодушным практически никого, кто связан с серверным программированием. В его обсуждении бэкэнд программисты разделились на два лагеря: одни отстаивали Node.js, другие прочили ему скорую смерть.
С момента выступления Райана прошло немногим больше двух лет, а в IT это целая эпоха, за время которой может поменяться еще не все, то очень многое. Давайте вспомним этот доклад и попробуем посмотреть, что изменилось с тех пор, кто был прав.
Немного про Node.js
Однажды, когда Райан загружал фотографии на Flickr, он заметил необычную вещь — индикатор, который наглядно показывал процесс загрузки фотографий на сервер. Сейчас никого не удивить прогресс-баром, а тогда такие интерфейсы еще не были распространены и, обычно, пользователь наблюдал гифку с банальными песочными часами, которые просто крутились и не давали никакой информации об оставшемся времени завершения операции.
Тогда он задумался о том, что веб-сервер должен уметь обрабатывать одновременно несколько задач. В то время Райан разрабатывал модуль для Nginx, где все работало асинхронно, и пришел к выводу, что эффективнее всего реализовать событийно-ориентированную систему, которой и стала платформа Node.js.
Первоначально среда называлась web.js, но ее возможности применения оказались намного шире, чем обычный веб-сервер, и потому платформу переименовали в Node.js. Готовый проект был представлен Райаном на JSConf 2009, 45-минутное выступление сорвало аплодисменты:
Система быстро получила признание и стала невероятно популярной. Помимо асинхронности у Node много других преимуществ, ее можно использовать как еще один слой абстракции над уже существующим бэкэндом и не переписывать серверную часть заново. Высокая скорость работы и хорошая масштабируемость позволила строить высоконагруженные системы, например, приложения для работы сетевых магазинов, не падающих даже в период сезонных распродаж, когда простой системы может лишить очень существенной части годового дохода.
Не обошлось без проблем, в частности было не просто найти разработчиков с подходящим бэкграундом. Чаще всего причины: «I HATE NODE.JS!!!1111oneone», они проистекают как раз из того, что кажущаяся простота языка привлекает программистов, которые ранее не занимались разработкой для серверов. На JS обычно писали фронтэнд, а там решаются совсем другие задачи. С проблемами сталкивались и разработчики на Java, потому что у них было предубеждение: «На языке называющемся JavaScript, я программировать смогу без проблем!», что на деле было совсем не так просто. Оказалось, что легче других с задачей программирования на JS под Node справляются программисты, работавшие на платформе .Net. Более того, в момент развития Node дотнетчики испытывали некоторые трудности с востребованностью, а программистам JS для бэкэнда хорошо платили.
Сам же Райан через некоторое время после завершения разработки, примерно в 2012-13 годах, увлекся языком Go и надолго отошел от всего, связанного с Node.js, потому что этот язык полностью устраивал его по возможностям и быстродействию, а позже он увлекся нейронными сетями.
Критика Node.js его создателем
Примерно за полгода до конференции JSConf 2018 Райан Даль решил попробовать работать со своим детищем, спустя почти 10 лет с момента его создания. Нельзя сказать, что он был доволен тем, что увидел. Несомненно, проект сильно развился, но во время разработки Node.js Райан был слишком зациклен на решении проблем ввода/вывода, потому допустил некоторые ошибки, которые потом превратились в системные проблемы. Поскольку платформа стала чрезвычайно популярной, то уже поздно было что-то глобально менять, не поломав все зависимости и совместимость.
Райан и раньше очень критично отзывался о всем программном обеспечении, не только о Node.js. В 2011 году он устроил небольшую «пятиминутку ненависти» на Google+. Сама соцсеть давно закрыта, но интернет все помнит. Перевод его слов можно прочитать здесь: Я ненавижу почти всё ПО. А за год до выступления в 2018 рассказывал о том, что: «Для серверов я не могу представить другой язык кроме Go». Забегая вперед, он действительно начинал писать на Go, «убийце node.js», но потом перешел на Rust.
Потому критичный тон его доклада в 2018 году никого особо не удивил, а свежий взгляд создателя платформы снова поднял актуальность некоторых проблем.
10 Things I Regret About Node.js
Давайте вспомним основные тезисы, которые были в нем рассмотрены, а потом сравним с тем, как обстоят дела на данный момент.
1.
Отсутствие Promises, от которых отказались на начальном этапе разработки.
2.
Проблема с безопасностью. Приложение на Node.js получает доступ к локальному диску, сети и вообще ко всей системе сразу.
3.
Сложная и устаревшая система сборки, от которой давно уже все отказались.
4.
Излишне громоздкий package.json.
5.
Семантика платформы несовместима с браузерами
6.
Централизованный репозиторий для модулей.
7.
Команда подключения модуля не требует обязательного указания типа файла, что может приводить к путанице.
8.
Использование index.js, по аналогии с index.html, привело к усложнению загрузки модулей и перестало быть необходимым после поддержки package.json.
Забавно, что в обсуждениях выступления не раз упоминали, что количество сожалений в докладе не соответствует количеству сожалений в заголовке, но надо учесть, что Райан очень сильно волновался, его заметно потряхивало в самом начале речи. Более того, он не раз отмечал в своих интервью, что является программистом, а не медийной персоной, сожалел о том, что каждый его пост в блоге «привлекает сотни комментариев» и «теперь надо аккуратнее высказывать свое мнение», потому что сообщество часто понимало его слова слишком буквально.
Анонс Deno
После перечисления недостатков Node.js Райан представил свой собственный проект среды выполнения JS на сервере, последовательно перечисляя его преимущества, в сравнении с Node:
1.
Безопасная песочница для выполнения кода, с предоставлением только необходимых привилегий.
2.
Упрощенное использование модулей, с загрузкой по прямым ссылкам и хранением в локальном кэше, который не будет обновляться до тех пор, пока не будет дана специальная команда.
3.
Полная поддержка TypeScript.
4.
Единственный исполняемый файл без лишних связей
5.
Deno позволяет нативно исполнять код на разных языках, в зависимости от того, какой удобнее для конкретной задачи.
6.
Падение приложений при Uncaught Errors, асинхронные операции будут возвращать Promise, большая совместимость с браузерами.
Кроме перечисленного Deno будет использовать ES Modules, которых тогда тоже не было в поддержке Node.
Что изменилось в Node.js
Доклад вышел неоднозначный, потому он и поднял такой шум в сообществе. С одной стороны, замечания были справедливы. С другой, не все они настолько критичны, что требуется все бросить и писать новую среду.
Пожалуй, самым справедливым было упоминание проблем с безопасностью. У Node.js нет песочницы, которая закроет сервер от запущенного приложения. Эта проблема так полностью и не решена до сих пор. Доступ в сеть можно закрыть фаерволом, доступ к диску и другие полномочия — ограничить через запуск из контейнера, но это сторонние решения, которые не везде могут быть удобны.
Упомянутые в докладе проблемы с выполнением асинхронного кода, на данный момент более-менее решены. Конечно, было бы лучше, если бы Райан не удалил Promises в 2010 году, посчитав, что они слишком все усложняют, но сейчас многие системные библиотеки уже предоставляют этот функционал, не говоря уже про сторонние. Появилась возможность запускать скрипты параллельно с помощью workers, большие компании, такие как Microsoft и Alibaba, разрабатывают свои версии Node с многопоточностью.
От GYP так и не избавились, это наследие будет с Node еще долго. Ссылки url, совместимые с браузером, уже не засунуть, зато, с некоторых пор Node поддерживает ES-модули.
Разрешение зависимостей сложное и работает не так как в браузере, но работает, что самое главное, хоть и не без некоторых проблем. А появление механизма package-lock.json сводит их к минимуму.
NPM сильно эволюционировал с 2012 года. Хотя, надо заметить, эволюция была болезненная и подталкивали ее проблемы типа набившего оскомину left-pad. Но пакеты уже не исчезают просто так, есть несколько уровней аудита безопасности и возможность ставить пакеты из разных источников. Хотя до сих пор ничего не мешает разработчику залить на github правильный код, а в npm код с эксплойтом.
Проблема с index.js выглядит скорее надуманной, чем реальной, как и отсутствие расширений при подключении модулей. Складывается впечатление, что он наспех придумал половину аргументов. Кстати, так и было, подробнее в конце статьи.
Стоит признать, что практически все эти проблемы были решены, и весьма успешно. Сам Даль отстранился от развития проекта, с 2012 года он не имеет отношения к Node, и его доклад выглядит довольно субъективным, где недостатки платформы преувеличиваются в пользу его собственного детища. Таким образом, это выступление больше похоже на рекламу своей разработки, а не на разоблачение Node.js.
Справедливости ради надо заметить, что активно развитие Node сильно сдерживается энтерпрайзом, в котором такое огромное количество легаси-кода, что избавиться от него слишком дорого. Это давно вызывает серьезные проблемы, когда Linux надо обновлять, а под новую систему не удается собрать все модули и рано или поздно приходится переписывать огромное количество кода, тратя на это много времени и денег. Большие корпорации могут позволить себе выделить на это ресурсы, но небольшой хоббийный OpenSource проект будет брошен, если у разработчика не будет времени на его обновление.
Тем не менее у Node.js огромное комьюнити, и оно помогает программистам разбираться со множеством проблем, хотя порой разработчики расставляют приоритеты не так, как хотелось бы сообществу, и потому развитие проекта идет неровно. Возможно, что рано или поздно Node окончательно упрется в те изначальные недостатки, которые описывал Райан, и решить их будет уже невозможно. Но для IT это не первый раз, когда приходится глобально что-то менять. Например, Flash, успешно похоронили, без особых хлопот.
Развитие Deno
Вскоре после доклада, сообщество быстро разгадало анаграмму Node-Deno. Даже прозвучали шутки, что когда-то будет написан проект под названием Done. Но шутки шутками, а к чему же пришло развитие Deno?
Во время доклада Райан честно сказал, что на данный момент Deno экспериментальный прототип и не предлагается как альтернатива Node
Но с тех пор прошло уже больше двух лет, весной прошлого года, наконец-то, появился релиз под номером 1.0.0.
Как уже упоминалось выше, проект начинался на Go, но потом был переделан на Rust. Проект хоть и перестал тормозить, как в начале, но так и не показал преимуществ по скорости. Работа с TypeScript стала быстрее, сказались оптимизации, которые внесла команда, потому что в момент презентации запуск транслятора TS занимал целую секунду. Решено это было, как Райан и предполагал в своем докладе 2018 года, с помощью снимков состояния движка.
Платформа совершенно не совместима с Node и задумывалась не как абсолютная замена, но как альтернатива, исследовательский проект, эксперимент, подсказывающий разработчикам другие пути развития подобных решений.
На данный момент Deno состоит из следующих частей: обертка из Typescript/ Javascript, над движком V8, который является песочницей, обеспечивающий интерфейс между слоем TS/JS и Rust Backend (серверная часть имеющая доступ к файловой системе). Многопоточная работа обеспечивается с помощью Tokio — асинхронной среды, отвечающей Rust, отвечающая за создание и обработку событий, с помощью конструкций «Rust Future», аналога «Promise» в JavaScript.
Среда изначально безопасна, по умолчанию не имеет никаких прав доступа. Для предоставления нужных привилегий, надо запустить платформу с определенными опциями командной строки. Решение неоднозначное. Рано или поздно, разработчикам может надоесть прописывать в скриптах бесконечные опции, потому что в крупных проектах их будет очень много и запускать будут «--allow-all» по дефолту.
При необходимости Deno позволяет вызывать программы на том языке, который удобен для выполнения каких-то отдельных вычислительных задач.
***
На данный момент уже вышла версия релиза под номером 1.7. Но все еще не слышно, чтобы какая-то крупная компания отказалась от Node.js в пользу Deno. Мы даже сделали образ в маркетплейсе для node.js
Проект Deno развивается на энтузиазме, сам же Райан сейчас работает в Google и занимается тем, что ставит задачи перед инженерами, занимающихся нейронными сетями и глубоким обучением.
Кто-то считает, что у Даль развился комплекс первого выстрелившего проекта, когда Node.js, совершенно неожиданно для Райана, почти сразу получил признание и очень резко набрал популярность. Но, скорее всего, он из тех людей, которые не могут сидеть без новых идей и терпеть несовершенства в своем собственном изобретении.
Хотя Даль начал работать над Deno задолго до выступления на конференции в 2018 году, первоначальная тема для него была совсем другая. Он планировал выступить с докладом по машинному обучению, которым занимался последние несколько лет. Но не успел вовремя подготовиться и тема его выступления была снята буквально за пару дней до конференции. А поскольку он понимал свой вес в сообществе и то, как зрители будут ждать его выступления, то за день или два ему пришлось очень сильно постараться, чтобы найти новую достойную тему, оправдывающую ожидания публики.
Так что может он и не задумывал провозгласить «убийцу Node.js», а просто поторопился с подготовкой нового доклада. Хотя ему таки удалось поднять очень изрядный шум, возможно куда больший, чем темой про глубокое обучение.