Ryan stvořil Deno a bylo to dobré

Publikováno: 15.10.2020

S nadsázkou se dá prohlásit, že vzniku Deno vděčíme hryzavému svědomí Ryana Dahla, autora NodeJS. Za jedenáct let, které dělí první verzi NodeJS a první verzi Deno, se ve světě referenčního JavaScriptu událo mnohé. Následovník NodeJS je proto mnohými vítán.

Celý článek

Příčiny svých poruch nespavosti shrnul Ryan Dahl do přednášky na konferenci JSConf EU v roce 2018. Uplynuly dva roky a na světě je první produkční verze Deno.

Když uvážíme, že NodeJS je tu s námi od roku 2009, je zřejmé, že serverová implementace JavaScriptu počatá na zelené louce v roce 2020, bude zralejší. Jistě víc než v roce, kdy Spojené státy poprvé vedl afroamerický prezident. Jedno ovšem mají obě implementace pod kapotou shodné. Uhodnete? Není to těžké. Google V8 JavaScript engine. Tím jsme seznam shodných prvků, s nadsázkou, vyčerpali.

Název a logo

Krátce k názvu Deno. Asi každého napadlo, že se jedná o přesmyčku Node. To inspirovalo některé další vývojáře. Takže kupříkladu druhý nejpopulárnější webový framework na NodeJS, Koa, se na Deno dočkal implementace Oak. Nutno podotknout, že velmi povedené implementace.

Pokud jde o logo dinosaura, nepodařilo se mi dopátrat vysvětlení. Tipuji, že půjde o prostou podobnost se slovem dino, tedy zkráceným názvem pro dinosaura. A také o postavičku Dino ze seriálu The Flintstones.

Kdo maže Rust, ten jede

NodeJS napsal Ryan v C++. Pro asynchronní I/O použil knihovnu libuv. Pro Deno vzal Rust a Tokio, což je obdoba výše zmíněné asynchronní knihovny. Nutno podotknout, že Rust má v letošním roce silné momentum. Nejen v souvislosti s Deno, ale především v souvislosti s WebAssembly. Tam je Rust s přehledem nejpoužívanější výchozí platformou. Co víc, tu samou popularitu požívá Rust i v případě WASI (WebAssembly System Interface), což je výsledek iniciativy dostat WebAssembly mimo browser. Tím se nám zdánlivě nesouvisející témata potencionálně spojují. Je totiž možné, že příští „NodeJS/Deno“ o další dekádu později, už nebude o JavaScriptu. Avšak dost předbíhání. Teď je tu Deno, a my jsme si stále neřekli, co krásného nám aktuální Ryanovo usilí přináší.

Bonjour monde

Pro naše první Hello World je třeba mít nainstalovaný Deno runtime. Uživatelé MacOS sáhnou po obligátním brew install deno. No a uživatelé Linuxu a Windows to nebudou mít o moc těžší.

Vytvořme soubor test.js s obsahem:

console.log(`Bonjour le Monde de ${Deno.hostname()}`);

A spusťme jej pomocí:

deno run --unstable --allow-env test.js

Jistě, nemuseli jsme použít template literal s vloženým Deno.hostname(). Nemuseli jsme použít ani francouzštinu. Ale uznejte sami, vypadá to hezky. A k tomu jsme si prakticky demonstrovali některé aspekty runtime. Více k --unstable později.

Trváteli však na svém minimalistickém Hello World, tak pojďme vytvořit test.js s obsahem:

console.log('Hello World')

A spusťme jej prostým:

deno run test.js

CommonJS nezlobil, přesto šel z kola ven

Klientský JavaScript nebyl z počátku zamýšlený na rozsáhlé aplikace, proto nepotřeboval řešit modularitu. Naopak NodeJS potřebovalo modularitu řešit hned ze startu, proto implementovalo CommonJS. Mezi tím referenční JavaScript v roce 2015 přišel se systémem modulů ECMAScript Modules (ESM). Z hlediska modularity Deno následuje ES6, nikoliv NodeJS. Nepokoušejte se psát do kódu require(). Tedy alespoň do chvíle, než bude k dispozici knihovna kompatibility Node. Nedočkavci tak mohou aktuálně (10/2020) využít cca třetinu kompatibilních funkcionalit, které doposud byly implementovány. Shodou okolností require() mezi ně patří.

Asi await()

Báječná věc. Tedy pokud nejste Rich Harris, autor Svelte. Napíšeme v Deno:

var data = await fetch('https://jsonplaceholder.typicode.com/users');
var result = await data.json();
console.log(result);

Vše v pořádku běží. Top level await(). Balení do async() funkce není třeba.

Bezešvý TypeScript

Podpora TypeScriptu bývá u Deno vzpomínána na prvním místě. Až vytváří dojem, že Deno žádné jiné soubory, než s koncovkou .ts, nezná. Pravda je, že uživatel není zatěžován transpilací. Ta se ovšem v pozadí stále odehrává, protože V8 je čistě JavaScript engine. Transpilace proto běží odstíněna od uživatele. TypeScript jako prvotřídní občan, jak se rádo uvádí. Neznamená to ovšem, že si Deno neporadí s deno run app.js. Ostatně, jak už jsme se přesvědčili v odstavci Bonjour monde. Deno se v každé verzi snaží podporovat nejaktuálnější TypeScript.

--allow prezervativ

