Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 36 Min.

Programmierung für Desktop und Mobile

Mit Svelte erstellte Entwicklungsergebnisse beschleunigen auch die Bereitstellung von Apps für Desktop und mobile Endgeräte.
Im Mittelpunkt der Programmierung mit Svelte stehen primär zwar Websites und Web-Apps, jedoch eignet sich der Quellcode auch für die Portierung von Entwicklungsergebnissen auf den Desktop oder mobile Endgeräte (Smartphone, Tablets). Für den Desktop (macOS, Linux und Windows) stehen verschiedene Cross-Plattform-Tools zur Verfügung. Für die Portierung auf mobile Endgeräte kommen Softwaretechniken wie Hybrid-Apps, Hybrid-Mobile-Apps und Progressive Web-Apps (PWAs) in Betracht. Zu den im Web-Umfeld wohl bekanntesten Cross-Plattform-Tools für den Desktop zählen Electron und NW.js. Electron als Projekt gehört wie Node.js inzwischen zur OpenJS Foundation.

Svelte – ein Ökosystem für Vanilla-JavaScript

1: Svelte – Compiler und Framework
Weniger in der Öffentlichkeit stehen die Entwicklungsumgebungen Framework7, Neutralinojs, NativeScript, NodeGui, Tauri und Wails, die neben dem Web, den Desktop und in Einzelfällen auch die mobile Welt unterstützen. Bei einer Hybrid-App handelt es sich um eine Web-App, die mittels einer sogenannten WebView die Web-App auf dem mobilen Endgerät darstellt. Eine Hybrid-Mobile-App erweitert eine Hybrid-App um native Features des mobilen Endgeräts – diese basieren auf einer Integration von Apache Cordova oder Capacitor von Ionic. Unter einer PWA versteht man eine Web-App/Website, die im Browser läuft und über zahlreiche Merkmale einer Native-App verfügt. Da ein Browser verschiedene Betriebssysteme unterstützt, eignet sich eine PWA auch für den Desktop und mobile Endgeräte.

Electron – ein Schwergewicht auch für Svelte/SvelteKit zuverlässig nutzbar

Electron gilt inzwischen als gängige Lösung für die Entwicklung/Portierung eines mit JavaScript/HTML und CSS programmiertem Quellcode auf den Desktop. Das Framework kommt in einer Vielzahl von Open-Source-Projekten wie Atom, Eclipse Theia, GitHub Desktop, Visual Studio Code oder WordPress Desktop zum Einsatz. Aufgrund der zugrundeliegenden Webtechnologien verträgt sich Electron mit allen gängigen Frameworks (Angular, React, Vue.js). Insbesondere unterstützt Electron die Einbindung von Vanilla-JavaScript, so dass sich auch die Compiler-Technologie von Svelte und das SvelteKit-Framework nutzen lässt. Dabei basiert die Cross-Plattform-Entwicklung mit Electron auf Chromium und Node.js. Damit kann man eine in Electron laufende App auch auf mobilen Endgeräten bereitstellen.Chromium als Open-Source-Projekt von Google entspricht einer Library für die Programmierung von Webbrowsern. Google setzt Chromium für die Entwicklung des eigenen Webbrowsers Google Chrome ein. Node.js führt JavaScript/ECMAScript-Quellcode als Laufzeitumgebung über mehrere Plattformen hinweg aus. Vereinfacht ausgedrückt nutzt Electron Chromium als HTML-Render-Engine und Node.js als Laufzeitumgebung für JavaScript. In Chromium als auch in Node.js kommt die JavaScript-Engine V8 von Google zum Einsatz. Google hat die V8-Engine in C++ implementiert, sie bietet eine hohe Performance und compiliert für alle gängigen Prozessor-Architekturen (x86, ARM, MIPS). Zusätzlich gibt es Portierungen von V8 auf verschiedene Serverumgebungen.Um vorhandene Svelte/SvelteKit-Apps neben dem Web, auch auf dem Desktop und mobilen Endgeräten bereitzustellen, stellt Electron einen gangbaren Weg dar. Im Projekt zur Portierung fällt vorwiegend Aufwand zur Einbettung der Svelte-Sourcen (Bild 1) in Electron als Wrapper und dem App-Management an. Electron erzeugt beim Packaging der App schnell einige hundert Megabyte, was die Dateigröße betrifft. Damit dauert nicht nur die Übersetzung unter Umständen lange, vielmehr wirkt sich eine derart große Datei auch negativ auf die Verteilung der App und ihren Startvorgang aus. Eine Electron-App entspricht während der Laufzeit einen eigenständigen Chromium-Prozess, der ausreichend Prozessorleistung und genügend RAM auf der Zielumgebung benötigt.
Die Demo-Appvon Svelte mit TypeScript läuft in der Chromium-WebView von Electron(Bild 1) © Autor

NW.js für Svelte-Quellcode schlechter geeignet

NW.js (ehemals node-webkit) ist ein Cross-Plattform-Tool für Desktop-Apps, das die Programmierung mit JavaScript/HTML und CSS unterstützt. Das bei Intel als Open-Source-System entwickelte NW.js basiert auf der HTML-Engine WebKit von Apple und rückt damit HTML ins Zentrum – im Unterschied zu Svelte einem Ökosystem für Vanilla-JavaScript. NW.js kombiniert WebKit zwar mit Node.js und macht so JavaScript einem Entwickler zugänglich, jedoch erfordert der Einsatz von NW.js die Kenntnis neuerer JavaScript-Konzepte wie dem Node- und Web-Context.

Einbettung von Electron als Wrapper in eine Svelte/SvelteKit-App

Für den Einsatz von Electron als Wrapper hat sich eine eindeutige Trennung von Electron- und Svelte/SvelteKit-Sourcen im Projektordner als vorteilhaft erwiesen. Dazu erweitert der DevOps-Mitarbeiter die bisherige Svelte/SvelteKit-App (siehe Teil 1 und 4) um zwei weitere Ordner: einen zur Bereitstellung des Electron-Grundgerüsts und einen zur Ablage der Build-Ressourcen der Electron-App. Der Ordner mit dem Electron-Grundgerüst befindet sich innerhalb des src-Verzeichnisses mit dem bisherigen Svelte/SvelteKit-Quellcode. Für die Ablage der Build-Dateien der Electron-App empfiehlt es sich, diese außerhalb des src-Ordners in einem eigenen app-Ordner in der Root des Projektordners vorzunehmen. Ebenso erleichtert ein eigenständiger Ordner das Management der seitens der Electron-App zu unterstützenden Zielumgebungen.Das Grundgerüst der Electron-App besteht aus dem Quellcode für den Hauptprozess (main.js/ts-Datei), dem Quellcode der grafischen Benutzeroberfläche (index.html-Datei) und den Metadaten der benutzten Pakete (package.json-Datei). Dazu muss lediglich der Quellcode für main.js/ts-Datei neu implementiert werden – dieser erzeugt die Fenster für den Electron-Hauptprozess und greift auf die Svelte/SvelteKit-Ressourcen zum Rendern der Svelte-App zurück. Wobei der Renderer für jede zusätzlich von Svelte erzeugte Webseite einen weiteren Renderer-Prozess unter eigener Regie ausführt und überwacht. Für das Handling des Chromium-Fensters stellt Electron eine Vielzahl von Methoden, auch für Tests durch Einbindung der Chrome DevTools zur Verfügung.Die Ausführung der grafischen Benutzeroberfläche erfolgt über das Electron-Fenster durch Aufruf deren loadFile()-Methode. Dabei erhält loadFile() als Parameter eine index.html-Datei mit Zugriff auf die Svelte/SvelteKit-Sourcen übergeben. Zu den wichtigsten npm-Paketen in der package.json-Datei gehören electron für die Ausführung der Electron-App, electron-builder für Build, Packaging und Publishing der App und electron-rebuild für die Integration der passenden Node.js-Module. Um Updates der App automatisch zu verteilen, gibt es verschiedene Lösungen. Dazu zählen die npm-Pakete: update-electron-app und electron-updater oder das in Electron integrierte autoUpdater-Modul. Zum Schluss muss die build-Section der package.json-Datei noch um die Spezifikationen der zu unterstützten Desktop-Umgebungen erweitert werden.

Tipps zur Einrichtung von NativeScript unter Android

Die Dokumentation zum Environment Setup von NativeScript enthält erste Hilfestellungen – die nachfolgenden Anleitungen bieten zusätzliche Unterstützung für Einrichtung und Entwicklung unter Android. Im Preferences-Window von Android Studio findet man unter Appearance & Behavior > System Settings beim Eintrag Android SDK die beiden Register SDK Platforms und SDK Tools.

Web-Apps, PWAs und Hybrid-Apps von Framework7 mit Svelte erweitern

Framework7 zielt schwerpunktmäßig auf die Entwicklung von Web-Apps mittels HTML/JavaScript und CSS ab mit einer Unterstützung von PWAs und Hybrid-(Mobile-)Apps. Für die Ausführung von DOM-Manipulationen besitzt Framework7 eine eigene DOM7-Library mit einer an jQuery-angelehnten Syntax. Die Programmierung mit Framework7 erfolgt mittels eines reichhaltigen Vorrats an Komponenten, einem eigenen Routing/Navigation-System und einer Built-in-State-Management-Library. Zudem unterstützt Framework7 das Styling mittels CSS-Variablen und speziellen Erweiterungen. Für mobile Endgeräte bietet das Framework zusätzliche Touch Utilities für eine bessere Interaktivität an. Ein Plugins-API ermöglicht es, Framework7 um eigene Anforderungen zu erweitern. Für die Optimierung der App-Performance stehen Lazy Modules zur Verfügung. Mittels gulp-Buildsystem kann eine individuelle Anpassung der Framework7-Custom-Library vorgenommen werden.Im Zentrum von Framework7 steht das Core-System und ein Call-Level-Interface (CLI). Zum Core-System zählen alle zuvor beschriebenen Bestandteile. Das Framework7-CLI bietet dem Entwickler eine leistungsfähige Schnittstelle, um verschiedene Aufgaben innerhalb eines Projekts mithilfe von Befehlen durchzuführen. Neben einer Schnittstelle zu Svelte besitzt Framework7 auch eine zu Vue.js und React. Diese Schnittstelle, Framework7 Svelte genannt, erschließt die Komponentenorientierung von Svelte. Damit erhält ein Entwickler innerhalb eines Framework7 App-Projekts Zugriff auf Svelte-Komponenten über die damit verbundene, intuitive Syntax (Bild 2). Die Realisierung der Schnittstelle zu Svelte erfolgt mittels eines Svelte-Plugins.
Framework7unterstützt die Einbindung von Svelte-Komponenten in der üblichen Svelte-Syntax(Bild 2) © Autor
Die Mächtigkeit dieser Schnittstelle demonstriert eine App mit dem langen Namen Framework7 Svelte Kitchen Sink. Dazu benötigt man eine Installation von Node.js und dem gulp-Buildsystem. Nach dem Herunterladen von Framework7 als ZIP-Archiv aus dessen GitHub-Repository und dessen Entpacken richtet der Befehl npm install die benötigten Abhängigkeiten ein. Anschließend startet npm run svelte die Framework7 Svelte Kitchen Sink-App, die man im Browser über die URL http://localhost:3000 erreicht. Auf diesem Port läuft ein Svelte-Entwicklungsserver, der den im Verzeichnis src/svelte/components enthaltenen Svelte-Quellcode der Framework7 Svelte Kitchen Sink-App ausführt.

