Blog

JavaScript Days | Angular Days | React Days | HTML & CSS Days
Die großen Trainingsevents für JavaScript, Angular, React, HTML & CSS
16. - 19. März 2020 | München
16
Jul

Electron: Wie man Web-Technologien auf den Desktop bringt – Jakob Westhoff im Interview

Mit Electron bringt man JavaScript auf den Desktop, mit WebAssembly dreht man den Spieß um: Welche Technologien stecken hinter den Konzepten und wie unterschiedlich sind die Ideen hinter Electron und WebAssembly wirklich? Das haben wir Jakob Westhoff im Interview auf den JavaScript Days 2019 gefragt.

Mit Electron lassen sich JavaScript-Anwendungen auf den Desktop holen. Was aussieht wie eine ganz normale Anwendung, wird im Hintergrund aber doch in einer unsichtbaren Browser-Instanz ausgeführt. Damit wirken Web-Apps wie native Desktop-Anwendungen. Neben dem Trend, JavaScript auf diese Weise auf den Desktop zu holen, gibt es mit WebAssembly nun auch eine Option dafür, den gegenteiligen Weg zu beschreiten und C/C++-Anwendungen in den Browser zu bringen. Die Grenzen der Plattformen verschwimmen, die technologischen Kategorien dahinter lösen sich auf. Auf den JavaScript Days 2019 haben wir mit Jakob Westhoff darüber gesprochen, wie sich Electron über die Jahre weiterentwickelt hat und wie man WebAssembly sogar zusammen mit Electron nutzen könnte.

JavaScript Days: Was ist Electron eigentlich?

Jakob Westhoff: Electron ist im Prinzip die Möglichkeit, eine Webapplikation mit den Technologien, die wir als Webentwickler kennen, also HTML, JavaScript oder CSS und allem, was da irgendwie dranhängt, als eine Desktopapplikation zu verpacken und dann auch dementsprechend auszuführen. Also als eine Standalone-Applikation, die einfach so ausgeführt werden kann, und die sich, wenn man sich entsprechend Mühe gibt, auch so verhält und auch so aussieht wie eine native Applikation auf dem System.

JavaScript Days: Kannst du uns vielleicht auch nochmal ein Beispiel geben, für welche Art von Anwendung das gut geeignet ist?

Jakob Westhoff: Prinzipiell ist das tatsächlich für nahezu jede Anwendung gut geeignet, die von einem Team entwickelt wurde, das diese Technologien beherrscht. Man will vielleicht jetzt nicht unbedingt irgendwie eine Spiele-Engine oder eine 3D-Engine damit schreiben, wobei man das mit WebGL mittlerweile sogar könnte, wenn man denn wollte – es gibt sogar Beispiele dafür –, aber eine normale Applikation des täglichen Gebrauchs. Wir haben große Beispiele, die auch tatsächlich das Electron Framework benutzen: von Microsoft den Visual Studio Code Editor, den wahrscheinlich viele Entwickler sogar kennen. Der ist komplett eine Webapplikation und in Electron geschrieben. Den Atom Editor von GitHub gibt es. Es gibt Applikationen wie zum Beispiel Nylas N1 Mail. Das ist ein Full-blown-Mailclient mit allem, was dazu gehört, der als Web-App funktioniert. Es gibt Git-Clients, es gibt Terminals, es gibt alles Mögliche, also die Liste ist sehr lang. In meiner Session habe ich am Anfang immer so einen Slide, auf dem ich ein paar ausgewählte Icons von Applikationen zeige, und der Slide ist randvoll, und das sind bei weitem nicht alle.

JavaScript Days: Auf der technischen Seite: was steht denn dahinter, wenn die Webtechnologie auf den Desktop kommt?

Jakob Westhoff: Im Endeffekt war Electron am Anfang eine sehr dünne Wrapper-Schicht, die eigentlich nur die Kommunikation zum Betriebssystem geregelt hat, bedeutet, wir haben ja spezielle Anforderungen. Wir wollen auf das Dateisystem zugreifen, wir wollen Systemdialoge aufmachen und ausführen können, wir wollen vielleicht auf irgendwelche Konfigurationsschnittstellen zugreifen, Dock-Icons positionieren und solche Sachen, die eine normale Webapplikation im Browser nicht könnte. Dafür brauchen wir eine Schnittstelle, die mit dem Operating-System redet und dann solche Sachen für uns erledigt, die wir aus unserem Webkontext ausführen können. Electron bietet das im Endeffekt dadurch, dass sie einen Node.js mit einem Chrome in Verbindung bringen und das als ein Paket kombinieren und diese APIs am Ende bereitstellen. Das ist im Prinzip ein in sich geschlossenes Browser-Node.js-System, mit dem wir dann arbeiten können.

