Ein Entwickler stellte mir vor kurzem begeistert Electron vor. Er war damit in der Lage in kürzester Zeit eine Desktop-Apllikation zu bauen, die sowohl auf Windows als auch auf Mac lauffähig war. Zwar tummeln sich unzählige Application-Frameworks im Netz, die vorgeben dies ebenfalls gut zu können. Die darunter liegenden Technologien und die rasante Verbreitung von Electron waren für mich aber Grund genug, mir dieses Framework  doch mal etwas genauer anzuschauen.

Electron ist ein Open Source Software Framework unter der MIT-License, welches ermöglicht, Cross-Plattform-Applikationen zu erstellen. Also gemäß dem Java-Ansatz “Write once run anywhere” Applikationen, die – einmal programmiert – auf unterschiedlichen Plattformen wie Windows, Mac und Linux installiert und ausgeführt werden können.

Es wurde ursprünglich von der Firma GitHub als Basis für deren Text-Editor Atom entwickelt. Immer mehr Desktop-Anwendungen setzen auf dieses Framework. Unter anderem Microsoft mit Visual Studio Code oder Slack.

Eine Alternative zu Electron ist übrigends das ältere NW.js, welches einen sehr ähnlichen Ansatz verfolgt. Eine Übersicht zu den  Unterschieden ist hier zu finden.

Unter der Motorhaube

Technologisch besteht Electron im Wesentlichen aus den folgenden Komponenten:

  • Programmiersprache: JavaScript
  • Laufzeitumgebung: Google’s Chromium mit V8 Engine
  • UI: HTML + CSS, native Widgets mit C/C++ Modulen
  • Packaging & Modularisierung: NPM / Node.js

Anders als z.B. bei Java werden bei Electron sowohl Laufzeitumgebung in Form von Chromium und Node.js mit der Applikation gepackt und ausgeliefert. Dadurch ist sichergestellt, dass die für die Applikation notwendige Laufzeitumgebung in der richtigen Version vorhanden ist.

Der Nachteil ist die Größe einer so gepackten Applikation (ca. 100 MB!) und der zusätzliche Packaging-Aufwand: Für jede Ziel-Plattform muss ein eigenes Paket “geschnürt” werden. Darüber hinaus ist das Vorhandensein meherer Laufzeitumgebungen mit unterschiedlichen Versionen auf einem Computer problematisch, denn diese müssen vor allem aus Sicherheitsgründen regelmäßig aktuell gehalten werden.

Da Electron/Chromium mit einem “Silent Update” Mechanismus kommt, ist zumindest die Möglichkeit gegeben, dies relativ unmerklich im Hintergrund durchzuführen und Packaging-Programme automatisieren den Build für verschiedene Plattformen. Zumindest für die Standardfälle 🙂

Electron installieren

Um Applikationen mit Electron erstellen zu können, müssen zunächst NPM und Node.js installiert sein. Wie das geht, kann man hier erfahren. Anschließend kann man über NPM wiederum Electron installieren, indem man folgendes Kommando ausführt:

npm install -g electron-prebuilt

Damit wird Electron auf deinem System installiert, inklusive aller nötigen Abhängigkeiten. Falls das nicht klappen sollte, kannst du weitere Details zur Installation  hier  finden. Anschließend kannst du Electron ausführen, indem du folgendes Kommando eingibst:

electron

Herzlichen Glückwunsch! Electron ist schon mal installiert.

Aufbau einer Electron-App

In der Regel besteht jede Electron-App aus einem Verzeichnis mit stets derselben Struktur darin:

my-electron-app/
├── package.json
├── main.js
└── index.html

pakage.json

Bei dieser Datei handelt es um eine NPM-Datei mit der deine Applikation beschrieben und parametrisiert wird, ähnlich wie die pom.xml bei Maven. Deine Applikation kann also gleichzeitig auch als Package im NPM-Universum verwendet werden. Darüber hinaus werden in dieser Datei Abhängigkeiten deiner Applikation definiert. Das alles ist nichts Electron-spezifisches. Es gehört zu Node.js/NPM. Nachfolgend ein Beispiel, wie der Inhalt dieser Datei aussehen könnte:

{
  "name"    : "my-electron-app",
  "version" : "0.1.0",
  "main"    : "main.js"
}

Hier wird  der Name der Applikation, deren Version und die initiale JavaScript-Datei definiert, welche ausgeführt werden soll, wenn Electron gestartet wird.

main.js