Tipps zur Einrichtung von NativeScript unter macOS

Die Dokumentation zum Environment Setup von NativeScript enthält erste Hilfestellungen – die nachfolgenden Anleitungen bieten zusätzliche Unterstützung bei der Einrichtung von NativeScript unter macOS. Die Erläuterungen zur Installation von NativeScript unter macOS bedeuten wie unter Android zwar etwas Zusatzaufwand, da der Hersteller die entsprechenden Schritte nicht durch einen Automatismus erledigt. Für Xcode, die zu gehörigen Tools CocoaPods und Xcodeproj erfolgt deren Installation wie dokumentiert recht einfach.

Web- & Mobile-Apps mit Framework7 und Svelte produktiver entwickeln

Um selbständig mit der Framework7-Svelte-Schnittstelle zu programmieren, nimmt man eine Installation der Framework7-Library und des Framework7-CLI vor. Anschließend startet der Befehl npx framework7-cli create –ui die CreateApp von Framework7; diese entspricht einer intuitiven Oberfläche für den CLI-Befehl create. Über deren GUI legt der Entwickler bestimmte Vorgaben für die neu zu erzeugende Framework7-App fest. Dazu zählen der Ablageordner, das Icon, den Namen und den Typ der App. Wobei als Typ neben einer einfachen Web-App auch eine PWA-, Cordova/PhoneGap- und Capacitor-App zur Verfügung steht.Für die Einbindung von Svelte wählt man Framework7 with Svelte aus. Auch ein Starter-Template, Bundler, CSS-Preprozessor und Theming bietet die Create App zur Auswahl für die Erzeugung eines Entwicklungsprojekts an. Ein Klick auf die CREATE APP-Schaltfläche von Create App nimmt über das Framework7-CLI die Einrichtung des Projektordners vor. Parallel erscheinen in einem Informationsfenster Meldungen zur Abarbeitung der einzelnen Arbeitsschritte. Dabei erzeugt die Create App abhängig vom ausgewählten App-Typ alle erforderlichen Konfigurationsdateien und installiert die erforderlichen npm-Packages.Zum Schluss gibt die Web-App des create-Befehls im Informationsfenster eine Anleitung aus, welche weiteren Schritte der Entwickler für das Projekt erledigen soll und wo er weitere Hilfestellung erhält. In der Regel richtet npm install im Projektordner weitere Packages ein. Der generierte Quellcode der Framework7-Svelte-App befindet sich wie üblich im src-Ordner. Das Unterverzeichnis assets-src enthält die Icons und Splash-Screen für die PWA. Der CLI-Befehl framework7 assets --ui hilft diese mit den eigenen Ressourcen zu ersetzen. Für die Unterscheidung verschiedener Entwicklungsstufen kommt das npm-Paket cross-env zum Einsatz. Mit cross-env setzt man für Node verschiedene Umgebungsvariablen wie NODE_ENV=development oder NODE_ENV=production.Für die Entwicklung von PWAs greift Framework7 auf das npm-Paket workbox-cli zurück. Dabei handelt es sich um Libraries und Tooling für die Implementierung von Service-Workers. Den Entwicklungsserver startet der Befehl npm run start; anschließend steht die PWA über die von Svelte bekannte URL http://localhost:5173/ bereit. Die PWA erreicht man nach vollständigem Production-Build durch Auswahl der index.html-Datei im www-Ordner über das Kontextmenü des in VS Code integrierten Live Server. Alternativ empfiehlt sich der Einsatz des npm-Pakets http-server. Um die App schneller in eine Produktionsumgebung zu überführen, steht innerhalb des Projektordners das npm-Paket cpy-cli zur Verfügung, das parallel arbeitet und auf Streams basiert.

Virtuelle Mobilgeräte mit Android Studio einrichten

Das Testen von NativeScript-Apps benötigt ein virtuelles Mobilgerät, das unter dem jeweiligen Desktop-Betriebssystem (macOS, Linux, Windows) läuft. Für die Definition eines virtuellen Mobilgerät über Android Studio muss der IDE das gewünschte Betriebssystem zum Beispiel Android 8.1 (Oreo) zugänglich sein. Dieses installiert der SDK Manager durch dessen Auswahl und Klick auf die OK-Schaltfläche. Anschließend richtet man den Emulator für das Mobilgerät über den Device Manager von Android Studio durch Klick auf die Schaltfläche Create device ein. Dazu wählt man die gewünschte Hardware aus und legt über den Einrichtungs-Assistenten/Wizzard mittels Next-Schaltfläche die weiteren Spezifikationen fest.

Neutralinojs – eine leichtgewichtige Alternative für Svelte-Desktop-Apps

Im Unterschied zu den anderen Cross-Plattform-Tools stellt Neutralinojs ein leichtgewichtiges Framework mit geringerem Ressourcenbedarf dar. Dieser Sachverhalt begründet sich in der Realisierung in C++ und im Einsatz der dem jeweiligen Betriebssystem zugrundeliegenden Webbrowser-Schnittstelle – das heißt Neutralinojs basiert nicht vollständig auf den schwergewichtigen Chromium-Ressourcen. So kommt aktuell unter Linux gtk-webkit2, unter macOS WebKit und unter Windows seit Version 2 von Neutralinojs EdgeChromium zum Einsatz. Da Microsoft inzwischen auch Chromium verwendet, hat der Hersteller von Neutralinojs den integrierten Renderer von EdgeHTML (MSHTML) auf diesen neuen Windows-Renderer umgestellt. Mobile Betriebssysteme wie Android oder iOS unterstützt Neutralinojs derzeit noch nicht native.Die Programmierung der zu realisierenden Anforderungen einer App erfolgt mittels JavaScript/HTML und CSS. Zudem verfügt das Cross-Plattform-Tool über ein eigenes JavaScript-API neutralino.js; für native Operationen kommuniziert dieses API mit dem Betriebssystem über C++. Damit erhält der Entwickler direkten Zugriff auf die Ressourcen und Features des Betriebssystems. Eine in diesem JavaScript-API realisierte Funktion hilft bei der Implementierung automatischer App-Updates. Für Test und Debugging umfasst das JavaScript-API eine Log-Funktion (Bild 3). Soll auf einem Backend eigener Code zur Ausführung kommen, so erfolgt dies mittels des in neutralino.js enthaltenen C++-basierten Extensions-API. Dieser Ansatz zielt darauf ab, jede für das Backend verfügbare Programmiersprache zu unterstützen.
Neutralinojszeichnet Informationen und Fehlermeldungen in einer Log-Datei neutralinojs.log auf(Bild 3) © Autor
Die Auslieferung der Software erfolgt über ein npm-Paket: @neutralinojs/neu – so dass man vorher lediglich eine Installation von Node.js (darin ist npm enthalten) benötigt. Bei @neutralinojs/neu handelt es sich um die Kommandoschnittstelle (Call-Level-Interface/CLI) von Neutralinojs. Die interne Architektur einer mit Neutralinojs entwickelten App besteht aus zwei Hauptkomponenten: einem Neutralino-Client und einem -Server. Der Neutralino-Server, auch Neutralino-Runtime genannt, verarbeitet alle vom Client kommenden Requests, welche die App über neutralino.js (dem Client-SDK) absetzt. Zusätzlich zu diesem Background-Prozess gibt es noch einen zweiten, der für die Benutzeroberfläche zuständig ist. Als weitere interne Architekturkomponenten gibt es Datenstrukturen für die Konfiguration der App oder deren Debugging.Die sich dem Endbenutzer präsentierende Oberfläche der Neutralino-App hängt von dem seitens der App aktivierten Modus ab. Neutralinojs kennt vier verschiedene Modi:
  • window: dieser standardmäßig eingestellte Modus führt die App in einem nativen Fenster des Betriebssystems aus; er eignet sich am besten für den Desktop
  • browser: dieser Modus bringt die App in dem seitens des Endbenutzers bevorzugten Webbrowser zur Ausführung – dabei überwindet Neutralino (aufgrund der app-seitig erlangten Berechtigungen), die im Webbrowser normalerweise vorliegenden Beschränkungen für native Operationen des Betriebssystems
  • cloud: stellt den Endbenutzern die App über eine Cloud-Umgebung zur Verfügung; dabei läuft der Neutralino-Server als eigenständiger Prozess auf dem Backend
  • chrome: startet die App anhand der Chrome-Entwicklungsressourcen mithilfe von Google Chrome, Chromium oder Microsoft Edge; die App reicht die übergebenen seitens Chrome bekannten Aufrufparameter weiter.
Eine Neutralinojs-App richtet der CLI-Befehl neu create <projektordner> ein: Zu Beginn legt der create-Befehl einen Projektordner an, lädt das im GitHub-Repository von Neutralinojs enthaltene neutralinojs-minimal-Template im ZIP-Format herunter, entpackt das ZIP-Archiv und besorgt sich mit der analogen Vorgehensweise wie beim Starter-Template für die unterstützten Desktop-Betriebssysteme (macOS, Linux, Windows) die passenden Laufzeit-Binaries. Befindet sich das Terminalfenster im Projektordner, so startet der CLI-Befehl neu run die zum aktuellen Betriebssystem passende Binary und führt die Neutralinojs-App aus.

Virtuelle Mobilgeräte mit Xcode-Simulator einrichten