JavaScript Days: Node.js hast du gerade schon genannt als Grundlage der Technologie. Wie sieht es denn mit anderen Webtechnologien aus oder mit Frameworks wie Angular. Wie kann man die Dinge miteinander kombinieren?

Jakob Westhoff: Im Endeffekt funktioniert das genauso wie bei jeder normalen Webapplikation auch. Das heißt, ich habe Node.js zur Verfügung, ich habe diesen Browser, diesen Chrome zur Verfügung, und im Endeffekt läuft mein Angular, mein React oder meine View oder was auch immer man da für ein Framework haben möchte, ja sowieso in meinem Browser. Das kann also auch in dem Browserteil von einer Elektron-Applikation laufen, und das ist dann natürlich wieder absolute Geschmacksache eines Entwicklerteams, was es da für ein Problem zu lösen versucht, was es da für ein Framework benutzt. Also im Endeffekt binde ich das genauso ein, wie ich das in der normalen Welt in einem Browser auch tun würde. Es gibt ein paar Spezifika, auf die ich dann in meiner Session auch eingehe, wie man das jetzt in die Electron-Welt besonders schön einbaut, damit man einfacher und bequemer entwickeln kann. Da gibt es solche Sachen wie Electron Compile von Slack – der Slack Client ist im Übrigen auch Electron – das ist so ein System, bei dem kann man dann alle möglichen Style Cheats und Transpiler, wenn man z. B. TypeScript verwenden möchte, einfach mit reinstecken, und das integriert das sehr schön in den ganzen Entwicklungsworkflow und baut das automatisch neu bei Änderungen oder dergleichen.

JavaScript Days: Wie sieht es bei Electron mit Hürden aus, die es am Anfang zu überwinden gibt, oder auch Grenzen, die die Technologie setzt?

Jakob Westhoff: Was bei Electron am Anfang am Wichtigsten zu verstehen ist: Man hat das gleiche Prinzip, wie wenn man eine Server-Client-Applikation im Web schreibt. Man hat einen Hauptprozess, der erstmal isoliert von dem eigentlichen Browser läuft, das heißt, von der View, von dem Fenster, das man anzeigt, und der die ganzen Systemfunktionalitäten kontrolliert. Man hat diesen Browser, der im Endeffekt einfach nur die Webseite anzeigt und eben das JavaScript, oder was auch immer man da hat, ausführt, und man muss das auch genauso entwerfen. Das heißt, diese beiden Komponenten müssen auch entsprechend über einen Kommunikationsbus, das ist in dem Fall nicht HTTP, sondern eine eigene Schnittstelle, die für die Interprozesskommunikation benutzt wird, verwenden. Jedoch muss man die gleiche Denkweise haben, und das Witzige ist, dass wir ja Webentwickler sind, die eigentlich genauso denken, weil wir solche Applikationen entwickeln. Aber wenn wir an Desktopapplikationen denken, denken wir immer: „Das kann ja so nicht sein, das muss ja ein anderes Prinzip sein.“ Es ist tatsächlich für viele Webentwickler, habe ich festgestellt, schwierig, erstmal zu begreifen, dass das ja eigentlich genau das Gleiche ist, was sie jeden Tag machen, nur dass sie eine andere Schnittstelle benutzen. Wenn man das einmal begriffen hat, ist es eigentlich relativ simpel, das zu tun. Mit Blick auf die Hürden bei dem, was jetzt die Ausführung des Ganzen angeht, muss man sich halt darüber im Klaren sein, dass das eben eine Webapplikation ist, die im Browser läuft. Es gibt zwar Möglichkeiten, das so aussehen zu lassen wie zum Beispiel eine native App, und es gibt auch Applikationen, die das sehr gut hinkriegen. Die kann ich, wenn ich nicht weiß, dass es eine Electron-App ist, nicht von einer System-nativen Applikation unterscheiden. Aber das erfordert sehr viel Arbeit. Also meines Wissens existiert keine fertige Cross System Library in irgendeiner Form, die das User Interface bereitstellt, was dann auf jedem System systemspezifisch aussieht. Es wäre schön, wenn es sowas gäbe. Das gibt es aber schlichtweg nicht, weil wahrscheinlich den meisten das nicht die Mühe wert ist und man relativ schnell auch feststellt, dass Benutzer eine Applikation dann als nativ wahrnehmen, wenn sie das Ding als Programm starten, selbst wenn das ihnen ein Web-UI präsentiert, wie zum Beispiel Googles Material Design oder sowas. Dann nehmen sie das trotzdem als nativ wahr und deswegen machen sich viele die Mühe nicht. Aber das ist tatsächlich eine der Hürden, die viele haben: Am Anfang gehen sie an die Sache ran und sagen, „super, eine Cross-Operating-System-Plattform, um Applikationen zu entwickeln“, möchten dann aber auch, dass es auf jedem System nativ aussieht. Das kann man machen, ist aber sehr viel Arbeit, und man muss den Leuten erstmal sagen, dass sie es in den meisten Fällen gar nicht brauchen. Das ist so eine der technischen Hürden. Ansonsten haben wir eben mittlerweile mit den verschiedenen Bibliotheken, die sich darum entwickelt haben, wie Electron Builder, Electron Packager, Electron Forge – das ist so ein Scaffolding-Tool, was ich dann gerne auch zeige – und Electron Compile, eigentlich ein sehr schönes Ökosystem drumrum, sodass man nicht mehr viel selber machen muss. Also man kann hergehen und einfach Electron Forge nutzen, das kann ich nur jedem ans Herz legen. Es ist zwar schon ein bisschen älter und auch schon länger nicht mehr aktualisiert worden, aber das ist auch nicht schlimm, weil es genau das tut, was es soll. Es ist im Endeffekt sowas wie Angular CLI oder Create React App, nur für Electron. Man sagt dem Ding, dass man ein neues Projekt mit den und den Features haben will, dann setzt es einem das auf und dann ist das da. Es ist richtig zusammengesteckt, und man kann direkt loslegen, zu entwickeln. Es hat ein Build-System und Möglichkeiten, irgendwelche Installer zu paketieren und das dann direkt auch mehr oder weniger auszuliefern. Das ist tatsächlich ein sehr schönes Environment, das es mittlerweile gibt. Das war früher eine sehr große Hürde, die es mittlerweile glücklicherweise eigentlich nicht mehr gibt.

