Deno — новый Node.js? +29


В нашем проекте, IDE для работы с API TestMace, в качестве основного языка используется TypeScript, поэтому мы активно интересуемся проектами, связанными с данным языком. Сегодня вашему вниманию представляется перевод статьи об инструменте Deno — runtime для TypeScript (но это не единственная его особенность). Приятного чтения.



Около трёх месяцев назад Райан Дал (создатель Node.js) выступил на конференции с докладом «10 вещей в Node.js, о которых я сожалею», где рассказал о некоторых своих неудачных проектных решениях для Node.js. Почти половину выступления он посвятил экспериментальному прототипу Deno, задачей которого было устранить недостатки Node.js.


Deno уже добрался до версии v0.1 (прим. переводчика — уже v0.3.8) и идёт правильной дорогой к своей цели заменить Node.js в будущем.


Что не так с Node.js?


Любая программа может производить запись данных в файловую систему или сеть


Это может вылиться в угрозу безопасности, особенно при установке непроверенных пакетов npm. Например, как в инциденте с crossenv. Если бы у crossenv не было разрешения на запись, подобного бы не случилось.


Быстро устаревающие асинхронные API


Промисы появились в Node.js в 2009 году, а в феврале 2010 их не стало. Однако в большинстве библиотек для работы с асинхронным кодом до сих пор используются колбеки.


Система сборки (GYP)


Собрать модуль для подключения библиотек на C через GYP — сплошное мучение. Чтобы получить адекватный developer experience, придётся использовать node-gyp (слой поверх GYP) и, возможно, другие слои (вроде nan). Я собственноручно пробовал все вышеописанное в своем небольшом проекте, и, готов согласиться, это заставило меня попотеть.


Система модулей и npm


Главная проблема в том, что система модулей не совместима с браузерами, а значит код не до конца изоморфен. Главным образом, на то есть две причины: хранение зависимостей в node_modules и наличие package.json.


Что такое Deno?


«Deno — это защищенная среда выполнения TypeScript на основе движка V8»,
? Райан Дал


Учитывая, что Typescript — это расширенная версия Javascript, Deno также является средой выполнения и для Javascript.


Deno — новый проект Райана Дала (создателя Node.js), призванный исправить проектные ошибки Node.js, речь о которых шла выше.


Основные особенности Deno


Безопасность


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


Процесс Deno запускается в непривилегированном режиме, и, чтобы получить доступ к данным вроде переменных окружения, необходимо передать специальные флаги.


Разрешение на запись в файловую систему, а также разрешения, связанные с окружением и сетью, отключены. Чтобы разрешить эти действия, необходимо вызвать Deno c аргументами --allow-write и --allow-net.


Всё взаимодействие привилегированного процесса Deno и v8 сводится к обмену сообщениями (ранее написанному на Go, теперь перенесённому на Rust). Это позволяет создать единую точку для проверки всех сообщений.


Система модулей


Забудьте о package.json и node_modules. При импорте исходных файлов можно указать как относительный или абсолютный путь, так и их полный URL:


import { test } from "https://unpkg.com/deno_testing@0.0.5/testing.ts"
import { log } from "./util.ts"

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


Поддержка TypeScript из коробки


TypeScript поддерживается в Deno по умолчанию. Вот так вот. Без всяких "но". Без конфигураций.


Deno v0.1.4 в действии


Для начала загрузим бинарный файл Deno:


$ mkdir deno-test && cd deno-test
$ wget https://github.com/denoland/deno/releases/download/v0.1.4/deno_linux_x64.gz
$ gunzip -c deno_linux_x64.gz > deno
$ chmod u+x deno
$ ./deno --version
deno: 0.1.4
v8: 7.0.247-deno

Теперь создадим typescript-файл и выполним его:



function hello(place: string): string {
  return `Hello ${place}`
}

console.log(hello('world'))

$ ./deno myscript.ts
Hello world

Можно также попробовать импорт через URL. Единственное требование — файл в конце URL должен иметь расширение .ts.


import { factorial } from "https://gist.githubusercontent.com/DanielRamosAcosta/ad514503b1c7cf8290dadb96a5fddee9/raw/4733e267f05d20110ba962c4418bab5e98abfe93/factorial.ts"

console.log(factorial(10))

$ ./deno myimport.ts
Downloading https://gist.githubusercontent.com/DanielRamosAcosta/ad514503b1c7cf8290dadb96a5fddee9/raw/4733e267f05d20110ba962c4418bab5e98abfe93/factorial.ts
3628800

Во время выполнения скрипта модуль загрузится и добавится в кэш. Чтобы обновить кэш, можно вызвать Deno, используя аргумент --reload, что эквивалентно действию клавиш F5 или Ctrl+R.


Ниже приведён более сложный пример с использованием библиотеки axios:


import axios from "https://gist.githubusercontent.com/DanielRamosAcosta/2f773d815f5434f185c59aec1bab418c/raw/a442cdd8699e39ab9855cbaa571a79049a7b67d4/axios.ts"

// Make a request for a user with a given ID
axios.get('http://jsonplaceholder.typicode.com/users/1')
  .then(response => {
    // handle success
    console.log("User name:", response.data.name);
  })
  .catch(error => {
    // handle error
    console.error("error:", error);
  })

Единственная загвоздка в том, что VSCode не может загружать typings удалённо, поэтому в редакторе появится следующая ошибка:


An import path cannot end with a '.ts' extension.


Но код всё равно работает и выдаёт корректный результат:


./deno --allow-net axios-test.ts
User name: Leanne Graham

Заключение


Deno понадобится ещё немало времени, чтобы вырасти в полноценный рабочий инструмент, но, я считаю, он развивается в верном направлении, и у него есть все шансы стать более продуманной средой выполнения Javascript, чем Node.js.


Благодарю за внимание!




К сожалению, не доступен сервер mySQL