Ein kleiner Einblick in Deno.js

Portrait von Jan-Patrick Rönnau

veröffentlicht am 20.06.2022
geschrieben von Jan-Patrick Rönnau

Deno.js im Vergleich zu Node.js

Ein kleiner Einblick in Deno.js

Deno.js im Vergleich mit Node.js

Abb. 1: Deno LogoAbb. 1: Deno Logo

In vielen Unternehmen setzen Entwickler:innen Open-Source-Software ein. Die JavaScript-Laufzeitumgebung Node.js ist ein bekanntes Beispiel. Allerdings reißt die zum Teil harte Kritik an Node.js nicht ab. Grund genug, sich einmal Deno.js anzuschauen. Ist Deno.js als Alternative in der praktischen Arbeit geeignet? Ihr kennt das Problem wahrscheinlich: Ständig wird in Entwicklerforen über Node/npm pakete updates gemeckert, und immer wieder gab es zuletzt auch negative Schlagzeilen aufgrund von Problemen mit npm Paketen (siehe Quellen am Ende des Artikels). Aber Node.js gibt es schon sehr lange und genießt dadurch scheinbar eine Monopolstellung im Bereich Java-Scirpt-Laufzeitumgebung, weshalb sich viele Entwickler:innen mit den Problemen abfinden. Oder gibt es doch eine bessere Alternative? Kann Deno.js mit Node.js mithalten? Spätestens, seit Ryan Dahl 2018 auf der JSConf EU 2018 mit seinem Vortrag „10 Things I Regret About Node.js" sein neuestes Projekt Deno.js vorgestellt hat, steht die Frage im Raum, ob Deno.js der Nachfolger von Node.js sein kann. So viel vorweg: Die Antwort ist sicher kontextabhängig und kann nicht allgemein gegeben werden. An dieser Stelle möchte ich dennoch von meinen Erfahrungen mit Deno.js berichten und vor allem einige wichtige Aspekte im Vergleich zu Node.js beleuchten. Deno.js (ein Anagramm von Node) und Node.js sind beide Laufzeitumgebungen basierend auf Googles V8-JavaScript-Engine – mit dem großen Unterschied, dass Deno.js mit Rust und Node.js mit C++ geschrieben wurde. Beide Entwicklungsumgebungen arbeiten mit einem Single Threat Event Loop und führen Skripte und Hilfsbefehle auf einem integrierten Server aus. Beide sind Command Line Tools, welche eine große Anzahl an unterschiedlichen Anwendungen ermöglichen. „Deno is a simple, modern and secure runtime for JavaScript and TypeScript that uses V8 and is built in Rust." - https://deno.land/

