Хабрахабр

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

Райан Даль, создатель Node.js, потратил последние полтора года на работу над проектом Deno. Это — новая среда выполнения для JavaScript, которая должна исправить проблемы, присущие Node.js.

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

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

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

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

Модули

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

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

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

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

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

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

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

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

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

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

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

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

Поддержка TypeScript

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

Итоги

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

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

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

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

Показать больше

Похожие публикации

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»