runtime - середовище, де виконується JS
Які взагалі можуть бути Runtime?
JavaScript - мова програмування, але для виконання коду JavaScript потрібне середовище виконання. Найпопулярнішими середовищами виконання є веб-браузери (як Chrome, Firefox, Safari) та Node.js для серверного програмування.
Ці середовища виконання надають різні об'єкти глобального контексту та API, які можна використовувати в коді JavaScript. Наприклад, в браузері ви маєте доступ до об'єктів, таких як window, document, location тощо, які дозволяють вам взаємодіяти з веб-сторінкою. В Node.js ви маєте доступ до об'єктів, таких як global, process, Buffer тощо, які дозволяють вам взаємодіяти з операційною системою та файловою системою.
JavaScript-оточення виконання (runtimes) допомагають вам створювати складні серверні проєкти на JavaScript, які не залежать від браузера користувача для виконання.
Є кілька варіантів оточень виконання, серед яких традиційно домінує старий надійний Node.js, але конкуренцію йому складають нові проєкти, як Deno та Bun. Deno — це новий проєкт, створений тим самим розробником, який свого часу створив Node.js, Райаном Далем, ще в 2009 році. Deno прагне покращити безпеку завдяки детальному контролю доступу та пропонує більш сучасні можливості, як-от нативну підтримку TypeScript та покращену сумісність з веб-технологіями.
У свою чергу, Bun — це новий претендент, який вражає швидкістю і значно перевершує своїх конкурентів. Однак він досі перебуває на стадії бета-версії і має деякі недоліки, які потрібно виправити перед тим, як ставати повноцінним продуктом (версія 1.0 наразі запланована на 7 вересня 2023 року).
Давайте розглянемо детальніше різні варіанти оточення виконання.
Чому важливо обирати правильне оточення виконання JavaScript
Оточення виконання JavaScript (runtimes) дозволяють запускати код застосунку поза браузером. Це означає, що ви можете надавати сайти у вигляді хостованих застосунків. Або ви можете обрати використання JavaScript-оточень для загальних сценаріїв автоматизації.
Оточення виконання, яке ви оберете, матиме суттєвий вплив на продуктивність ваших застосунків, зокрема на швидкість обробки запитів та доступу до баз даних, які можуть значно відрізнятися. Це також впливає на зручність розробки та масштабованість.
Окрім різних функцій, доступних в кожному оточенні виконання, важливий також досвід розробника. Ваша команда, зокрема їх досвід з певними оточеннями та готовність експериментувати, впливатиме на вибір оптимального оточення для вас. Чи віддаєте ви перевагу стабільності чи швидкості? Чи хочете ви підтримку нативного TypeScript у більш багатому оточенні, чи шукаєте більш налаштовуване середовище? Це лише кілька прикладів запитань, які можуть виникнути при виборі оточення виконання.
Knowing what each runtime offers can help you make the most educated decision.
Ознайомлення з оточеннями виконання JavaScript
Перед тим, як порівнювати ці оточення виконання за їх продуктивністю, стабільністю та безпекою, давайте зробимо короткий огляд кожного з них:
Node.js
Node.js — це лідер серед оточень виконання JavaScript, який був визнаний найпопулярнішою веб-технологією 2023 року за версією розробників Stack Overflow. Його створив Райан Даль, і він був запущений у 2009 році. Можна з упевненістю сказати, що він змінив уявлення про те, що можна робити з JavaScript, коли цей інструмент з'явився на ринку. Завдяки йому розробники можуть створювати складні серверні застосунки на JavaScript.
Сьогодні існує величезна екосистема навколо Node.js, з безліччю ресурсів та бібліотек. Але, як і в будь-якої технології чи оточення виконання, завжди є місце для вдосконалення.
Це саме те місце, де з'являються Deno та Bun, додаючи нові варіанти в ландшафт оточень виконання JavaScript.
Deno
Deno — це оточення виконання JavaScript, що базується на Rust. Як і Node.js, його створив та запустив Райан Даль з надією покращити те, що пропонується в Node.js. Більше про мотивацію Райана щодо створення Deno можна дізнатися з цього запису виступу на JSConf EU.
Однією з основних цілей є покращення безпеки Node.js. У Deno доступ до файлів, мережі та середовища потрібно явно дозволяти, щоб зменшити ймовірність безпекових проблем, які зазвичай виникають у цих сферах. Воно також краще підтримує JSX та TypeScript, а також орієнтоване на веб-стандарти. Для зручності розгортання застосунки постачаються як єдиний виконуваний файл.
Deno також має екосистему інструментів, що дозволяє розробникам швидко почати роботу над своїми проєктами. Fresh
dev/) — це веб-фреймворк, створений для Deno, а Lume — їх генератор статичних сайтів.
Bun
Bun — це нове оточення виконання, яке змагається за вашу увагу. Засноване на Zig, його мета — стати універсальним оточенням виконання та інструментом, з акцентом на швидкість, бандлінг, тестування та сумісність з пакетами Node.js. Однією з найбільших переваг є його продуктивність, яка значно перевершує як Node.js, так і Deno. Це робить Bun дуже привабливою пропозицією, якщо він здатен виконати обіцяне.
Щодо продуктивності, розробники Bun надають приклад бенчмарку, який запускає обробник HTTP, що рендерить серверну сторінку за допомогою React. Це призвело до того, що Bun обробляв близько 68 000 запитів на секунду, порівняно з приблизно 29 000 та 14 000 для Deno та Node.js відповідно. Це велика різниця. Джарред Самнер регулярно публікує оновлення щодо розвитку Bun
com/jarredsumner) разом з останніми бенчмарками на Twitter, тому обов’язково підписуйтеся на нього, щоб бути в курсі новин.
Bun також включає функції бандлінгу та виконання завдань для проєктів на JavaScript та TypeScript. Подібно до Deno, він постачається у вигляді єдиного бінарного файлу та має вбудовану підтримку Web API. Він також підтримує деякі бібліотеки Node.js з сумісністю з npm.
Порівняння оточень виконання JavaScript
Тепер давайте детальніше розглянемо різниці, зосередившись на продуктивності, підтримці та спільноті, стабільності, безпеці та додаткових функціях.
Продуктивність
До суті: Bun перемагає. Раніше ми вже дізналися про його можливості щодо продуктивності, зокрема, скільки запитів на секунду він може обробляти, і це справді вражає. Схожа ситуація з операціями з базами даних. Середня кількість запитів на секунду при завантаженні бази даних Northwind для SQLite за допомогою бенчмарку Bun
com/oven-sh/bun/tree/main/bench/sqlite) виглядають наступним чином:
| Оточення виконання | Середня кількість запитів/секунду |
| — — | — — |
| Node.js | 21.29 |
| Deno | 43.50 |
| Bun | 81.37 |
У іншому порівнянні між Node.js, Deno та Bun, Bun виявився найшвидшим у обробці одночасних з'єднань. Кількість запитів на секунду також набагато вища. Наприклад, при 10 одночасних з'єднаннях Bun досягає 110 000 запитів на секунду, тоді як Node.js обробляє 60 000, а Deno — 67 000. Ця тенденція зберігається з підвищенням кількості одночасних з'єднань і продуктивності кожного з оточень виконання.
Хоча є деякі суперечки щодо ефективності сценаріїв, що використовуються для тестів продуктивності, Bun залишається переможцем. Node.
js займає останнє місце у всіх порівняннях, зокрема погано показує себе у швидкості роботи з базами даних. Deno та Node.js зазвичай не надто відрізняються між собою, а Bun значно перевершує обидва. Хоча Node.js відстає в цьому плані, Ягіз Нізіплі (Yagiz Nizipli) очолює зусилля щодо покращення продуктивності в кількох аспектах Node.js. Наприклад, покращення швидкості парсингу URL на ~80–90%.
FIXME Unknown Tag — contentEmbedWidget Ви також можете виконати тести продуктивності Bun у своєму середовищі, щоб побачити, як він працює в наступних сценаріях:
Швидкість Bun була основним фокусом для його розробників, і він використовує JavaScriptCore, який є частиною Safari. Тоді як Deno та Node.
js використовує той самий JavaScript-двигун V8, що і в Chrome. Планується подальше покращення Bun шляхом видалення зайвого коду у зібраних бінарних файлах (це було частково реалізовано до цього часу).
Окрім того, що Bun працює швидко, він також розроблений для швидкого запуску — мета полягає в тому, щоб зберігати високу продуктивність при запуску кількох екземплярів. Це робить його гарним вибором для динамічно масштабованих застосунків. Якщо ви отримуєте різке збільшення трафіку та вам потрібно швидко створити екземпляри, Bun розроблений з урахуванням цього, щоб зробити ваші сервіси доступними якнайшвидше.
Підтримка та спільнота
Всі три проєкти є відкритим програмним забезпеченням, але не всі з них повністю підтримуються спільнотою. Node.js підтримується OpenJS Foundation і є повністю комунальним проєктом, заснованим на волонтерстві. Deno та Bun підтримуються комерційними організаціями та проектами з венчурним фінансуванням.
Node.
js має добре розвинуту екосистему та величезну спільноту, з онлайн-матеріалами, доступними для кожного випадку використання, який можна собі уявити. У порівнянні з цим, Deno та Bun набагато новіші, тому ви не знайдете стільки матеріалів підтримки. Однак серед ентузіастів-розробників є чимало охочих поділитися своїми знаннями. Крім того, Deno 1.28 покращив сумісність з npm пакетами, що полегшує його впровадження для розробників, які переходять з Node.js.
Ось таблиця, що показує кількість запитів, відмічених для кожного середовища виконання на Stack Overflow (станом на вересень 2023):
| Оточення виконання | Запитів з міткою |
| — — | — — |
| Node.js | 466,762 |
| Deno | 917 |
| Bun | 52 |
Як видно, у Node.js значно більше запитів, що робить ймовірність того, що ви знайдете вже існуюче питання, або отримаєте відповідь на ваше, значно вищою.
Щороку проводиться опитування серед розробників, яке називається State of JavaScript. У ньому є питання про те, які середовища виконання учасники використовують регулярно, і на нього відповіли майже 30 тис. респондентів. Результати найновішого опитування 2022 року також показують Node.js як явного лідера, з Deno, що відстає з близько 5,3 тис. голосів, та Bun з близько 1,2 тис. голосів. Це було очікувано на той час, і буде цікаво подивитися, як ці цифри зміняться в результатах опитування 2023 року. Можливо, ми побачимо нові тенденції для Deno та Bun.
Офіційна документація Node.js містить різні посібники, велику довідку по API та інформацію для початківців. Також є інформація про його залежності.
На сайті Deno є дуже детальний посібник, який допоможе вам ознайомитись з оточенням виконання і почати використовувати його у ваших проєктах.
Головна сторінка Deno акцентує увагу на доступі до встановлення та документації, щоб новачки не шукали допомогу в інших місцях. Також є інформація про стандартну бібліотеку, яку розробники можуть використовувати прямо з коробки. Сторінка з модулями сторонніх розробників є корисною, щоб дізнатися, що доступно в екосистемі. Вона містить понад 6 000 модулів (станом на серпень 2023 року) з прикладами коду.
Головна сторінка Bun має помітні посилання на його Discord, документацію та сторінки на GitHub. Документація значно покращилася з моменту її першого виходу. Тепер є повноцінний окремий сайт, наповнений інформацією на різні теми, такі як початок роботи, використання бандлера та тестового запуску, а також довідка по API. Тепер є навіть посібники, які показують, як виконувати типові завдання за допомогою Bun.
Стабільність
Як усталений гравець, Node.js пропонує перевірену продуктивність, підтримуючи 2,1% світових вебсайтів.
Node.js — це перевірений продукт, на який залежить велика кількість проєктів. Якщо ви зіштовхнетеся з проблемою, ймовірно, хтось уже знає, як її вирішити.
Перша стабільна версія Deno була випущена у травні 2020 року, і вона вважається першим стабільним релізом. Однак, успіх у прийнятті був незначним, можливо, через відсутність "перцептивно важливих" відмінностей, щоб залучити розробників масово. З моменту випуску версії 1.0 Deno досяг успіху в покращенні досвіду розробників, зберігаючи стабільність у кожному випуску, щоб розробники могли оновлювати без великих труднощів.
Bun досі знаходиться в бета-версії, на момент написання це версія 0.7.3, але він близький до випуску 1.0, який очікується у вересні 2023 року. Через це його стабільність та підтримка Node.
API ядра (core APIs) значно зросли з моменту виходу в бета-версії і, ймовірно, продовжать розвиватися, оскільки все більше людей у спільноті шукають можливість використовувати їх у своїх проєктах.
Безпека
Безпека може бути слабким місцем при керуванні залежностями через npm і поширюється на загальні проблеми безпеки додатків при побудові на базі Node.js. Створення більш безпечного середовища виконання стало одним із основних факторів для створення Deno, яке зосереджене на тонко налаштованих контролях доступу до чутливих API, таких як мережеві запити, операції з файловою системою та інші основні можливості. Node.js не відстає на цьому фронті. Node.js 20 ввів модель дозволів, що дозволяє здійснювати подібні заходи безпеки, як у Deno.
Існує безліч ресурсів, що допомагають вивчити безпечні практики, таких як стаття [Найкращі практики безпеки Node.js від Snyk] і цей [чіт-лист OWASP](https://cheatsheetseries.owasp.
(чіт-лист OWASP](https://cheatsheetseries.owasp.org/cheatsheets/NodejsSecurityCheat_Sheet.html). Ознайомлення розробників з поширеними помилками може допомогти побудувати безпечний додаток на Node.js.
Deno усуває деякі проблеми безпеки, властиві Node.js, вимагаючи явних дозволів для певних дій у працюючому додатку. Наприклад, для того, щоб дозволити вашому додатку доступ до читання з файлової системи, потрібно ініціювати його за допомогою прапорця --allow-read
під час запуску. Повний список цих дозволів можна знайти в їхній документації по дозволах. Також ви можете взаємодіяти з цією системою дозволів під час виконання, що дозволяє вам запитувати та відкликати дозволи програмно.
Будьте обережні із запуском підпроцесів під час використання прапору --allow-run
, оскільки створені підпроцеси не мають таких самих обмежень безпеки, як процес Deno, і можуть порушити безпековий пісочний майданчик Deno, що призведе до підвищення привілеїв.
Bun ще дуже новий, і інформація про його безпеку знайти непросто. Через свою відносну незрілість, його слід використовувати з обережністю, уважно стежачи за оновленнями та оголошеннями про виправлення безпеки. У майбутньому є плани провести аудит безпеки, коли проєкт стане більш стабільним.
Щодо відстеження оновлень безпеки, Snyk може спростити управління безпекою вашого проєкту: від відкритих бібліотек, на які він спирається, до коду, який ви пишете самостійно.
Snyk Open Source (SCA) допомагає знаходити, пріоритизувати та виправляти вразливості безпеки та проблеми з ліцензіями у ваших залежностях з відкритим кодом. Тим часом Snyk Code (SAST) дозволяє швидко сканувати ваш вихідний код — без необхідності збірки — і миттєво виправляти знайдені проблеми.
Додаткові можливості
Node.js нещодавно отримав кілька нових функцій, щоб наблизити свої можливості до Deno та Bun. Наприклад, тепер він має вбудований тестовий запуск (Test Runner), а також активно обговорюється вбудована підтримка TypeScript.
Deno включає інспектор залежностей (Dependency Inspector) і форматер коду (Code Formatter). Його здатність розгортати код у вигляді одного виконуваного файлу також є перевагою. Під час налаштування сервера з використанням Deno базовий метод, описаний у документації, передбачає завантаження коду з інших джерел. Код не виглядає значно складнішим, ніж у Node.js, але може здатися трохи незвичним, оскільки залежності завантажуються через URL.
Ось спрощений приклад коду:
import { serve } from "https://deno.land/[email protected]/http/server.ts";
const handler = async (\_request: Request): Promise =\> {
const resp = await fetch("https://api.github.com/users/denoland", {
// Об'єкт init тут містить об'єкт headers із заголовком,
// який вказує, який тип відповіді ми очікуємо.
// Поле method не вказується, оскільки за замовчуванням
// fetch виконує GET-запит.
headers: {
accept: "application/json",
},
});
return new Response(resp.body, {
status: resp.status,
headers: {
"content-type": "application/json",
},
});
};
serve(handler);
Додаткові можливості Bun включають транспайлер (Transpiler) та менеджер пакетів (Package Manager). Як натякає назва, він [також має функції для бандлінгу](https://bun.
[sh/docs/bundler), що надає функціонал, який зазвичай потребує використання іншого інструмента, наприклад Snowpack або rollup.js. Bun також має функцію видалення зайвого коду (Dead Code Elimination) через свій мінімайзер JavaScript.
Якщо використовувати Bun як таск-раннер (Task Runner), його швидкість може стати значною перевагою. Bun заявляє, що стартує приблизно за 5 мілісекунд порівняно з 25 мілісекундами для Node.js. Це може здаватися незначною різницею, але якщо врахувати багато задач, які потрібно виконувати з часом, це може суттєво прискорити робочий процес розробки.
Міграція з Node.js на Deno або Bun
Код, написаний на чистому JavaScript або TypeScript, має працювати без проблем у будь-якому середовищі виконання. Проте, якщо ви використовували специфічні функції Node.js, перехід на інші середовища може виявитися складнішим. Давайте коротко розглянемо це питання.
Міграція з Node.js на Deno
Node.
Сумісність модулів (Module Compatibility) була однією з головних проблем при міграції на Deno у минулому. Проте зараз це так просто, як додати префікс node:
до ваших інструкцій імпорту (Import Statements). Що стосується пакетів npm, їх можна імпортувати з префіксом npm:
або створити файл deno.js
, який описує карти імпорту для їхньої обробки Deno.
Якщо ви створюєте пакети чи бібліотеки (Libraries) для спільноти, зверніть увагу на Denoify. Це проєкт, який автоматично змінює деякі файли під час міграції, спрощуючи підтримку проєкту як для npm, так і для deno.land/x.
Міграція з Node.js на Bun
Bun реалізує більшість функцій Node-API. Якщо ваш проєкт невеликий або використовує лише загальні функції, ви можете просто перенести його в Bun і почати роботу. Однак для більших проєктів імовірність зіткнутися з проблемами є вищою.
Це означає, що великі проєкти можуть зіткнутися з труднощами, які вимагатимуть переписування коду.
Bun також має власні API. Наприклад, Bun використовує свій API для обслуговування веб-файлів. Створення захищеного веб-сервера (Web Server) таке ж просте, як застосування наступного коду, адаптованого з документації Bun:
Bun.serve({
fetch(req) {
return new Response("Hello!!!");
},
tls: {
key: Bun.file("./key.pem"),
cert: Bun.file("./cert.pem"),
}
});
Як видно, при міграції на Deno або Bun використання їхніх власних API означає, що ваш код буде відрізнятися від того, який використовується в Node.js. Це варто врахувати, якщо ви конвертуєте існуючий проєкт або навіть починаєте новий, оскільки це може ускладнити повернення до Node.js, якщо ви зіткнетеся з критичною проблемою, яка у Node.js була б відсутньою.
Який проєкт підходить саме вам?
Варто врахувати всі згадані раніше можливості, обираючи, який із проєктів використовувати.
Ваші пріоритети можуть змінюватися залежно від випадку використання та потреб проєкту.
Bun однозначно перемагає за швидкістю, проте через його новизну використання може бути ризикованим. Чи досягне він стабільності, як у двох інших варіантів? Можливо. У будь-якому разі, якщо ви шукаєте інноваційний інструмент для перевершення конкурентів за швидкістю, Bun пропонує таку можливість (у більшості сценаріїв).
Головна перевага Node.js — його зрілість та розмір екосистеми. Ви знайдете багато розробників, які його добре розуміють. Водночас Deno та Bun приваблюють своєю новизною, що завжди викликає інтерес у розробників.
Deno також має багато переваг над Node.js. Його функціональність забезпечує більш плавну розробку та дозволяє легко створювати складні проєкти високої якості. Deno є безпечним, а також швидшим за Node.js, хоча в порівнянні з Bun він трохи повільніший.
Загалом Node.js все ще залишається найнадійнішим варіантом із перевіреним часом успіхом.
Deno має багато переваг завдяки своїм сучасним функціям, що робить його хорошим вибором для розробників, які прагнуть створити щось нове. А Bun стане вашим інструментом, якщо для вас найважливіша швидкість або якщо ви хочете бути на передовій нових технологій.
Перекладено з: JS runtime