Das Testen einer NativeScript-App benötigt ein virtuelles Mobilgerät, das unter dem jeweiligen Desktop-Betriebssystem (macOS, Linux, Windows) läuft. Unter macOS startet man virtuelle Mobilgeräte zum Testen unter iOS über die Apple-Software Simulator, die Bestandteil der Xcode-IDE ist. In der aktuellen Xcode-Edition findet man die verschiedenen iOS-Simulatoren unter Xcode &gt; Settings… bei der Registerkarte Platforms. Einen bestimmten iOS-Simulator zum Beispiel für die Version 15.2 lädt ein Klick auf das links untenstehende +-Icon-Symbol, Auswahl der Version 15.2 und Download &amp; Install herunter.
Im Projektordner befindet sich die Datei README.md; sie verweist auf das verwendete Template neutralinojs-minimal, dass sich für die Einbindung eines Frontend-Frameworks wie Svelte eignet. Neutralinojs basiert nicht auf npm-Packages, deshalb existiert auch keine package.json-Datei, so dass die Installation weiterer npm-Packages entfällt. Allerdings besteht die Möglichkeit, das CLI von Neutralinojs mit npm-Packages über die Plugin-Architektur des CLIs um eigne Kommandos zu erweitern. Für die Konfiguration der App gibt es im Wurzelverzeichnis des Projektordners eine neutralino.config.json-Datei – sie stellt alle zur Ausführung oder das Testen der App benötigte Informationen bereit. Zum Beispiel ein für die App zu verwendendes Programm-Icon, die im Hauptfenster der App anzuzeigende Titelzeile oder aktiviert das Logging in einer externen Datei.Die Laufzeitumgebungen für die verschiedenen Desktop-Betriebssysteme und für die WebView befinden sich im bin-Unterverzeichnis des Projektordners – dabei handelt es sich um die bereits erwähnten Binaries (Bild 4). Im Bedarfsfall aktualisiert der CLI-Befehl neu update diese Binärdateien für die Betriebssysteme und Prozessoren sowie das dazu passende JavaScript-API neutralino.js. Alle aus Sicht der Programmierung mit Neutralinojs zentralen Dateien und Ordner befinden sich im Verzeichnis resources:
Neutralinojsstellt Laufzeitumgebungen für verschiedene Betriebssysteme und deren Prozessoren bereit – nicht standardmäßig unterstützte Hardware erfordert einen Compile der Neutralinojs-Quellen für die jeweilige Zielumgebung(Bild 4) © Autor
  • index.html: diese Datei enthält den HTML-Startercode der Neutralinojs-App
  • styles.css: entspricht den Layoutvorgaben für die Neutralinojs-App
  • js: dieser Ordner nimmt den JavaScript-Quellcode der App in der Datei main.js auf. Zusätzlich umfasst der js-Ordner noch das Client-SDK in der Datei neutralino.js.
  • icons: Ordner mit den seitens der App definierten Icons
  • .gitignore: diese verdeckte Datei beschreibt die seitens des Git-Systems nicht zu berücksichtigenden Dateien.
Aus DevOp-Sicht empfiehlt es sich, die Quelldateien der Svelte-Neutralinos-App in einen separaten Ordner abzulegen oder über ein spezielles Release-Management im Versionsmanagement abzuwickeln. Diese Vorgehensweise sichert die jederzeitige Reproduzierbarkeit aller vorliegenden Produkte: der ursprünglichen Svelte-Web-App und der Neutralinojs-Svelte-App. Beim zweiten Produkt handelt es sich um eine Einbettung der in Svelte programmierten App (Vanilla-JavaScript-Code) in einen Neutralinojs-Wrapper. Die Svelte-App stellt quasi ihre Oberfläche und Funktionalität zur Verfügung, die der Neutralinojs-Wrapper über seine verschiedenen Laufzeitumgebungen ausführt.Diese Einbettung kopiert die komplette Verzeichnisstruktur mit allen darin enthaltenen Bestandteilen der beiden Quellen – Svelte-App und Neutralinojs-Wrapper – in einen gemeinsamen Projektordner. Da beide Quellen Svelte- und Neutralinojs-App eine eigenständige .gitignore-Datei besitzen, müssen diese vor der Einbettung in einer gemeinsamen .gitignore-Datei zusammengefasst werden. Dazu übernimmt ein Copy & Paste die Definitionen der einen in die andere .gitignore-Datei. Da keine weiteren Konflikte in den beiden Quellen existieren, erfolgt zum Schluss deren Einbettung in einen gemeinsamen Projektordner.

CSS-Frameworks unterstützen Responsive Design

CSS-Frameworks wie Bootstrap oder TailwindCSS besitzen Gestaltungselemente für Responsive Webdesign. So kennen Bootstrap und TailwindCSS verschiedene Breakpoints – bei Bootstrap auch Responsive-Tiers genannt – für verschiedene Bildschirmklassen. Für beide CSS-Frameworks steht der flexible und leistungsstarke Mechanismus des CSS3-Flex-Layout zur Verfügung. Zudem besitzen beide eine Reihe vordefinierte Media-Queries für Layouting, Grid-System (Bootstrap), Grid-Utilities (TailwindCSS), Komponenten (Bootstrap) und spezielle Utility-Klassen.
Das neu aufzubauende Projekt widmet sich vollständig der Neutralinojs-Svelte-App, also der Ausführung einer Svelte-Web-App in einem Neutralinojs-Wrapper. Eine Neutralinojs-App startet das Rendering seiner HTML/JavaScript-Sourcen mit der über documentRoot erreichbaren statischen Ressourcen. Die Definition der documentRoot erfolgt in der Neutralinojs-Konfigurationsdatei (neutralino.config.json); im Falle der Svelte-App lautet diese "documentRoot": "/dist/". Der nachfolgende "url": "/"-Eintrag bewirkt, dass der Neutralinojs-Wrapper die index.html-Datei von "/dist/" lädt. Damit der Neutralinojs-Wrapper auf die Svelte-Web-App Zugriff erhält und diese ausführt, ersetzt man die im resource-Ordner stehende index.html-Datei mit der index.html-Datei der Svelte-Web-App und erweitert deren <body>-Tag:
&lt;body&gt;
    &lt;div id="app"&gt;&lt;/div&gt;
    &lt;!-- Den Neutralinojs als Wrapper ausfuehren --&gt;
    &lt;script src="js/neutralino.js"&gt;&lt;/script&gt;
    &lt;script defer src="js/neuinit.js"&gt;&lt;/script&gt;
    &lt;script type="module" src="/src/main.js"&gt;&lt;/script&gt;
&lt;/body&gt; 
Der nächste Schritt richtet das in der package.json-Datei der Svelte-Web-App deklarierte Package-Management auf die beiden Komponenten aus. Das gemeinsame Projekt besitzt einen eigenen separaten Übersetzungs- beziehungsweise Build-Prozess für die jeweils andere Komponente. Somit existiert ein Übersetzungsvorgang für die Svelte-App und einer für den Neutralinojs-Wrapper. Zudem ermöglicht die Einbettung der Svelte-Web-App in den Neutralinojs-Wrapper die Ausführung der beiden in der jeweils anderen Laufzeitumgebung:
"dev:svelte": "vite",
"dev:neu": "neu run --frontend-lib-dev",
"build:svelte": "copyfiles -f ./resources/index.html ./; vite build",
"build:neu": "neu build", 
Beispielsweise startet npm run dev:svelte einen Entwicklungsserver zum Testen der Neutralinojs-Svelte-App, die das Vite-Tooling bereitstellt und in einem Webbrowser ausführt. Als TCP-Port zeigt das Vite-Tooling die Adresse localhost:5173 an. Damit der Neutralinojs-Wrapper auf diesen von Vite bereitgestellten Entwicklungsserver zugreift, muss in der Konfigurationsdatei von Neutralinojs (neutralino.config.json) im cli-Eintrag ein frontendLibrary-Eintrag mit einem patchFile und einer devUrl deklariert werden. Der patchFile-Eintrag verweist auf die index.html-Datei, welche den Background-Prozess Neutralino.js mit dem User-Interface und die Funktionalität der Svelte-Web-App ausführt: "patchFile": "/index.html". Der devUrl-Eintrag erhält die Adresse "devUrl": http://localhost:5173 übergeben.

Webbrowser verfügen über Responsive Design-Mode

