Pull to refresh
2779.19
RUVDS.com
VDS/VPS-хостинг. Скидка 15% по коду HABR15

Что такое Deno и чем этот проект отличается от Node.js?

Reading time6 min
Views23K
Original author: Maciej Cieslar
Райан Даль, создатель Node.js, потратил последние полтора года на работу над проектом Deno. Это — новая среда выполнения для JavaScript, которая должна исправить проблемы, присущие Node.js.

Не поймите меня неправильно. Платформа Node.js представляет собой замечательную серверную среду для выполнения JavaScript. Своей популярностью она обязана, преимущественно, огромной экосистеме, и, собственно, поддержке JavaScript. Однако Райан Даль признаёт, что кое-чему, касающемуся Node.js, ему стоило бы уделить больше внимания. Речь, в частности, идёт о безопасности, о модулях и об управлении зависимостями.


В его защиту можно сказать то, что он не мог знать о том, насколько популярной станет платформа Node.js за довольно короткий отрезок времени. Кроме того, в 2009 году JavaScript всё ещё выглядел как ограниченный и странный язык, над которым издевались все, кому не лень. Также надо отметить то, что в те времена многих возможностей JavaScript, привычных в наши дни, ещё не существовало.

Что такое Deno и каковы основные особенности этой платформы?


Deno — это безопасная среда выполнения TypeScript, построенная на базе JS-движка V8, разработкой которого занимается Google. Платформа Deno создана с использованием следующих средств:

  • Rust (ядро Deno написано на Rust, а ядро Node — на C++).
  • Tokio (цикл событий, написанный на Rust).
  • TypeScript (Deno, без дополнительных настроек, поддерживает и JavaScript, и TypeScript).
  • V8 (JS-движок от Google, используемый в браузере Chrome, в Node.js и в других проектах).

Поговорим о том, какие возможности предлагает нам платформа Deno.

Безопасность (разрешения)


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

В отличие от Node, Deno, по умолчанию, выполняет код в «песочнице». Это означает, что у среды выполнения нет доступа к следующим сущностям и возможностям:

  • Файловая система.
  • Сеть.
  • Выполнение других скриптов.
  • Переменные окружения.

Взглянем на то, как работает система разрешений Deno. Рассмотрим следующий скрипт:

(async () => {
 const encoder = new TextEncoder();
 const data = encoder.encode('Hello world\n');

 await Deno.writeFile('hello.txt', data);
 await Deno.writeFile('hello2.txt', data);
})();

Этот скрипт создаёт пару текстовых файлов — hello.txt и hello2.txt. В эти файлы помещён текст Hello world. Код выполняется в «песочнице». Поэтому у него нет доступа к файловой системе.

Кроме того, обратите внимание на то, что тут мы используем пространство имён Deno, а не обращаемся к чему-то вроде модуля fs, как сделали бы в Node. Пространство имён Deno предоставляет в распоряжение разработчика множество базовых вспомогательных функций. Но мы, используя пространство имён, теряем совместимость кода с браузером. Об этом мы поговорим ниже.

Этот скрипт можно запустить такой командой:

deno run write-hello.ts

После этого мы увидим уведомление следующего содержания:

Deno requests write access to "/Users/user/folder/hello.txt". Grant? [a/y/n/d (a = allow always, y = allow once, n = deny once, d = deny always)]

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

Если же мы выберем один из вариантов deny — будет выдана ошибка PermissionDenied. Процесс скрипта будет после этого завершён, так как в нём нет кода для обработки ошибок.

Скрипт можно запустить и так:

deno run --allow-write write-hello.ts

Уведомлений при этом мы не увидим, оба файла будут созданы.

Помимо флага --allow-write, влияющего на работу с файловой системой, при запуске скриптов можно использовать и другие флаги. Это — --allow-net, --allow-env и --allow-run. Они, соответственно, открывают скрипту доступ к сети, к окружению, и к запуску подпроцессов.

Модули


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

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

Тут у вас может возникнуть вопрос о том, что такого особенного в импорте пакетов по URL? Ответ на этот вопрос прост: благодаря использованию URL пакеты Deno могут распространяться без использования централизованного реестра наподобие npm. У npm в последнее время возникает множество проблем.

Организация импорта кода посредством URL позволяет создателям пакетов хостить свой код везде, где они сочтут нужным. Это — децентрализация во всей красе. Больше никаких package.json и node_modules.

Когда мы запускаем приложение, Deno загружает все импортированные модули и кэширует их. После того, как они оказываются кэшированным, Deno не будет повторно их загружать, если только мы явно не запросим их повторную загрузку, использовав флаг --reload.

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

▍Что если ресурс, на котором размещён код модуля, окажется недоступным?


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

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

Deno хранит кэш в папке, заданной переменной окружения $DENO_DIR. Если мы эту переменную не настроим — Deno будет хранить кэш в стандартной системной директории для кэшей. Переменную $DENO_DIR можно установить так, чтобы она указывала бы на какую-нибудь папку в нашем локальном репозитории. Эту папку можно обрабатывать с помощью используемой системы контроля версий.

▍Нужно ли будет постоянно импортировать модули по URL?


Регулярный ввод длинных URL может быстро надоесть. К счастью, Deno даёт нам два способа облегчить выполнение этой задачи.

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

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

Предположим, что тот файл, в котором находится вышеприведённая команда, называется local-test-utils.ts. Теперь, если нам снова понадобятся функции test или assertEqual, мы можем импортировать их так:

import { test, assertEquals } from './local-test-utils.ts';

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

Вторая возможность заключается в создании карты импортов, оформленной в виде JSON-файла:

{
   "imports": {
      "http/": "https://deno.land/std/http/"
   }
}

При использовании подобного файла команда импорта может выглядеть так:

import { serve } from "http/server.ts";

Для того чтобы эта схема заработала — нужно сообщить системе об использовании в проекте карты импортов, использовав при запуске скрипта флаг --importmap:

deno run --importmap=import_map.json hello_server.ts

▍Как осуществляется управление версиями модулей?


За управление версиями пакетов отвечает их разработчик. С точки зрения клиента выбор нужной версии пакета выглядит как его добавление в URL:
https://unpkg.com/liltest@0.0.5/dist/liltest.js.

Совместимость с браузерами


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

Однако инструменты вроде Babel преобразуют современный JS-код в код, соответствующий стандарту ES5. В результате этот код может выполняться даже в не самых новых браузерах, не поддерживающих современные возможности JavaScript. Но и у такого подхода есть минус, который заключается в том, что бандлы веб-проектов разрастаются из-за того, что в них попадает много вспомогательного кода.

Собственно говоря — решения о целях наших проектов принимаем мы. Мы же выбираем и соответствующие инструменты.

Поддержка TypeScript


Deno упрощает использование TypeScript, избавляя разработчика от необходимости что-либо настраивать для запуска TS-кода. Но программы для Deno без проблем можно писать и на JavaScript.

Итоги


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

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

Райан Даль говорит, что он рассчитывает выпустить Deno 1.0 в конце лета. Если вас интересует будущее этого проекта — обратите внимание на его репозиторий.

Уважаемые читатели! Что вы думаете о Deno?

Tags:
Hubs:
+37
Comments43

Articles

Information

Website
ruvds.com
Registered
Founded
Employees
11–30 employees
Location
Россия
Representative
ruvds