Diese Datei ist der Startpunkt deiner Applikation und kann deshalb auch als Launcher-File bezeichnet werden. Sie wird ausgeführt, wenn Electron gestartet wird. Deren Name muss in der packages.json angegeben sein. Fehlt dieser Eintrag in der packages.json, wird stets eine Datei mit dem Namen main.js erwartet.

index.html

In dieser Datei wird die eigentliche UI definiert. Es handelt sich um eine Standard-HTML-Datei mit allen Möglichkeiten wie man sie von der Web-Entwicklung her kennt.

Hello World

Nun wird es Zeit für die “Electron Hello World App”. Diese App soll nichts anderes machen, als “Hello World” in einem Electron-Fenster auszugeben.

Falls noch nicht geschehen, erstelle hierfür zunächst ein Verzeichnis my-electron-app und erzeuge darin die Dateien package.json, main.js und index.html wie oben beschrieben. Öffne dann die Datei index.html , um folgenden Inhalt hinzuzufügen:

<!DOCTYPE html>
<html>
<body>
    Hello World!
</body>
</html>

Dann in der Datei main.js folgenden Inhalt hinzufügen:

'use strict';

const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;

app.on('ready', function() {
    
    var window = new BrowserWindow({
        
        height: 500,
        width: 500
    });
    
    window.loadURL(`file://${__dirname}/index.html`);
    
});

Hier werden zunächst die nötigen Abhängigkeiten “importiert” und initialisiert. Anschließend wird asynchron definiert, was zu passiert hat, nachdem Electron gestartet ist. In diesem Fall soll also ein Browser-Fenster mit einer Größe von 500×500 Pixel gezeichnet und anschließend darin die Datei index.html geladen werden, die zuvor erzeugt wurde und unser “Hello World” enthält.

Um die Applikation  zu starten, wechsle in das Verzeichnis my-electron-app und führe dort das folgende Kommando aus:

electron .

Es sollte sich ein Fenster mit folgendem Inhalt öffnen:

Bildschirmfoto 2016-05-29 um 12.49.12

Herzlichen Glückwunsch zur ersten Electron Hello World App!

Packaging und Distribution

Als nächstes schauen wir uns an, wie eine Electron-App für unterschiedliche Plattformen gebaut werden kann. Dies kann auf verschiedene Arten erfolgen, wie hier beschrieben. Mit die einfachste ist es, das NPM-Modul electron-package zu verwenden, welches mit folgendem Kommando global installiert werden kann:

npm install -g electron-packager

Anschließend müssen wir noch die Datei packages.json editieren und  die Abhängigkeit zum Package electron-prebuilt durch das Property devDependencies spezifizieren:

{
  "name"    : "my-electron-app",
  "version" : "0.1.0",
  "main"    : "main.js",
  "devDependencies": {
    "electron-prebuilt": "^0.35.2"
  }
 }

Danach können wir unsere App bauen, indem wir folgendes Kommando innerhalb des Verzeichnisses my-electron-app ausführen:

electron-packager . --platform=darwin,win32 --arch=x64

Mit diesem Befehl bauen wir für die Plattformen Windows und Mac, allerdings nur für die 64-Bit-Varianten. Es gibt noch zahlreihe weitere Parameter, die hier erklärt sind.

Nachdem electron-packager erfolgreich ausgeführt wurde, legt es die erstellten Distributionen im Projekt-Verzeichnis my-electron-app in zwei Unterverzeichnisse mit den Namen my-electron-app-darwin-x64 und my-electron-app-win32-x64 ab. Der Inhalt dieser Verzeichnisse ist nun fertig für den Release unserer Hello World App auf Windows und Mac 🙂

Wie bereits erwähnt ist ein Nachteil von Electron die Größe der paktierten Distribution von 100MB und mehr, was auch bei unserer einfachen Hello World App der Fall ist. Dass diese Größe tatsächlich für viele ein Problem ist, zeigen viele Beiträge hierzu mit regen Diskussionen. Unter anderem entstand die Idee, eine “Shared Library” für alle Electron-Apps zu installieren. Dann wären wir allerdings wieder beim Java-VM-Ansatz. Es bleibt spannend, wie dieses Problem gelöst wird.

Community und Dokumentation

Im Privaten teile ich absolut die Ideologie von Open Source und glaube fest daran, dass wir keine so rasante technologische Weiterentwicklung in den letzten Jahren erlebt hätten, wenn es Open Source nicht gegeben hätte. Es ist die beste Art, Wissen zu tauschen und jedem zugänglich zumachen, um aufbauend auf bestehenden Technologien was noch größeres, tolles zu bauen. Electron ist hierfür ein ideales Beispiel, indem es auf den beiden großen Open Source Projekten Node.js und Chromium aufbaut.