Alle gängigen Browser bieten dem Entwickler einen Responsive Design-Mode zum Testen an. Bei Installation und Aktivierung der Chrome DevTools im Browser öffnet ein Klick auf das Icon-Symbol Smartphone/Tablet mit dem Hoverhelp-Text Toggle device toolbar (Bildschirmgrößen testen oder Geräteemulation umschalten) dessen Responsive Design-Mode. Safari besitzt ebenfalls einen Responsive Design-Mode, zuvor muss die Checkbox Menü „Entwickler' in der Menüleiste anzeigen bei den Einstellungen ausgewählt werden. Nach Auswahl von In Modus Responsive Design wechseln in der Menüzeile Entwickler öffnet sich dieser.
Der obige patchFile-Eintrag aktiviert das Hot-Module-Reload-Feature, welches in Neutralinojs über ein Patching der index.html-Datei erfolgt. Damit löst Vite nach dem Speichern über den Entwicklungsserver einen Compile-Vorgang aus und zeigt alle vorgenommenen Änderungen im Quellcode der Svelte-Web-App sofort im Webbrowser an. Damit diese Änderungen auch im Neutralinojs-Wrapper erscheinen, erhält der Aufruf der Laufzeitumgebung von Neutralinojs über seinen neu run-Befehl den Parameter --frontend-lib-dev übergeben (Bild 5).
In einem Neutralino-Svelte-Projektsteht HMR (Hot-Module-Reloading) im Webbrowser und auch im Neutralino-Wrapper über das Vite-Tooling für die Svelte-Ressourcen zur Verfügung(Bild 5) © Autor
Damit der Neutralinojs-Wrapper die aktuelle index.html-Datei verwendet, müssen eventuelle Änderungen dem Vite-Tooling zugänglich sein. Dabei hilft das npm-Package copyfiles – der Befehl npm install -D copyfiles installiert es als devDependency in die Svelte-Web-App. Dabei stellt der Befehl copyfiles -f ./resources/index.html ./; die aktuelle index.html-Datei des Neutralinojs-Wrapper dem Vite-Tooling für den Build-Prozess bereit. Um den Compile- und Build-Vorgang für eine größere Neutralinojs-Svelte-App zu beschleunigen, empfiehlt sich der Einsatz des npm-Packages npm-run-all. Installiert man npm-run-all in die devDependencies, so stehen zwei Befehle run-p und run-s zur Verfügung. Während run-s übergebene npm-Skripts sequentiell einen nach dem anderen ausführt, beschleunigt run-p diese durch eine parallele Ausführung – entsprechend erweitert man den Script-Bereich der package.json:
"start": "run-p dev:svelte dev:neu",
"build": "run-s build:svelte build:neu", 
Das ursprünglich in 2014 bei Telerik konzipierte NativeScript-Framework entwickelt seit Mitte 2020 das Softwarehaus nStudio weiter. Ende 2020 erklärte die OpenJS Foundation die OpenSource-Software zum Incubating-Projekt, was dem Cross-Plattform-Tool zusätzliche Aufmerksamkeit und Ressourcen brachte. Das inzwischen in der Version 8 vorliegende NativeScript zielt auf die Entwicklung von Mobile-Apps für iOS und Android mit JavaScript/TypeScript, HTML und CSS ab.Dazu stellt NativeScript eine Laufzeitumgebung zur Verfügung, die sich direkt den nativen Steuerelementen und anderen Klassen bedient. Die Laufzeitumgebung entspricht softwaretechnisch einem Proxy oder einer Bridge, die Anforderungen aus der JavaScript- an die Native-Welt weiterreicht und umgekehrt – von der Native- zurück an die JavaScript-Welt. Derzeit beschränkt sich die Cross-Plattform-Entwicklung mit NativeScript rein auf die mobile Welt – alle Anstrengungen zum Beispiel die Universal Windows Platform (UWP) zu unterstützen, hat auch der jetzige Entwickler nStudio zurückgefahren.Der Einsatz von NativeScript benötigt Node.js und das npm-Package nativescript dessen globale Installation auch das CLI von NativeScript (ns früher mit tns bezeichnet) verfügbar macht. Neben JavaScript und TypeScript erlaubt NativeScript die Einbindung der weit verbreiteten Frameworks (Angular, React, Svelte, Vue.js). Zusätzlich erfordert die Programmierung mit NativeScript die Installation einer vollständigen Entwicklungsumgebung von Android Studio mit JDK und Xcode mit deren SDKs.Eine Unterstützung beider mobiler Betriebssysteme macht die Anschaffung einer macOS-Hardware von Apple notwendig. nStudio stellt in Google Play (dem App Store von Google) beziehungsweise im App Store von Apple eine eigene App NativeScript Preview zur Verfügung. Ferner erschließt NativeScript Preview die Entwicklung über die StackBlitz-Web-IDE mit verschiedenen Starter-Projekten. Für NativeScript Preview verwendet die Benutzergemeinde von NativeScript auch häufig die Bezeichnung NativeScript Playground, da dieser durch NativeScript Preview ersetzt wurde.Nach der Installation von NativeScript Preview ermöglicht das Scannen eines QR-Codes den Test einer NativeScript-App auf dem mobilen Endgerät. Zusätzlich wird das Testen der mobilen App mittels Emulation beziehungsweise Simulation über die jeweilige native Entwicklungsplattform (Android Studio, Xcode) unterstützt. Dazu startet der Entwickler am besten vor dem Testen das gewünschte virtuelle mobile Endgerät über die jeweilige IDE (Android Studio, Xcode).

NativeScript besitzt ein mächtiges CLI für das Arbeiten mit Android und iOS

Zu den wichtigsten Terminalbefehlen des CLI (ns) für das Arbeiten mit NativeScript zählen:
  • ns: gibt eine Anleitung für den schnellen Einstieg in die NativeScript aus
  • ns doctor: überprüft alle Abhängigkeiten der NativeScript-Entwicklungsumgebung und zeigt eine Zusammenfassung auf dem Bildschirm an (Bild 6) – ein hilfreicher Befehl, um mögliche Inkonsistenzen aufzuspüren. Um gezielt eine einzelne Zielplattform anzusprechen, kennt ns doctor die beiden Aufrufoptionen ns doctor android und ns doctor ios
Die vollständige und korrekte Einrichtungeiner NativeScript-Entwicklungsumgebung prüft der Terminalbefehl ns doctor(Bild 6) © Autor
  • ns create: erzeugt nach der Eingabe eines Namens für die App und der Festlegung angebotener interaktiver Auswahloptionen Appname, Projekttyp (Angular, React, Vue.js, Svelte, Plain TypeScript, Plain JavaScript) und eines Templates einen Projektordner mit einer NativeScript-App. In Verbindung mit dem Parameter --template <template-package-name> oder eines Flags (--ng, --react, --vue, --svelte, --ts, --js) zieht der create-Befehl des CLIs eine App-Template aus dem GitHub-Repository für die Anlage des Projekts an
  • ns preview: generiert einen QR-Code für den direkten Test einer App auf dem mobilen Endgerät mittels NativeScript Preview
  • ns platform list: erstellt eine Liste aller Zielplattformen des Projekts
  • ns debug <platform>: startet den Debugger für Android oder iOS, mit zusätzlichen Parametern lässt sich der jeweilige Debugger gezielt steuern
  • ns test <platform>: arbeitet die Unit-Tests des Projekts auf einem verbundenen physikalischen oder virtuellen Gerät ab
  • ns clean: erzeugt einen sauberen Auf- oder Ansetzpunkt für eine erneute Installation aller Plattformspezifika
  • ns update: ermöglicht eine Re-Initialisierung oder Re-Konstruktion von Plattformspezifika auf eine bestimmte Version des NativeScript-Frameworks
  • ns platform: unterstützt zusätzlich zum üblichen npm install-Befehl das gezielte Management von Plattformspezifika mittels der Sub-Kommandos add oder remove
  • ns build <platform>: stößt einen Build für die angegebene Plattform an und erstellt ein App- oder ein Emulator-Package
  • ns deploy <platform>: nimmt eine Verteilung des Projekts auf ein verbundenes physikalisches oder virtuelles Gerät vor
  • ns device: gibt eine Liste der aktuell verfügbaren, virtuellen Geräte für die beiden Plattformen Android und iOS aus
  • ns run <platform>: führt ein Projekt auf einem verbundenen Gerät oder über einen Emulator (Android) beziehungsweise Simulator (iOS) aus – dabei nimmt <platform> den Wert android oder ios an. Zusätzlich gibt es für jede Plattform eine Reihe weiter Flags oder Aufrufoptionen
NativeScript unterstützt die Programmierung mobiler Apps mittels TypeScript, JavaScript und den Frameworks Angular, React, Svelte und Vue.js. Kommt in der Entwicklung NativeScript zusammen mit Svelte zum Einsatz, so bezeichnet man diese Softwaretechnik als Svelte Native. Die Svelte-Community forciert die Entwicklung von Svelte Native und stellt auch eine eigene Homepage bereit, welche die beiden beteiligten Technologien Svelte und NativeScript zugänglich macht.Anhand eines Quick Starts bietet diese Website eine Schnellanleitung für die Installation des NativeScript-Frameworks, der zugehörigen Playground-App, der Erzeugung einer Svelte Native-App und deren Ausführung über den Playground. Grundsätzlich nimmt der dabei verwendete create-Befehl auch die Installation aller über die package.json spezifizierten npm-Packages vor.Die auf der Svelte Native-Homepage stehende schon etwas ältere Anleitung zum Quick Start ist zwar immer noch aktuell, lediglich der Screenshot zur Überprüfung einer korrekten NativeScript-Installation mittels des tns-Befehls ist veraltet. Alternativ zur Quick Start-Anleitung richtet der Terminalbefehl ns create <meine-app> --template @nativescript/template-blank-svelte eine Svelte Native-App im Projektordner <meine-app> ein. Alternative Templates findet man im NativeScript-Marketplace im Bereich Plugins über eine Suche nach svelte.Dort enthält das Unterverzeichnis app die komplette Svelte Native-App, bestehend aus einer Starter-Komponente App.svelte, welche aus dem Ordner app/components den Svelte-Quellcode mit der Home.svelte-Komponente anzieht. Den eigentlichen Start der Svelte-Native-App führt die app.ts-Datei durch – dieser TypeScript-Quellcode übergibt die Kontrolle an die App.svelte-Komponente. Für das Layouting kommt die dortige app.(s)css-Datei zum Einsatz. Wobei für die beiden mobilen Betriebssysteme Android oder iOS im Bedarfsfall zwei verschiedene Dateien app.android.(s)css und app.ios.(s)ccs möglich sind. Dieser Code-Aufbau verdeutlicht, die Wiederverwendung von Svelte-Komponenten über NativeScript für Mobile-Apps.Neben dem üblichen node_modules-Ordner mit den vorinstallierten und damit aktuellen npm-Packages befinden sich noch die beiden Verzeichnisse hooks und App_Resources im Projektordner. Das Verzeichnis hooks realisiert den seit NativeScript 6.0 verfügbaren Hooks-Mechanismus des CLI, um während des Builds spezielle Aktionen auszuführen. Der Unterordner App_Resources teilt sich entsprechend der Zielumgebungen einer NativeScript-App in die beiden Verzeichnisse Android und iOS auf. In diesen Verzeichnissen befinden sich jeweils die Meta-Informationen für das mobile Betriebssystem, um für die NativeScript-App den entsprechenden Build vorzunehmen.

Svelte Native-App mit CLI und Tools für diemobile Welt testen