JavaScript Days: Das klingt gut, Electron ist ja aber gar nicht mehr das einzige Tool oder Konzept, das das Web auf den Desktop bringen soll. Hier sind Progressive Web Apps noch ein ganz großes Stichwort. Wo liegen da die Unterschiede zu Electron?

Jakob Westhoff: Progressive Web Apps (PWAs) haben vom Grundprinzip her die gleiche Idee, sie sind aber eingeschränkter insofern, als sie auf sehr viel weniger APIs Zugriff haben. Sie haben im Endeffekt erstmal nur auf die gleichen APIs Zugriff wie auch eine Webapplikation. Das heißt, ich bin da erstmal eingeschränkter in dem, was ich machen möchte. Wenn ich zum Beispiel hergehen möchte und will irgendwie systemnäher mit irgendeinem Gerät reden oder dergleichen, kann ich das nicht so einfach tun, auch wenn wir im Web mittlerweile anfangen, Schnittstellen zu entwickeln für USB, für Bluetooth und für alle möglichen anderen verschiedenen Sachen. Obwohl wir uns da auch auf dem richtigen Weg befinden, fehlt das immer noch so ein bisschen. Diese wirkliche Systemnähe habe ich nur bei Electron. Auf der anderen Seite hat eine PWA an der Stelle eigentlich erstens den Vorteil, dass sie auf mobilen Endgeräten funktioniert, was Electron überhaupt nicht tut, die ist rein für den Desktop, also für einen Laptop oder normalen PC, gedacht. Zweitens haben wir bei PWAs den Vorteil, dass sie grundsätzlich ein anderes Konzept verfolgen. Man geht davon aus, dass wir den Browser da sowieso installiert haben, wir brauchen doch nur eine Instanz davon, und die kann diese PWA mehr oder weniger mit ausführen. Electron ist immer ein in sich geschlossener Prozess. Das heißt, wenn ich jetzt vier verschiedene Electron-Applikationen auf meinem System öffnen würde, macht es für alle einen komplett eigenen Browser und Node.js-Prozess auf, was am Ende natürlich viel mehr Ressourcen und Speicher verbraucht. Das ist bei den meisten Anwendern kein großes Problem, aber man muss es natürlich berücksichtigen. Da wäre irgendwas, das sich einen Teil der Ressourcen teilt, natürlich irgendwie schöner, und das würde eine PWA im Endeffekt tun. Es ist sogar so, dass man Teile der Technologien für PWAs auch in Electron verwenden kann, also man kann so Dinge wie Service Worker durchaus auch in Electron-Apps benutzen und sich da entsprechend im Service Worker registrieren, um spezifisches Cashing, irgendwelche Ressourcen zu machen oder dergleichen. Das funktioniert auch. Ich habe zwar tatsächlich jetzt so im weiteren Umfeld noch nicht gesehen, dass jemand das aktiv tut, aber es würde funktionieren. Das heißt, man kann versuchen, das Beste aus beiden Welten ein bisschen zu kombinieren. Ich glaube, das sind zwei verschiedene Ansätze, ein und dasselbe Problem zu lösen, und wir müssen einfach mal in der Zukunft gucken, welches davon sich durchsetzen wird.