Wenn es um teure Projekte meiner Investoren oder Kunden geht, die mehrere Jahre lang betreut werden müssen, fällt mir die Entscheidung aber nicht immer leicht. Zu Beginn habe ich mir hier allzu häufig die Finger verbrannt, indem Open Source Projekte von heute auf morgen eingestellt wurden und dann veralteten. Ein Umstieg auf Alternativen war oftmals mit viel zusätzlichem Aufwand verbunden.

Deshalb kommt in meinen Projekten nur Open Source Software zum Einsatz, welche die folgende grundlegenden Erwartungen erfüllt:

  • “Erwachsen genug” im Sinne von erprobt und stabil
  • hat eine breite Community
  • ist ausreichend dokumentiert
  • wird idealerweise durch ein Unternehmen im Hintergrund gewartet
  • technologisch nicht zu weit vom “Main-Stream” weg
  • OS-Lizenz ist vertretbar

Bei Electron ist das so eine Sache. Das Projekt selbst ist noch sehr jung und wurde erst vor ein paar Wochen in Version 1.0 veröffentlicht. Wichtige API-Calls ändern sich noch häufig. Teilweise so häufig, so dass manche Tutorials noch veraltete Beispiele zeigen, obwohl diese selbst erst wenige Monate alt sind.

Auf der anderen Seite baut es auf Node.js und Chromium auf und diese OS-Projekte wiederum gelten als sehr ausgereift und stabil.

Die offizielle Dokumentation ist zwar nicht immer auf dem neuesten Stand und manchmal etwas umständlich, aber insgesamt gut und Google bringt fast immer eine Antwort auf technische Fragen zu Electron. Das wiederum ist ein Zeichen für eine gesunde Community.

Zwar wurde Electron ursprünglich von GitHub entwicket und auch Microsoft und Slack verwenden es. Trotzdem gibt es kein Unternehmen, welches sich ganz der Wartung und Weiterentwicklung von Electron verschrieben hat. Hier sehe ich eine Gefahr. Ähnlich wie beim Electron-Vorgänger NW.js kann es nämlich schnell passieren, dass etwas noch “cooleres” auf den OS-Markt kommt und sich der Großteil der Community dann “forked” oder weiter zieht.

Technologisch ist Electron ebenfalls eine Ausnahme. Es ist nunmal ein ungewohnter Ansatz, Desktop-Applikationen mit JavaScript zu bauen. Einer Sprache, die vor wenigen Jahren noch von allen Seiten verteufelt wurde. Ich kann mich noch gut erinnern, als ich vor ein paar Jahren  in einem Projekt servseitiges JavaScript einführen wollte und mich alle im Team angeschaut hatten, als wie wenn ich nicht mehr alle Tassen im Schrank hätte. Heute finden es alle klasse 🙂 Einen ähnlichen Weg könnte JavaScript sicherlich auch auf dem Desktop gehen. Klassische “GUI-Programmierer” müssen allerdings dann umdenken bzw. Web-Programmierer an ihre Stelle treten. Ob das geht, hängt natürlich im Wesentlichen von der Team-Zusammensetzung bzw. Verfügbarkeit der Entwickler ab.

Die Open Source Lizenz von Electron in Form der MIT stellt hingegen vermutlich für die meisten Projekte kein Problem dar.

Fazit

Electron ist ein cooles und sehr junges Projekt. Die Tatsache, dass es von den hippen Unternehmen GitHub und Slack verwendet und unterstützt wird, gibt dem noch mehr Gewicht. Es verlagert den Spaß, den die Web-Entwicklung mit sich bringt endlich auch auf den Desktop. Die Community und Dokumentation ist ausreichend und man wird schnell produktiv. Das alles gefällt mir sehr gut.

Die Tatsache, dass es sich hierbei um ein sehr junges Projekt handelt und es (noch) keinen etablierten  “Pseudo-Standard” gibt, führt dazu, dass sich mit jedem Release Dinge ohne Abwärtskomptabilität ändern können. Die finale Paket-Größe von 100 MB und mehr ist für manche Projekte möglicherweise  ein KO-Kriterium.

In Summe ein sehr spannendes Projekt, das Spaß macht, aber noch mit einigen “Kinderkrankheiten” zu kämpfen hat. Vermutlich wird man aber noch viel von Electron hören, lesen und sehen. Ich freue mich darauf.

2 comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s