Der Befehl ns run android oder ns run ios startet einen Build für die jeweilige mobile Plattform und führt unmittelbar darauf auf einem virtuellen mobilen Endgerät den Test durch. Anfangs nimmt der Build-Prozess relativ viel Zeit in Anspruch, da beim ersten Aufruf noch das Unterverzeichnis platforms für das jeweilige mobile Betriebssystem erzeugt und die Build-Ergebnisse dort abzulegen sind. Die Build-Ergebnisse für Android legt der ns run android-Befehl in das Unterverzeichnis android und der ns run ios-Befehl in das Unterverzeichnis ios im platforms-Ordner ab.Für Tests der mobilen App unter macOS startet der Terminalbefehl ns run ios automatisch das zuletzt im Simulator von Xcode verwendete iOS-Gerät. Sollte man ein anderes wünschen, so muss dieses vorher dem Aufruf von ns run ios aktiviert werden. Dazu startet Xcode > Open Developer Tool > Simulator die Software und man wählt über File > Open Simulator aus der angezeigten Liste das gewünschte mobile Endgerät aus. Sollte dieses nicht in der Liste erscheinen oder die falschen Eigenschaften besitzen, so muss über die Simulator-Software (File > New Simulator…) ein neues mobiles Endgerät entsprechend angelegt werden.Im Unterschied zum ns run ios-Befehl muss für die Android-Plattform vorher über Android Studio immer ein bereits eingerichtetes Virtual Device gestartet sein. Dazu klickt man in Android Studio im Begrüßungsfenster Welcome to Android Studio in der rechten oberen Toolbar auf das Drei-Punkte-Icon und wählt dort den Eintrag Virtual Device Manager aus (Bild 7). Das Dialogfenster Device Manager mit einer Liste aller aktuell definierten virtuellen mobilen Endgeräte öffnet sich. Nach Auswahl eines der dortigen Endgeräte und Klick in der Spalte Actions auf Launch this AVD in the emulator startet dieses mobile Endgerät. Erst nach dem Start eines virtuellen Endgeräts führt der Befehl ns run android einen erfolgreichen Build durch und stellt die App zum Testen bereit.
Für die Entwicklung mit NativeScriptempfiehlt sich der Einsatz von Android Studio, da Programmierer mithilfe der IDE bestimmte Aufgaben für Android wesentlich einfacher und schneller erledigen(Bild 7) © Autor

Responsive-Webdesign mit CSS3 und HTML5

Im Unterschied zu einer Web-App soll eine PWA nicht nur im Web und auf dem Desktop sondern auch auf dem ganzen Spektrum der mobilen Endgeräte zum Einsatz kommen. Um sowohl das Web, den Desktop als auch mobile Endgeräte zu unterstützen, basiert eine PWA auf einem Responsive-Webdesign. Abhängig vom Endgerät (Desktop, Tablet, Phone) zeigt eine PWA die spezifische Seite entsprechend an und reagiert passend auf die unterschiedlichen Eingabemethoden (Maus, Touchscreen). Zusätzlich kommen Techniken des Progressive Enhancements hinzu, wie die Trennung von Präsentation und Information, um die Web-App fortschreitend zu verbessern. Diese gewährleisten Barrierefreiheit und die besonderen Features einer PWA wie Offline-Fähigkeit.CSS3 und HTML5 bieten die erforderlichen Mittel, um den Inhalt einer Webseite an das Ausgabegerät anzupassen; sie beispielsweise zu verkleinern oder zu vergrößern. Gemäß den Vorgaben erfolgt diese Anpassung für die Darstellung auf jedem Bildschirm entsprechend seiner Größe. Dazu führte HTML5 beim <meta>-Tag das viewport-Element ein. Der viewport übergibt dem Browser Anleitungen wie die Größe und Skalierung einer Seite erfolgen soll, zum Beispiel:
&lt;meta name="viewport" content="width=device-width, 
initial-scale=1.0"&gt; 
So setzt die Anweisung width=device-width die Seitenbreite auf die Bildschirmbreite des Endgeräts und initial-scale=1.0 nimmt beim erstmaligen Laden der Seite keine Skalierung vor. Diese Vorgehensweise stellt sicher, dass ein Besucher der Webseite auf allen Endgeräten vertikal und nicht horizontal scrollt. Kommt es dennoch zu einem horizontalen Scrollen, so helfen weitere Vorkehrungen, um dennoch ein gutes Styling zu erreichen. Eine weitere Softwaretechnik für Responsive-Webdesign führte CSS3 mit der Media-Query (auch Eigenschaftsspezifisches Stylesheet genannt) ein. Dabei handelt es sich im Prinzip um eine Regel beginnend mit @media, die einen Block von CSS-Properties nur anzieht, wenn eine bestimmte Bedingung (Eigenschaft eines Geräts) erfüllt ist.Eine Media-Query definiert Regeln, die abhängig vom Gerätetyp (Print, Desktop, mobiles Endgerät, Speech) und dessen Eigenschaften (zum Beispiel Bildschirmgröße) bestimmte CSS-Regeln für das Styling anwendet. Deklariert eine @media-Regel verschiedene Geräteklassen für Layout/Styling, so deckt das zugehörige class-Attribut in HTML bereits eine große Bandbreite anzutreffender Geräte ab. Eine Klassenbildung erfolgt am besten über die Pixelgröße mittels dem max-width- und/oder min-width-Attribut: kleine, mittlere, große, extra-kleine und extra-große Bildschirme. Die zugewiesenen Werte zusammen mit den Geräteklassen nennt man Breakpoints.

Zusätzliche CSS3-Methoden für dynamisches Layout nutzen

Eine Media-Query besitzt die Fähigkeit, die Orientierung einer Webseite dynamisch (Portrait für vertikal oder Landscape für horizontal) einzustellen. Als weitere wichtige Features einer Media-Query mit HTML5 und CSS3 sind zu nennen:
  • Elemente der Webseite beim Anzeigen verhindern (display: none)
  • die Schriftgröße (font-size: 40px) einstellen
  • der Skalierung von Breite (min-width, max-width) und Höhe (height:auto) bei Bildern
  • besitzt ein Bild ein Hintergrundbild, so stellt background-size dessen Größe separat ein
  • das HTML <picture>-Element spezifiziert das zu verwendende Bild (srcset) und besitzt ein optionales media-Attribut.
Svelte unterstützt HTML5, CSS3 und JavaScript und erschließt damit verbundene Softwaretechniken für eine responsive Web-App. Gemäß dem Grundsatz Single-File-Component (SFC) (siehe Teil 1) besteht eine Svelte-Komponente immer aus einer .svelte-Datei, die sich aus HTML-Code sowie den optionalen Bestandteilen <script> für JavaScript und <style> für CSS zusammensetzt. Damit besitzen Styles in Svelte standardmäßig einen bestimmten Gültigkeitsbereich. Ein :global-Selector im <style>-Bereich definiert einzelne als global gültig – ein global-Attribut beim <style global>- Tag erklärt alle deklarierten Styles als global. In SvelteKit gilt der Grundsatz: Jede Webseite erbt ihr Styling vom Root-Layout, das sich in der Datei src/routes/+layout.svelte befindet – dort eingebundene CSS-Deklaration zum Beispiel aus einer global.css-Datei machen diese global gültig:
&lt;!-- src/routes/+layout.svelte --&gt;
&lt;script&gt;
…
import './global.css';
…
&lt;/script&gt; 
Neben Media-Queries hat das W3C für dynamisches Layouting die Flexbox und das Grid-Layout eingeführt. Die Flexbox beschreibt ein eindimensionales System: Sie ordnet Elemente im Layout entweder in Spalten oder Zeilen ein – deren Hauptachse in der Regel von links nach rechts, während die Nebenachse von oben nach unten verläuft.Im Unterschied zur Flexbox bietet das Grid-Layout zwei Dimensionen zur Platzierung von Objekten an: Statt nur auf einer Achse verfügt das Grid über ein Raster mit Zeilen und Spalten. Beide Flexbox und Grid stellen verschiedene CSS-Konstrukte bereit, um das Layout detailliert zu gestalten. Als Programmierer greift man auf diese CSS-Vorgaben über die verschiedenen Möglichkeiten im HTML-Quellcode zurück und definiert dabei ihren Inhalt. Seit längerem existieren verschiedene npm-Pakete für das Grid-Layouting mit JavaScript/TypeScript (Bild 8).
Das in TypeScript implementierte Grid.jsstellt eine Svelte-Komponente als Wrapper bereit(Bild 8) © Autor

Media-Queries in Svelte(Kit)-PWA über JavaScript/TypeScript ausführen

Obwohl Media-Queries mit CSS3 primär auf Responsive-Webdesign ausgerichtet sind, stehen diese auch direkt in JavaScript zur Verfügung. Dies klingt zwar seltsam, da Media-Queries einem Layout-Feature entsprechen und das damit verbundene Styling über CSS erfolgt. Bei CSS handelt es sich um eine deklarative Sprache im Unterschied zum imperativen JavaScript. Um mit JavaScript festzustellen, ob ein anzuzeigendes Dokument einen Media-Query-String (auch Medienmerkmal genannt) im Webbrowser erfüllt, setzt der Programmierer die Methode matchMedia() ein. Zugriff auf das Document-Objekt-Model (DOM) im Webbrowser erhält man in JavaScript über das window-Objekt. Beispielsweise prüft der Media-Query-String '(min-width: 800px)', ob das DOM im Webbrowser diese übergebene mediaQuery erfüllt:
const mediaQuery = window.matchMedia('(min-width: 800px)') 
Das Resultat mediaQuery entspricht einem MediaQueryList-Objekt, das Informationen darüber enthält, ob ein Dokument eine Media-Query erfüllt oder nicht. Diese Information liefert ein Zugriff auf das matches-Property von mediaQuery: Ergibt mediaQuery.matches den booleschen Wert true, dann erfüllt das Dokument die spezifizierte mediaQuery (im Beispiel '(min-width: 800px)'). Anders als bei der Media-Query in CSS3 reagiert im Falle von JavaScript das Styling/Layout im User-Interface der Web-App nicht. Um das Styling/Layout des User-Interface über JavaScript zu erledigen, steht im Interface der MediaQueryList die onchange-Eigenschaft als Callback-Funktion zur Verfügung.Über die Methode addEventListener() verbindet man den onchange-Event mit einer callback-Funktion, welche die Änderungen im User-Interface ausführt. Die Registrierung des Event-Listener erfolgt mittels: mediaQuery.addEventListener ('change', mediaQueryChange). Dabei entspricht mediaQueryChange der callback-Funktion, welche ausgeführt wird, sobald die über mediaQuery() deklarierte Media-Query erfüllt ist. Diese Vorgehensweise zu prüfen, ob ein Dokument einen Media-Query-String erfüllt, lässt sich in ein externes Modul als Funktion auslagern:
// Modul mit mediaQuery als Funktion
export function mediaQuery(minMaxWidth = 'min', measure = 1280, callBack) {
// Den Media-Query-String konstruieren
var mediaQueryList = window.matchMedia(`(${minMaxWidth}-width: ${measure}px)`);
// Die Callback/Handler-Funktion deklarieren
function mediaQueryChange(e) {
  if (e.matches) {
  callBack();
  }
};
// Den Event-Handler für die Callback-Funktion 
// registrieren
mediaQueryList.addEventListener('change', 
mediaQueryChange)
// Die Callback-Funktion initialisieren
mediaQueryChange(mediaQueryList)
}; 
Diese Funktion mediaQuery() besitzt drei Parameter minMaxWidth, measure und callback – mit den Beispielwerten min für den ersten und 1280 für den zweiten Parameter. Daraus erzeugt die Anweisung `(${minMaxWidth}-width: ${measure}px)` den MediaQuery-String anhand der beim Funktionsaufruf tatsächlich übergebenen Parameter. Die Funktion matchMedia() aus dem window-Interface liefert ein MediaQueryList-Objekt zurück. Darüber lässt sich bestimmten, ob das aktuell im Webbrowser angezeigte Dokument den Media-Query-String erfüllt. Die deklarierte Callback-Funktion mediaQueryChange wird als Event-Listener registriert und durch den erstmaligen Aufruf initialisiert. Innerhalb von JavaScript greift der Quellcode auf die mediaQuery()-Funktion wie folgt zu:
// Media-Query-String: max-width: 480px
// Das Ausgabegeraet besitzt eine Breite kleiner oder gleich 480px
mediaQuery('max', 480, function(){
…
});
// Media-Query-String: min-width: 1280px
// Das Ausgabegeraet besitzt eine Breite groeßer oder 
// gleich 1280px
mediaQuery('min', 1280, function(){
… 
}); 
Die zuvor realisierte JavaScript-Funktion mediaQuery lässt sich nur auf dem Client rendern (ausführen). Diese Beschränkung resultiert aus dem Gebrauch des window-Objekts, das nur auf dem Client im Webbrowser und nicht auf dem Server existiert. Jede in einer .svelte-Datei deklarierte Svelte-Komponente durchläuft einen Lifecycle und besitzt immer einen Zustand, der nach ihrer Instanziierung inhärent wird. Im Unterschied zu Svelte kennt das SvelteKit-Framework verschiedene Techniken für das Rendering (siehe Teil 4). Auch Betrieb oder Implementierung einer Svelte-App über ein Web-Framework wie Astro erfolgt mittels Server-Side-Rendering (SSR).