JavaScript Days: Wenn du sagst, dass es da um zwei verschiedene Ansätze für dasselbe Problem geht, denkt man natürlich auf der anderen Seite bei Web Assembly genau in die andere Richtung. Damit hat man ja eigentlich den genau gegenteiligen Trend. Was, denkst du, steckt hinter dieser Entwicklung?

Jakob Westhoff: Web Assembly ist ein bisschen was anderes, weil es nicht darum geht, eine Desktopapplikation irgendwie ins Web zu bringen, sondern da geht es eigentlich darum, andere Sprachen ins Web zu bringen, und damit sind Sprachen gemeint, die zum Beispiel manuelles Memory Management und dergleichen bieten, oder sagen wir mal, eine statischere Kontrolle über Speicher und eventuell auch eine etwas systemnähere, optimierte Ausführung von spezifischen Codefahnen bieten. Es geht also darum, sich da nicht nur auf einen Typus JavaScript zu verlassen, wo wir doch mittlerweile sowieso sehr viele verschiedene Sprachen haben, die wir in JavaScript kompilieren, damit wir sie da ausführen können. Sei es jetzt sowas wie TypeScript, oder es gibt, wie der erste Ansatz mit Emscripten, zum Beispiel die Idee: Wir könnten auch eigentlich mal versuchen, irgendwie C durch einen Umweg in JavaScript zu übersetzen, um das da dann auszuführen. Das ist natürlich eine schöne Idee, aber eigentlich nur ein Hilfsmittel. Web Assembly ist hingegen die Idee, mal doch von der grundsätzlichen JavaScript Engine, die da dranhängt und das dann ausführt, wegzugehen. Wir haben ja schon lange keine JavaScript-Interpreter mehr, sondern virtuelle JavaScript-Maschinen, die sogar entsprechende Just-in-Time-Compiler haben, die dann wirklich Codepfade in nativen Maschinencode übersetzen, um das Ganze zu beschleunigen. Das heißt, wir haben eigentlich eine Technologie gebaut, um diese spezifische Sprache möglichst schnell ausführen zu können, was auch super ist. Dann sind wir hergegangen und haben andere Sprachen in diese Sprache übersetzt, damit wir die im gleichen Environment ausführen können. Web Assembly bietet jetzt zum ersten Mal die Möglichkeit, diesen komischen Zwischenschritt von JavaScript einfach wegzulassen und das, was wir kompilieren, direkt in eine Form von Assembly Language, also in ein reduziertes Instruction Set zu übersetzen, das wir dann im Browser ausführen können. Das hat die Vorteile, dass wir erstens aus anderen Sprachen dahin kompilieren können, und dass zweitens viele Dinge einfach schneller laufen. Wir haben die automatische Garbage Collection von JavaScript nicht, das heißt, wenn wir wissen, was wir da genau machen, wenn wir spezifische Algorithmen oder Module haben, die wir viel effizienter programmieren können, wenn wir mehr Kontrolle über das System an sich und die Speicherkontrolle haben, dann können wir das damit umsetzen. Da wir mittlerweile sehr viele, auch sehr rechenintensive Dinge im Web tun, wie zum Beispiel Engines, die Maschine Learning in Browsern machen, oder Dinge, die allein nur auf Basis von Maschine-Learning-Modellen von irgendwelchen Deep Neural Nets dann einfach nur Erkennungen von Videobildern usw. live machen. Gerade solche Operationen sind sehr rechenintensiv. Auf der anderen Seite sind die aber auch sehr gut optimierbar, weil es dafür gut optimierte Algorithmen gibt. In JavaScript kann man sie aber nicht so einfach abbilden, in sowas wie Web Assembly schon. Daher haben wir eigentlich das Ziel, dass dieses Ganze dynamische Web, das wir mit JavaScript bauen, unabhängiger von dieser Sprache selber wird. Um zu zeigen, dass das auch tatsächlich gar nicht im Kontrast zu sowas wie Electron steht: Man könnte theoretisch problemlos – und das ist tatsächlich auch etwas, das ich mir noch nicht angeguckt habe, aber das werde ich mir definitiv mal angucken – natürlich auch in Electron in die Browserinstanz ein Stück Web Assembly laden und das ausführen. Das wäre auch durchaus ein Vorteil, weil es, je nachdem, was ich da mache, eben nochmal einen Geschwindigkeitszuwachs bietet, den ich eventuell sonst nicht haben kann. Daher ist das eine sehr schöne Entwicklung, was Web Assembly angeht, und ich freue mich, dass das mittlerweile in fast allen großen, also aktuellen Browsern supportet wird. Das ist eine schöne Zukunft.