Die Kurzbeschreibung vom Projekt sagt aus:

  • Deno.js ist „secure by default".
  • TypeScript wird in Deno.js „out of the box" unterstützt.
  • Deno.js kommt als einzeln ausführbares File ohne externe Abhängigkeiten.
  • Deno.js besitzt eingebaute Features, wie ein dependency inspector und ein code formatter.
  • Deno.js besitzt eine große Anzahl an integrierten Standard Modulen ( https://deno.land/std ).
  • Es gibt schon einige Firmen mit Interesse an Deno.js.

„Secure by default"?

Ein oft von Entwicklern angekreidetes Problem von Node.js ist die Sicherheit. Ryan Dahl entschied sich dafür, in Deno.js die Programmiersprache Rust zu verwenden. Dies führt dazu, dass durch die Restriktionen von Rust weniger Bugs durch Code Fehler auftreten können, welche zu Sicherheitslücken führen. Zusätzlich erhöht Rust die Performance im Vergleich zu C++. Der zweite große Sicherheitsaspekt ist, dass Deno.js den Anwendungscode in einer Sandbox ausführt. Das heißt, die Anwendungen haben keinen direkten Zugriff auf die Files, auf das Netzwerk oder auf die Umgebung des Rechners auf dem sie verwendet werden – außer, dies wird explizit mit allowance-flags oder der Zustimmung des Nutzers erlaubt.

Typescript out of the box?

Um nicht nur JavaScript, sondern auch TypeScript als first-class Language mit Deno.js verwenden zu können, ist ein TypeScript-Compiler direkt in Deno.js integriert. Dieser ermöglicht es, JavaScript und TypeScript gleichzeitig zu verwenden, ohne weitere Module und Änderungen an der Entwicklungsumgebung. Hierfür übersetzt Deno.js TypeScript zuerst mit dem TypeScript Compiler und der Rust Library „swc" in JavaScript. Nachdem der Code einen Type Check unterlaufen hat und umgewandelt wurde, wird der Code in einem Cache gespeichert, von wo er dann immer von der Anwendung aufgerufen werden kann. Mit der Angabe der .ts Datei-Endung kann Deno.js also problemlos ohne Voreinstellungen TypeScript-Code kompilieren. Dies setzt allerdings auch voraus, in Deno.js die Dateiendungen immer angeben zu müssen, damit der interne Compiler weiß, was wie kompiliert werden soll.

Deno.js kommt als einzeln ausführbares File ohne externe Abhängigkeiten?

Deno.js kommt im Vergleich zu Node mit einer großen standard Library und einem integriertem Package Manager daher. Zusätzlich unterstützt Deno.js die import Syntax von ES6 (der offizielle ECMAScript Module Standard). Das führt dazu, dass Deno.js ohne eine große Anzahl von externen Modulen viele Aufgaben bewältigen kann, wofür nur die Deno.js executable benötigt wird. Die standard Library wurde von Go's standard Library inspiriert und ist eine freie Übertragung (loose Port) von dieser. Praktisch ist auf jeden Fall auch die Integration verschiedener Tools in das Single-File-Binary von Deno.js, zum Beispiel ein code formatter, linter und dependency inspector. Dies macht externe Tools wie Prettier oder ESLint überflüssig. Die Möglichkeit, Third Party Modules via URL import in eine Anwendung einzubinden, ist auch vorteilhaft, weil ein externer package manager wie npm nicht gebraucht wird und die Third Party Modules dezentralisiert werden. Da Deno.js die Module beim ersten Starten der Anwendung cached, fällt auch das Problem weg, dass URLs offline gehen könnten. Und es sorgt dafür, dass die Module nicht jedes mal neu geladen werden müssen. Für den Fall, dass dies doch geschehen soll, kann die reload-flag gesetzt werden. Deno funktioniert auf Linux, macOS und Windows und lässt sich entweder über die Kommandozeile oder einen Installer installieren. Deno.js selbst ist dabei mit einer Größe von etwa 85 MB für ihren Funktionsumfang verhältnismäßig klein.

Was für Firmen haben bisher ihr interesse gezeigt?

Laut eigener Aussage haben sich bereits einige große Firmen wie z.b. Amazon, Microsoft und Siemens mit Deno.js als Entwicklungsumgebung auseinandergesetzt. Eine vollständige Liste mit verweisen auf die Projekte der jeweiligen Firma findet man unter:

https://github.com/denoland/deno/wiki#companies-interested-in-deno

Browser Kompatibilität:

Ein weiterer Aspekt, welchem sich Deno verschrieben hat, ist die gute Browser Kompatibilität. Technisch gesehen wird beim Benutzen der ES Module kein webpack oder anderes externes Tool benötigt, um den Code "Browser ready" zu machen. Trotzdem können Tools wie Babel diesen auf ES5 übersetzen und somit den Code auch zugänglich für ältere Browser machen, welche nicht die neuesten Features von JavaScript supporten (zum Beispiel ältere Versionen des Internet Explorer, die aber aus anderen Gründen eh nicht mehr zum Einsatz kommen sollten 😉). Die Deno API folgt den Browser APIs. Das heißt, Programmierer:innen können einfach zwischen beiden APIs wechseln. Deno.js bietet Zugriff auf das window Objekt im Browser. Dies ermöglicht die Nutzung von Dingen wie fetch und Event-Listener. Zusätzlich erlaubt es, Code zu schreiben, der sowohl browser- als auch serverseitig ausgeführt werden kann. Dies bedeutet auch, dass Deno.js Anwendungen, welche komplett in JavaScript geschrieben sind und ohne Deno namespace auskommen (Isomorphie), in allen modernen Webbrowsern ohne Änderungen ausführbar sind. Deno.js wird daher auch als Webbrowser für comand line scripts bezeichnet.

Community & Support

Node hat über die Jahre eine große Community aufgebaut, sowie viele Supporter und Third Party Module. Deno hat in diesem Punkt aufgrund seiner kurzen Existenz klar das Nachsehen. Für Node gibt es deshalb auch mehr Tutorials und Lösungsansätze für Probleme im Internet. Node.js nutzt CommonJS in Kombination mit npm und einem node_modules Ordner als zentrales Register für Third Party Module. Deno.js hingegen geht einen dezentralen Weg und setzt auf den Import via ES Module als URL aus dem Netz. Dennoch setzt Deno hier nicht nur auf externe Third Party Hosts, was wieder zu Sicherheitsproblemen führen könnte, sondern bietet seinen eigenen Hosting Service ( https://deno.land/x ) an. Npm hatte schon über 1,3 Millionen Module in 2019, deno.land/x dagegen bescheidene 4.527 (Stand: Mai 2022). Hierbei muss man aber auch beachten, dass Node.js daran arbeitet, ES Module zu supporten (stand Mai 2021) und Deno.js die Möglichkeit bietet, npm Module, welche nicht mit CommonJS sondern als ES Module geschrieben worden, zu nutzen.

Third Party Module

Deno bietet einen integrierten package manager und ermöglicht die Nutzung der ES6 import Syntax. Das führt dazu, dass die Third Party Modules dezentral auf separaten Webspace (wie z.b. Github) verwaltet werden können und kein externer package manager wie npm benötigt wird. Deno selbst bietet auch "verifizierte" (gewisse Guidelines müssen beachtet werden) Third Party Module unter deno.land/x an. Dies ist ein von Deno bereitgestellter Host Service, welches die verifizierten open source Module von GitHub cached. Alle Module sind also by default public und werden täglich aktualisiert, wenn ein neuer Github Tag für das Modul erstellt wurde. Dies bietet den Vorteil, dass die Module von dort sicher und kompatibel mit Deno.js standard library sind und die Domain übersichtlicher und einheitlicher ist. Man kann via https://jspm.org/, dem Content Delivery Network (CDN) esm.sh, oder anderer Seiten einige npm Pakete in Deno.js nutzen. Bei CDN handelt es sich um ein Repository, das npm-Pakete als ES-Module zur Verfügung stellt, welches esbuild nutzt, um die meist als CommonJS-Module vorliegenden Pakete in ES Module umzuwandeln. Die genutzten Pakete sollten keine Abhängigkeit auf den Kern von Node.js haben, da diese Schnittstellen in Deno.js so nicht existieren. Auch der Support von allen populären Datenbanken ist durch verifizierte Third Party Modules gegeben. Deno.js hat auch ein anderes Verfahren als Node.js was das Einbinden und Updaten von Third Party Modulen angeht. Alle dependencies, welche ein Modul mit sich bringt und natürlich auch das Module selber werden einmal gedownloaded und gecached und nur mit explizitem reload command neu geladen und aktualisiert. Seit Version 1.15 bietet Deno zusätzlich einen Kompatibilitätsmodus für Node.js an, welcher sich mit dem Command —compat aktivieren lässt. In dem Modus stellt Deno die globalen Variablen von Node.js zur Verfügung. Außerdem funktionieren darin die Import-Statements und require-Aufrufe für Node.js-Kernmodule. Derzeit implementiert Deno aber noch nicht alle Module. Das Deno-Repository bei GitHub bietet eine Liste der Module und den aktuellen Entwicklungsstand.

Sicherheit

Einer der größten Kritikpunkte von Dahl an Node.js ist der Sicherheitsaspekt. Clientseitiges JavaScript wird normalerweise in einer Sandbox im Browser ausgeführt, was verhindert, dass der Code Schaden am System verursachen kann. Node.js server-side JavaScript besitzt allerdings keine Sandbox und erlaubt den Anwendungen vollen Zugriff auf das System des Users. Auch erlaubt Node.js ausgehende requests und Zugriff auf die Umgebungsvariablen. Zusätzlich erlaubt C++ wild- und nullpointer. Deno löst das Problem zum einen mit der Verwendung von Rust, welches Buffer overflow und Memory Access Bugs verhindert, zum anderen dadurch, dass es den Anwendungscode in einer Sandbox ausführt und für den Systemzugriff die Genehmigungen in Form von Command-Line-Flags gegeben werden müssen. Zusätzlich ist dieser Zugriff auf den jeweiligen Pfad beschränkt, sodass z.b. die „–allow-read" flag nicht alle Dateien auslesen kann, sondern nur jene in dem Ordner, für den die Anwendung Berechtigung hat. Ein weiterer Unterschied in der Sicherheit ist, dass Deno.js immer bei einem ungehandelten Error direkt das Programm stoppt. Dies ist bei Node.js nicht der Fall. Deno stellt ebenfalls sicher, dass unhandled promises sofort "sterben", Node.js hingegen tut dies nicht, welches zu code crashes und ungewollten Erros führen kann.

Fazit

Deno.js bietet gegenüber Node einige Vorteile und Neuerungen. Dies ist nicht verwunderlich, schließlich hat Ryan Dahl beide Projekte ins Leben gerufen hat und die Schwächen von Node.js selbst beschrieben. Der große Vorteil von Node.js ist sein Alter. Daraus resultieren eine große Community, viele Module, viele Tutorials und Lösungsansätze für Probleme. Folglich ist Node.js sehr stabil und ausgereift geworden. Deno.js hat hier den Vorteil, dass es auf Node.js als Vorlage zurückgreifen kann und somit die Fehler nicht ein zweites Mal begehen muss. Was genau macht Deno.js in der Webentwicklung nun alles besser als Node.js? Ob man bei vielen Aspekten von "besser" sprechen kann, lässt sich sicher diskutieren. Es bietet auf jeden Fall Alternativen für Probleme, die sich in Node.js nicht "out of the box" lösen lassen. Die höhere Sicherheit von Webanwendungen welche Deno.js nutzen, ist allerdings ein entscheidender Punkt, der bei Deno.js unabhängig von der Anforderung im Einzelfall besser ist als bei Node.js.

Wird Deno.js Node.js irgendwann ablösen?

Erst einmal wohl nicht. Dies soll es aber auch nicht. Deno.js soll laut Ryan Dahl nur eine Alternative für Node.js sein und die Entwicklungsumgebung keinesfalls ablösen. Und mit dem momentanen Stand tut Deno.js genau das, für das es vorgesehen war.Es bietet eine Umgebung für spezifische Herausforderung, die Node.js nicht oder nur umständlich ausführen kann. Die Entwickler von Node.js haben bereits angekündigt, dass sie einige der von Dahl mit Deno.js angesprochenen „Fehler" beheben wollen, und einige Probleme wurden sogar bereits angegangen (zum Beispiel import via ECMA 6 Standard). Ebenfalls haben die Entwickler von Node.js angekündigt, dass sie einige Kritikpunkte nicht als Fehler sehen und diese dementsprechend auch nicht ändern werden. - How Node.js Is Addressing the Challenge of Ryan Dahl's Deno – The New Stack Deno.js bietet also eine Menge Potenzial, um zu einer guten Alternative zu Node.js zu werden. Hierfür bietet es einige Neuerungen und Änderungen im Bereich der JavaScript Entwicklungsumgebung, welche von der Community über die Jahre für Node gewünscht waren, aber nicht umgesetzt wurden. Solange sich die Webentwicklung nicht komplett von JavaScript und TypeScript weg entwickelt, sollten beide Entwicklungsumgebungen eine gute Zukunft haben. Auch gibt es die Möglichkeit, dass Ryan Dahl mit Deno.js eines Tages, wie es damals mit dem io.js Projekt geschehen ist, wieder zurück zu Node.js findet und dadurch Node. js auf ein neues Level bringt. Wenn man zu dem Erfolg von Deno.js beitragen will, hilft es, sich aktiv in der Community oder an der Entwicklung zu beteiligen. Denn eine große Community ist einer der Hauptaspekte welcher Node.js groß gemacht hat. Die Community hat auch dazu geführt, dass Node.js zum Branchenprimus in diesem Bereich geworden ist. Meiner Meinung nach lohnt sich, in Deno.js reinzuschauen und sich selbst ein Bild zu machen, ob die Entwicklungsumgebung etwas für einen ist, mit dem man besser arbeiten kann. Die Implementierung von TypeScript als native Sprache direkt in der Plattform, die komfortablen Features der Deno-Kommandozeile, sowie die schrittweise Einbindung des Node.js-Ökosystems tragen dazu bei, dass Deno in Zukunft wohl ein ernstzunehmender Konkurrent für Node.js werden kann. Für uns Entwickler:innen kann das nur von Vorteil sein, da Konkurrenz bekanntlich das Geschäft belebt.

Quellen

  1. https://deno.land/
  2. https://deno.land/std
  3. https://deno.land/x
  4. https://www.heise.de/news/Paketmanager-npm-Paketabhaengigkeiten-fuer-Angriff-missbraucht-6594520.html
  5. https://www.heise.de/developer/meldung/JavaScript-Paket-aus-NPM-entfernt-Node-Babel-und-Co-scheiterten-beim-Build-3148796.html
  6. https://www.heise.de/news/Paketmanager-npm-Entwickler-macht-eigene-Packages-unbrauchbar-6322366.html
  7. https://www.youtube.com/watch?v=M3BM9TB-8yA
  8. https://www.heise.de/hintergrund/JavaScript-Runtime-Deno-das-bessere-Node-js-6586323.html?seite=3
  9. https://www.rlogical.com/blog/nodejs-vs-denojs-which-is-better-for-you/
  10. https://esm.sh/
  11. https://jspm.org/
  12. https://thenewstack.io/how-node-js-is-addressing-the-challenge-of-ryan-dahls-deno/
  13. https://github.com/denoland/deno/wiki#companies-interested-in-deno