Bezpečnost NodeJS je oblast, u které Ryan zpytoval svědomí snad nejvíc. Budiž mu vše odpuštěno, neboť v případě Deno navlékl Ryan pomyslný prezervativ na vše, co nám může přijít na mysl. Zvlášť lze udělit povolení pro síťové operace, zvlášť pro přístup k souborovému systému, zvlášť pro přístup k environmental variables atd. Tato oprávnění jsou řízena přes parametry zadávané při spuštění. Oprávnění lze cílit na konkrétní síťové zdroje nebo adresáře. Oblast permissions se stále vyvíjí. Proto se vyplatí průběžně sledovat příslušnou pasáž Deno dokumentace.

Mimochodem, nechráněný styk nám Deno dovolí skrze --allow-all

Worker() dře, až se z procáku kouří

Deno podporuje Web Worker API, což nám umožňuje spouštět kód náročný na výpočetní výkon v jiném vlákně. V NodeJS byla podpora Web Worker API začleněna teprve nedávno. Stírá se tím z velké části výtka, která byla serverovému JavaScriptu vytýkána v souvislosti s vhodností na intenzivní I/O operace, ale nevhodností na výpočetně intenzivní operace.

Vlhký izomorfní sen

Sladění systému modulů mezi browserem a Deno na ESM je jistě sympatické. Ale co teprve browser JavaScript API. Pochopitelně tam, kde sjednocení dává smysl. Například window object nebo fetch().

No NPM no cry

Asi znáte vtip o nejtěžším objektu ve vesmíru, který zakřivuje prostor. Není to ani hvězda, ani černá díra, ale adresář node_modules. Každý NodeJS projekt má svou kompletní kopii všech knihoven. Deno na to jde jinak. Inspiraci zjevně našlo u Golangu. Každý externí modul je stažen pouze jednou v požadovaných verzích do home adresáře, a sdílen všemi Deno projekty, které jej potřebují.

Přesto máme možnost nastavit environmental variable DENO_DIR. A Moduly ukládat do adresáře, na který DENO_DIR odkazuje.

Kde tedy vzít knihovna a nekrást? Základem je Deno Standard Library a opatrovaná knihovna třetích stran. Poměrně dobře se rozjíždí repozitář nest.land.

Pokud na tom přesto trváme, můžeme využít NPM knihovny. Nejčastěji natažením z CDN, jako Skypack.dev nebo jpsm.org. Ovšem za předpokladu, že NPM moduly jsou kompatibilní s Deno API.

Palubní nářadí v podpalubí

Deno přichází s řadou sympatických utilit. Namátkou formátování zdrojových souborů deno fmt jistě našlo svou inspiraci v Golangu. Bundlování deno bundle nejspíše u ncc od Vercelu. A další utility, ke kterým by se hodilo vrátit samostatným článkem.

Z knihoven, po kterých se začne každý vývojář brzy pídit, můžeme vzpomenout reloadovač Denon, což je obdoba Nodemonu. Načítač .env Dotenv, který pod stejným názvem existuje v NodeJS. Logger Houston, který je alternativou k Winstonu z NodeJS. Slibně použitelná se zdá být standardní knihovna std/log, která umí v základu logovat do konzole, souboru a rotujícího souboru.

Bez Expressu ani ránu

Aplikace postavené okolo Express, a serverových web frameworků obecně, jsou bezpochyby nejčastější scénář využití NodeJS. Je tedy předpoklad, že nejinak tomu bude i v případě Deno.

Máme tu zdařilou implementaci Express s názvem Opine, která je silně kompatibilní s Express 4 API. Největší popularitu si ovšem získává, dříve zmiňovaný, Oak, který je silně inspirovaný Koa z NodeJS. O něco méně populární pogo je silně inspirované hapi z NodeJS.

Mimo to vzniká bezpočet dalších frameworků pro Deno. A nesmíme zapomínat na standard HTTP modul ze Standard Library, který je vhodné používat s routovací knihovnou reno.

Terminálové ambice

Už v NodeJS se dají vytvářet povedené CLI aplikace. Obzvlášť, když jsme spolu upekli emoji, omalovánky a hejblátka. Ryan se ovšem nechal slyšet, že ambice Deno v oblasti tvorby CLI nezůstávají při zemi. Rád by viděl viděl CLI, tvořená v Deno, minimálně tak populární, jako shell scripty nebo Python.

Pojďme si demonstrovat primitivní náhradu curl.

// karel.js
const url = Deno.args[0];
const res = await fetch(url);
const body = new Uint8Array(await res.arrayBuffer());

await Deno.stdout.write(body);

A spusťme přes:

deno run --allow-net karel.js https://zdrojak.cz

Hostname do domu, --unstable do ruky

Inu, hodí se zmínit, že jistým řízením osudu se stalo, že v Deno aktuálně jen tak lehce nezjistíme hostname systému, na kterém nám kód běží. Řešení je spustit Deno s dříve vzpomínaným parametrem --unstable. Hostname je pak k dispozici přes Deno.hostname().

Závěrem

Ačkoliv jsme vzali Deno z rychlíku, věřím, že i Vám přijde celkem fajn. Na menší projekty se dá nasadit bez okolků. Na rozsáhlejší projekty ještě chvilku vyčkáme. Na každý pád může Ryan Dahl klidně spávat. Hříchy NodeJS jsou napraveny. Nebo snad ne? Podělte se do komentářů.

Nahoru
Tento web používá k poskytování služeb a analýze návštěvnosti soubory cookie. Používáním tohoto webu s tímto souhlasíte. Další informace