Client-Side-Rendering (CSR)

Um das benötigte Client-Side-Rendering (CSR) für eine Komponente in einer SvelteKit-App sicherzustellen, greift man auf den onMount-Handler zurück. Dieser onMount-Handler kommt nach dem ersten Rendern der Komponente im DOM zur Ausführung – was nur auf dem Client stattfinden kann. Dazu nimmt der <script>-Bereich der Svelte-Komponente den folgenden Quellcode auf (Bild 9):
Die Ausführung von DOM-Funktionenund das Arbeiten mit dem document- oder window-API in JavaScript erfolgt immer clientseitig im Webbrowser(Bild 9) © Autor
…
import {mediaQuery} from './utilities/mediaQuery.js'
import {onMount} from "svelte"
let mediaQueryExp1;
let mediaQueryExp2;
onMount(() =&gt; {
    // Media-Query-String: max-width: 480px
    mediaQueryExp1 = mediaQuery('max', 480, function() 
    {
    alert('Dies ist ein schmaler Bildschirm — 
    weniger als 480 Pixel breit.')
});
// Media-Query-String: min-width: 1280 px
mediaQueryExp2 = mediaQuery('min', 1280, function(){
    alert('Dies ist ein breiter Bildschirm — mehr als 1280 Pixel breit.');
    })
})
… 
Als Alternative für die Realisierung von Media-Query-Abfragen in JavaScript/TypeScript bietet sich der Einsatz eines Svelte-Stores an. Ein Readable-Store erlaubt es, die oben beschriebene Media-Query-Abfrage innerhalb der Svelte-App für die Komponenten bereitzustellen. Der nachfolgende Svelte-Store bildschirmKlasse unterteilt die Ausgabegeräte anhand der Media-Query-Strings mit den Breakpoints 576px, 992px und 1400px in drei verschiedene Bildschirmgrößen (Listing 1). Anschließend bietet es sich an, anhand der jeweils aktuell ermittelnden Bildschirmgröße, das User-Interface entsprechend zu behandeln. Dazu eignet sich ein {#if…} … {/if}-Block mit der Einbindung passender HTML-Tags:
Listing 1: Media-Query über Svelte-Store realisieren
import { readable } from "svelte/store';&lt;br/&gt;&lt;br/&gt;export const bildschirmKlasse = &lt;br/&gt;readable(undefined, set =&amp;gt; {&lt;br/&gt;  let stop = () =&amp;gt; {};&lt;br/&gt;&lt;br/&gt;  // Ausfuehrung des nachfolgenden Quellcodes nur &lt;br/&gt;  // im Webbrowser&lt;br/&gt;&lt;br/&gt;  if (typeof window != "undefined') {&lt;br/&gt;    let mediaQuerySM = window.matchMedia&lt;br/&gt;    ('(max-width: 576px)');&lt;br/&gt;    let mediaQueryLG = window.matchMedia('&lt;br/&gt;    (max-width: 992px)');&lt;br/&gt;    let mediaQueryXXL = window.matchMedia('&lt;br/&gt;    (max-width: 1400px)');&lt;br/&gt;&lt;br/&gt;    // Eine Funktion definieren, welche die &lt;br/&gt;    // Bildschirmklasse bestimmt&lt;br/&gt;    const setzeBildschirm = () =&amp;gt; {&lt;br/&gt;        if (mediaQuerySM.matches) return(set('sm'));&lt;br/&gt;        if (mediaQueryLG.matches) return (set('lg'));&lt;br/&gt;        if (mediaQueryXXL.matches) return &lt;br/&gt;        (set('xxl'));&lt;br/&gt;    }&lt;br/&gt;    // Diese Funktion einmalig ausfuehren&lt;br/&gt;    setzeBildschirm();&lt;br/&gt;    &lt;br/&gt;    // Fuer die MediaQueryList einen Event-Listener &lt;br/&gt;    // fuer "change' registrieren&lt;br/&gt;    mediaQuerySM.addEventListener("change', &lt;br/&gt;    setzeBildschirm);&lt;br/&gt;    mediaQueryLG.addEventListener("change', &lt;br/&gt;    setzeBildschirm);&lt;br/&gt;    mediaQueryXXL.addEventListener("change', &lt;br/&gt;    setzeBildschirm);&lt;br/&gt;&lt;br/&gt;    // Die stop-Funktion fuer den readble-Store &lt;br/&gt;    // definieren&lt;br/&gt;    stop = () =&amp;gt; {&lt;br/&gt;        mediaQuerySM.removeEventListener&lt;br/&gt;        ('change', setzeBildschirm);&lt;br/&gt;        mediaQueryLG.removeEventListener('change', &lt;br/&gt;        setzeBildschirm);&lt;br/&gt;        mediaQueryXXL.removeEventListener('change',&lt;br/&gt;        setzeBildschirm);&lt;br/&gt;    }&lt;br/&gt;  }&lt;br/&gt;  return stop;&lt;br/&gt;}); 
&lt;script lang="ts"&gt;
    …
    import { bildschirmKlasse } from 
    './utilities/store.js'
    …
&lt;/script&gt;
&lt;main&gt;
…
{#if ($bildschirmKlasse==='sm')}
&lt;p&gt;Bildschirm kleiner Größe liegt vor: 
{$bildschirmKlasse} !&lt;/p&gt;
…
{/if}
{#if ($bildschirmKlasse==='lg')}
&lt;p&gt;Bildschirm großer Größe liegt vor: 
{$bildschirmKlasse} !&lt;/p&gt;
…
{/if} 
{#if ($bildschirmKlasse==='xxl')}
&lt;p&gt;Bildschirm großer Größe liegt vor: 
{$bildschirmKlasse}!&lt;/p&gt;
…
{/if}
…
&lt;/main&gt; 
Eine Svelte-Komponente MediaQuery.svelte, die einen Media-Query-String entgegennimmt, diesen für das angezeigte HTML-Dokument überprüft und die boolesche Variable erfuellt zurückliefert, baut auf der vorher verwendeten Vorgehensweise mit den entsprechenden Funktionen auf (Listing 2). Der anschließende Import dieser Komponente in eine andere Svelte-Komponente ermöglicht es, bestimmte Media-Query-Strings für das aktuelle HTML-Dokument zu überprüfen und, abhängig davon, (mittels eines {#if} … {/if}-Blocks mit konditionalem Rendering) das Layout und Styling mit nachfolgenden HTML-Tags zu gestalten:
Listing 2: Media-Query als Svelte-Komponente
&amp;lt;script&amp;gt;&lt;br/&gt;// Svelte-Komponente MediaQuery.svelte&lt;br/&gt;    import { onMount } from 'svelte';&lt;br/&gt;    export let mediaQueryString;&lt;br/&gt;    &lt;br/&gt;    let mediaQueryList;&lt;br/&gt;    let mqlListener;&lt;br/&gt;    let wasMounted = false;&lt;br/&gt;    let erfuellt = false;&lt;br/&gt;  &lt;br/&gt;    // Media-Query pruefen und change-Event-Listner &lt;br/&gt;    // hinzufuegen&lt;br/&gt;    function addNewListener(mediaQueryString) {&lt;br/&gt;        mediaQueryList = &lt;br/&gt;        window.matchMedia(mediaQueryString);&lt;br/&gt;        mqlListener = (parm) =&amp;gt; (erfuellt = &lt;br/&gt;        parm.matches);&lt;br/&gt;        mediaQueryList.addEventListener('change', &lt;br/&gt;        mqlListener);&lt;br/&gt;        erfuellt = mediaQueryList.matches;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // change-Event-Listener entfernen, wenn er und &lt;br/&gt;    // mediaQueryList existiert&lt;br/&gt;    function removeActiveListener() {&lt;br/&gt;        if (mediaQueryList &amp;amp;&amp;amp; mqlListener) {&lt;br/&gt;            mediaQueryList.removeEventListener &lt;br/&gt;            ('change', mqlListener)&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // Wenn MediaQuery-Komponente im DOM &lt;br/&gt;    // hinzugefuegt wird&lt;br/&gt;&lt;br/&gt;    onMount(() =&amp;gt; {&lt;br/&gt;        wasMounted = true;&lt;br/&gt;        return () =&amp;gt; {&lt;br/&gt;            removeActiveListener();&lt;br/&gt;        };&lt;br/&gt;    });&lt;br/&gt;    &lt;br/&gt;    // Das reactive Statement immer ausfuehren, &lt;br/&gt;    // wenn if-Abfrage erfuellt!&lt;br/&gt;    $: {&lt;br/&gt;        if (wasMounted) {&lt;br/&gt;            removeActiveListener();&lt;br/&gt;            addNewListener(mediaQueryString);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&amp;lt;/script&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;slot {erfuellt} /&amp;gt; 
&lt;script&gt;
  // App.svelte-Komponente
  import MediaQuery from 
  "./utilities/MediaQuery.svelte";
&lt;/script&gt;
&lt;MediaQuery mediaQueryString="(min-width: 1281px)" let:erfuellt&gt;
{#if erfuellt}
&lt;h1&gt;Die ist ein Standard-Ausgabegerät&lt;/h1&gt;
{/if}
&lt;/MediaQuery&gt;
&lt;MediaQuery mediaQueryString="(min-width: 481px) and (max-width: 1280px)" let:erfuellt&gt;
{#if erfuellt}
&lt;h1&gt;Dieses Ausgabegerät ist ein Tablet&lt;/h1&gt;
{/if}
&lt;/MediaQuery&gt;
&lt;MediaQuery mediaQueryString="(max-width: 480px)" let:erfuellt&gt;
{#if erfuellt}
&lt;h1&gt;Dies ist ein mobiles Ausgabegerät&lt;/h1&gt;
{/if}
&lt;/MediaQuery&gt; 
NodeGui unterstützt als Cross-Plattform-Tool die Entwicklung von Desktop-Apps mit JavaScript und CSS für Linux, Mac und Windows. Dabei steht NodeGui als Entwicklungswerkzeug auch für alle drei Betriebssysteme zur Verfügung. Softwaretechnisch basiert NodeGui auf der älteren Version 5 der GUI-Library Qt, einem Application-Framework, das inzwischen zur Firma The Qt Company aus Finnland gehört. Zusätzlich verfolgt das Qt-Projekt die Wartung und Weiterentwicklung der Qt-Library, die unter der QPL (Q Public License) steht. Das unter Linux bekannte KDE (K Desktop Environment) verwendet Qt als Widget-Toolkit, ebenso wie einige weitere Desktops verschiedener Linux-Derivate.Die Realisierung von Qt erfolgt in C++ mit Anbindungen für nahezu alle wichtigen Programmiersprachen: C#, Java, Pascal, PHP, Python, Ruby und weitere. Dabei nutzt NodeGui für JavaScript nicht QML (Qt Modeling Language), sondern das C/C++-Addon des Node-APIs. Damit rendert NodeGui das GUI einer App nicht im Webbrowser, sondern mit den nativen Widgets von Qt. Die Programmierung mit NodeGui erfolgt anhand der über dieses Binding bereitgestellte JavaScript-Wrapper. Das Styling der Widgets greift auf die Stylesheets von Qt zurück, welche sich an CSS orientieren. Über die von Meta (Facebook) bereitgestellte yoga-Library erfolgt das Layouting mithilfe von Flexbox.NodeGui setzt die Installation von Node.js in Version 16.x, des darin enthaltenen Package-Managers npm, der GNU Compiler Collection (GCC) V 7 mit make-Utility und CMake ab 3.1 voraus. Diese Zusammenhänge gehen leider nicht aus der aktuellen Dokumentation von NodeGui hervor. Damit die beiden Event-Queues Node.js und Qt harmonisieren, kommt Qode zum Einsatz. Dieses npm-Package integriert die beiden Event-Loops zu einer Einheit (in Anlehnung zu Electron).Im Zentrum der Programmierung mit NodeGui steht die index.js-Datei – diese macht durch Import von require("@nodegui/nodegui") dessen API verfügbar. Das über GitHub zugängliche Starter-Projekt installiert nach dessen Cloning mit npm install das passende Qt-System. Das Starter-Projekt nutzt TypeScript über die initiale index.ts-Datei. Um das Starter-Projekt auszuführen, muss NodeGui in Version 0.44.0 nachinstalliert werden. Ansonsten kommt es im Starter-Projekt zu Fehlermeldungen.

Einsatz von Svelte NodeGUI für Desktop-Apps nicht zu empfehlen

Basis für Svelte NodeGUI bilden die nativen NodeGui-Widgets, die über dessen JavaScript-API verfügbar sind. Dazu implementiert Svelte NodeGUI einen Svelte-Renderer für NodeGui, in dessen Zentrum die view-Komponente steht. In Anlehnung an eine <div>-Anweisung von HTML strukturiert dieses <view>-Tag die App und kapselt andere Komponenten über das QWidget von NodeGui ein.Darüber hat Svelte NodeGUI eine Reihe der Qt-Widgets wie Checkboxen, Schaltflächen, Text-Bereiche oder Fortschrittsbalken realisiert. Analog NodeGui erfolgt das Styling mittels des Qt-Stylesheets und das Layouting mittels Yoga-Flexbox. Die Verarbeitung von Events greift auf den Aufzählungstyp WidgetEventTypes von NodeGui zurück, der auf den QEvents basiert.Die beschriebene Realisierung von Svelte NodeGUI verdeutlicht, dass derzeit nur ein Teil der Qt-Widgets zur Verfügung steht. Zudem erreicht Svelte NodeGUI nicht den vollen Funktionsumfang von HTML und CSS, der für Svelte bereitsteht. Zudem hat sich gezeigt, dass dieser mit den Bindings verbundene Ansatz weitere zusätzliche Hürden schafft, die nur schwer zu überwinden sind. So gibt es Probleme mit den differierenden Fonts der Desktop-Betriebssysteme, dem konditionalen Rendering von Svelte oder dem Einfügen von Svelte-Komponenten. Der Entwickler von Svelte NodeGUI arbeitet klar heraus, dass die Implementierung einer dom-nodgui-Library der zielführendere Weg sowohl für NodeGui als auch für Svelte NodeGUI wäre.Aus diesen Gründen lässt sich das Starter-Projekt von Svelte NodeGUI nur nach einigen Anpassungen in seiner ursprünglichen Form ausführen. Nach dem Cloning des Starter-Projekts aktiviert man über einen Node-Version-Manager die Node-Version 16.x und das in der package.json-Datei referenzierte svelte-nodegui-Package setzt man auf die Version 0.0.3-alpha.1. Danach starten die beiden Script-Befehle npm run dev und npm run start die App (Bild 10).
Svelte NodeGUIbenötigt für den praktischen Einsatz einige grundlegende Überarbeitungen(Bild 10) © Autor
Im Unterschied zur Alpha-Version verarbeitet das aktuellste Package von Svelte NodeGUI das Einfügen von Svelte-Komponenten nicht korrekt – was natürlich für den Aufbau des GUIs nicht akzeptabel ist. Dieses Fehlverhalten resultiert aus dem internen Verhalten des Svelte-Compilers, welches nur wenige Kenner der Materie ändern können. Einziges Manko des Alpha-Release liegt in der falschen Verarbeitung des konditionalen Rendering.

Tauri – ein frontend-unabhängiges Rust-Toolkit

Bei Tauri handelt es sich um ein Framework für die Portierung von Frontend-Anwendungen auf den Desktop und die mobile Welt. Die Realisierung von Tauri erfolgt mit der Programmiersprache Rust, die derzeit auch auf dem Backend zum Einsatz kommt. Insofern benötigt eine Tauri-Entwicklungsumgebung eine Installation von Rust, die automatisch auch den für Rust zuständigen Package-Manager/Build-Tool Cargo einrichtet.Tauri basiert auf der in Rust implementierten Cross-Plattform-Window-Manager-Library tao, die für Android, iOS, Linux, macOS und Windows zur Verfügung steht. Unter Android greift tao auf nkd-rs (Rust-Schnittstelle für Android NDK) und unter Linux auf die gtk-Rust-Bindings zurück. Um HTML, JavaScript und CSS einzubinden, hat das Tauri-Team die Cross-Plattform Rendering-Engine WRY (Webview Rendering Library) in Rust implementiert, die auf macOS WebKit, auf Windows WebView2 und auf Linux WebKitGTK benutzt.Auf dem Frontend unterstützt Tauri neben reinem HTML, JavaScript, CSS auch alle gängigen Frontend-Frameworks wie Angular, React, SvelteKit und Vue.js; zusätzlich das Frontend-Building-Tool Vite und das Webframework Next.js. Für das Scaffolding eines neuen Projekts bietet Tauri die create-tauri-app-Utility an, die auch über Bash, PowerShell, Cargo, npm, Yarn und pnpm zur Verfügung steht. Alternativ lässt sich Tauri in ein vorhandenes Frontend-Projekt integrieren. Dazu fügt einer der Package-Manager npm, Yarn, pnpm oder Cargo ein minimales Rust-Projekt, das für Tauri konfiguriert ist, dem existierenden Frontend-Projekt hinzu. Dies erfordert die Installation des Tauri-CLI (Call Level Interface): npm install --save-dev @tauri-apps/cli.Für den Einsatz von npm benötigt die package.json-Datei einen Eintrag "tauri": "tauri" in ihrem scripts-Bereich. Der anschließende im Projektordner auszuführende init-Befehl des Tauri-CLIs stellt dem Programmierer einige Fragen, dessen Antworten die notwendigen Konfigurationsdateien für die Tauri-Integration generiert. Der CLI-Befehl init von Tauri legt die erzeugten Dateien im Unterverzeichnis src-tauri in den vorhandenen Projektordner ab. Der Befehl npm run tauri info überprüft das Tauri-Setup und gibt die aktuellen Einstellungen mit den installierten Versionen der Tauri-Entwicklungsumgebung aus. Abschließend startet der dev-Befehl des Tauri-CLIs einen Compile und führt die zugehörige Web-App über Tauri als Desktop-App aus (Bild 11). Beim ersten Compile lädt Cargo die erforderlichen Abhängigkeiten herunter, so dass dieser länger als nachfolgende Compiles dauert.
Tauri führt die Demo-Appvon SvelteKit in einer WebView als Desktop-App auf macOS aus(Bild 11) © Autor
Aktuell arbeitet nur ein Entwickler von tauri am Projekt tauri-mobile, das für viele Frontends die Android und iOS-Welt mit Tauri erschließt. Die Realisierung basiert auf cargo-mobile, einem Projekt der Brainium Studios. Die Programmierung setzt für Android eine Installation von Android Studio oder den Android-Development-Tools voraus; für iOS sind die Kommandozeilen-Tools von Xcode erforderlich: xcode-select --install. Die Android-Entwicklung benötigt die Umgebungsvariablen ANDROID_HOME, ANDROID_SDK_ROOT und NDK_HOME. Für die iOS-Entwicklung kommt leider eine veraltete Xcode-Version zum Einsatz, die aktuelle Version 14.x kann noch nicht verwendet werden. Da sich bei tauri-mobile derzeit noch vieles im Fluss befindet, empfiehlt es sich aktuell nicht, das Toolkit in einem bestehenden Projekt einzusetzen.

Hybride Apps auf mobilen Endgeräten bereitstellen

Bei Capacitor von Ionic handelt es sich um ein Framework zur Erstellung hybrider Apps für mobile Endgeräte. Ionic entwickelt Capacitor als Open-Source-Projekt über GitHub. Für die Ablösung von PhoneGap empfiehlt Adobe, dieses Tool einzusetzen. Ausgangspunkt stellt eine mit HTML, CSS und JavaScript entwickelte Web-App dar. Capacitor packt diese Web-App und bettet sie in eine WebView ein, um sie innerhalb einer nativen App der jeweiligen mobilen Plattform anzuzeigen. Zusätzlich besitzt Capacitor ein API für den Zugriff auf native Features von Android und iOS. Des Weiteren unterstützt Capacitor viele der über 3000 für Cordova (PhoneGap) verfügbaren Plugins.Über eine eigene Plugin-Schnittstelle entwickelt die Capacitor-Community verschiedene Capacitor-Plugins und stellt deren Features für die Wiederverwendung in der hybriden App zur Verfügung. Capacitor besitzt ein CLI (Call-Level-Interface), das der Package-Runner über npx @capacitor/cli erschließt. Als Alias für @capacitor/cli steht cap zur Verfügung, so dass der Befehl npx cap das CLI erreicht. Eine Installation von Capacitor mittels des Befehls npm install -g @capacitor/cli als globales npm-Package genügt für die Ausführung von CLI-Befehlen über den Alias cap. Danach öffnet der Befehl cap --help das Hilfesystem von Capacitor. Um Capacitor in einem Web-Projekt zu verwenden, benötigt man eine Installation der beiden Packages @capacitor/cli @capacitor/core.Anschließend bereit der Befehl cap init <appName> <appID> das Projekt auf den Einsatz von Capacitor vor. Dieser init-Befehl erzeugt die Konfigurationsdatei: capacitor.config.ts – in dieser muss manuell der Eintrag webDir an die Gegebenheit der Web-App angepasst werden. Dabei muss der webDir-Eintrag auf das Verzeichnis verweisen, in das ein Build-Vorgang der Web-App alle seine Ergebnisse ablegt. In diesem Verzeichnis muss sich auch die index.html-Datei befinden. Für SvelteKit verwendet man dazu den @sveltejs/adapter-static, diesen installiert der Befehl npm i -D @sveltejs/adapter-static@next in das Projekt. Danach nimmt man in die svelte.config.js-Datei die Anweisung import adapter from '@sveltejs/adapter-static'; auf und legt eine +layout.js|ts-Datei mit der Anweisung export const prerender = true; an. Zudem benötigt die index.html-Datei einen <head>-Tag.Nachdem die Voraussetzungen für die Entwicklung mit Capacitor geschaffen sind, fügt man im nächsten Schritt die gewünschte mobile Plattform hinzu. Dazu greift man auf die Befehle cap add android und cap add ios zurück. Der add-Befehl erzeugt ein Unterverzeichnis für das mobile Betriebssystem, generiert die passenden Entwicklungsdateien für die Einbettung der Web-App in die mobile Plattform und legt die erzeugten Dateien dort ab. Nach Änderungen in den Entwicklungsdateien der Web-App müssen diese ebenfalls den vorhandenen Capacitor-Projekten zugänglich gemacht werden. Dazu stehen die beiden CLI-Befehle cap sync android und cap sync ios zur Verfügung.Der Befehl cap doctor prüft die Einstellungen eines vorhandenen Capacitor-Projekts, diesen kann man auch auf eine mobile Plattform beschränken. So überprüft cap doctor ios lediglich die Verfügbarkeit von Capacitor und die Einbettung der Web-App in das mobile Betriebssystem iOS. Um ein Capacitor-Projekt in einer der beiden nativen Entwicklungsumgebungen zu öffnen, führt man einen der Befehle cap open android oder cap open ios aus. Nach dem Start von Android Studio zeigt die IDE das Capacitor-Projekt an. Mit der Auswahl eines geeigneten virtuellen Geräts führt die IDE einen Build-Vorgang mittels Gradle durch.War der Build-Vorgang erfolgreich, so öffnet der Android-Emulator die Web-App und das virtuelle Gerät führt diese aus (Bild 12). Analog arbeitet der Programmierer mit der Apple-IDE Xcode: cap open ios zeigt in Xcode das zugehörige Capacitor-Projekt an. Ein Klick auf das kleine schwarze Pfeil-Icon in der Xcode-Toolbar 'Start the active scheme' startet den Build-Vorgang und öffnet die Web-App im iOS-Simulator. Um native Features zu nutzen, muss die JavaScript-Welt mit der mobilen Welt kommunizieren. Für diese Kommunikation steht in Capacitor eine spezielle Plugin-Schnittstelle zur Verfügung.
Capacitorstellt die von SvelteKit als Skeleton project generierte Web-App für Tests über einen Android-Emulator bereit(Bild 12) © Autor
Ionic, der Entwickler von Capacitor, hat eine Reihe kostenloser Official Plugins und drei über ein monatliches Abo verfügbare Enterprise Plugins realisiert. Zusätzlich hat die Capacitor-Community weitere Plugins realisiert. Sollte keines der von Ionic bereitgestellten Capacitor-Plugins über die benötigte Funktionalität verfügen, kann man mittels der Plugin-Schnittstelle ein eigenes Plugin programmieren. Für diese Realisierung nutzt man entweder das iOS SDK von Apple und eine der Programmiersprachen Swift oder Objective-C. Analog steht unter Android dessen SDK und eine Java- beziehungsweise Kotlin-Schnittstelle zur Verfügung.Nach der Realisierung des Plugins für die beiden mobilen Betriebssysteme macht ein eignes npm-Package das Capacitor-Plugin anderen Entwicklern verfügbar. Dazu erzeugt der Plugin-Generator von Capacitor ein eigenständiges Projekt; anschließend kopiert der Entwickler die programmierten iOS- und Android-Ressourcen in dieses Projekt. Ein spezielles im Plugin-Projekt vorhandenes verify-Script überprüft die korrekte Übernahme der Quelldateien. Nach erfolgreichen Tests des neuen Capacitor-Plugins macht der Befehl npm publish im Plugin-Projektordner dieses in der öffentlichen npm-Registry verfügbar. Jetzt lässt sich das neue Plugin, genauso wie alle anderen Capacitor-Plugins in einem Capacitor-Projekt wiederverwenden.Wails stellt ebenfalls eine leichtgewichtige Alternative für Desktop-Apps dar. Das in der Sprache Go programmierte Framework bietet die Möglichkeit verschiedene Frontend-Technologien einzubetten. Dazu muss das Frontend-Framework die Programmiersprache JavaScript unterstützen. Der Einsatz von Wails setzt eine Installation von Node (ab Version 15) sowie eines Go-Systems (ab Version 1.18), die Einrichtung der Umgebungsvariable GOPATH und deren Aufnahme in den PATH voraus. Für Windows benötigt man eine Installation des WebView2-Runtimes, für macOS die Xcode-Command-Line-Tools und für Linux die gcc-Buildtools mit libgtk3 und libwebkit.Nach dem Einrichten von Wails über dessen GitHub-Repository steht das Wails-CLI (Call Level Interface) zur Verfügung. Der CLI-Befehl wails doctor prüft, ob alle Abhängigkeiten für den Einsatz von Wails erfüllt sind. Im Bedarfsfall gibt der doctor-Befehl Ratschläge aus, um Probleme zu beheben. Für die Arbeit mit einem Frontend bindet Wails bei der Neuanlage eines Projekts die Frameworks Lit, Preact, React, Svelte, Vanilla JavaScript und Vue ein. Dazu greift der init-Befehl bei der Projekt-Anlage auf ein in Wails für das jeweilige Framework hinterlegtes Template zurück. Zusätzlich gibt es noch Templates, die von der Wails-Community bereitstellt werden.Das Frontend-Template fügt Wails in seine eigene Ablagestruktur in das Unterverzeichnis frontend ein. Oberhalb von frontend befinden sich der Ordner build, die go-Ressourcen sowie die Wails-Konfigurationsdatei wails.json. Im frontend-Unterverzeichnis arbeitet ein Programmierer wie üblich mit den Tools des Frontend-Frameworks. Bei der Neuanlage eines Projekts für ein spezielles Frontend erzeugt der init-Befehl auch den notwendigen Go/JavaScript-Quellcode für die Einbindung von Wails in die Web-App. Für Tests über den Projektordner greift der Entwickler auf den CLI-Befehl wails dev zurück.Leider stimmt die dabei von Vite-ausgegebene URL für Entwicklungstests nicht; vielmehr läuft der Webserver auf http://localhost:34115. Zusätzlich öffnet Wails automatisch die zugehörige Desktop-App (Bild 13). Mithilfe des CLI-Befehls wails build erzeugt das Wails-Framework anhand optionaler Flags das gewünschte Binärprogramm. Die so erhaltene Desktop-App benutzt JavaScript-Bindungs, um Go-Methoden auszuführen. Dabei lassen sich diese Go-Methoden auch auf dem Frontend wie lokale JavaScript-Methoden verwenden. Das Frontend läuft in der Desktop-App als Web-App in einem Webkit-Fenster. Seit Go Version 1.16 bietet die Go-Plattform über das mobile-Package eine Entwicklung für mobile Endgeräte an. Daher plant die Wails-Community ab Version 3.5 (aktuell befindet sich Wails in der Version 2.3.1) eine zusätzliche Unterstützung für Android und iOS.
Eine über das Svelte-TypeScript-Templatevon Wails bereitgestellte Desktop-App, die unter macOS läuft(Bild 13) © Autor

Links zum Thema

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Evolutionäres Prototyping von Business-Apps - Low Code/No Code und KI mit Power Apps
Microsoft baut Power Apps zunehmend mit Features aus, um die Low-Code-/No-Code-Welt mit der KI und der professionellen Programmierung zu verbinden.
19 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige