Flutter, React Native und NativeScript: Kopf an Kopf im Cross-Plattform-Rennen

Flutter, React Native und NativeScript verwenden ähnliche Ansätze zur plattformübergreifenden Entwicklung mit Skriptsprachen. Bei der Auswahl hilft ein Blick auf die großen und kleinen Unterschiede.

Werkzeuge  –  11 Kommentare

Die Hersteller der Cross-Plattform-Frameworks zum Erstellen vor allem mobiler Anwendungen locken mit beeindruckenden Versprechen. Daher lohnt ein Vergleich der unterschiedlichen Ansätze und Arbeitsweisen von NativeScript, React Native und Flutter.

Als Testfall dient das Erstellen von Applikationen für Android, während die Portabilität für den Desktop nur am Rande Thema ist. Im Zentrum stehen die Konzepte der jeweiligen Frameworks und zwar aus Sicht eines Mobilentwicklers. Webentwickler mögen teilweise eine andere Sichtweise haben.

Die drei vorgestellten Frameworks sind nicht die einzigen Tools, die plattformübergreifende Entwicklung bieten. Ebenfalls nennenswert sind die Werkzeuge der Qt Company und von Embarcadero. Letzteres eignet sich dank des Komforts beim Data-Binding vor allem für das Erstellen komplexer modellgetriebener Anwendungen.

Flutter, React Native und NativeScript sind jedoch keine zufällige Auswahl: Alle drei Frameworks verwenden zeitgemäße Designkonzepte und weichen mehr oder weniger stark vom seit Visual Basic etablierten RAD-Prozess (Rapid Application Development) ab.

Entwickeln in der Businessclass

Aus Entwicklersicht ist der Komfort ein wichtiges Kriterium für die Auswahl. Das leistungsstärkste Framework taugt wenig, wenn es nicht leicht zugänglich ist. Google hat dabei einen Vorteil, da es mit Android Studio eine von JetBrains lizenzierte, extrem leistungsfähige Entwicklungsumgebung im Haus hat. Aus der Logik folgt, dass Android Studio mit einigen Plug-ins zur Arbeit mit Flutter geeignet ist. Details dazu finden sich in der Flutter-Einführung auf heise Developer. Die Integration der Zielgeräte in die IDE ist erstklassig.

Der in Android Studio enthaltenen WYSIWYG-Editor steht jedoch derzeit nicht für Flutter zur Verfügung. Eine Alternative ist der Widget-Maker, und der XML-zu-Layout-Konverter ist eine nützliche Hilfe zum Erstellen von Layouts für Visual-Studio-Nutzer. Allerdings erreichen beide Werkzeuge nicht den Arbeitskomfort eines integrierten Tools.

"Bring your Own" bedeutet "Kümmert euch selbst".

In der Praxis ist es zumindest nach Ansicht des Autors besser, wenn der Plattformanbieter eine offizielle oder zumindest empfohlene Entwicklungsumgebung vorgibt.

In der Microprozessorwelt von STMicroelectronics existierte zeitweise ein gutes halbes Dutzend IDEs. Das mag diverse Spezialanforderungen abgedeckt haben, die breite Masse der Entwickler waren damit aber überfordert. Als Pointe ist erwähnenswert, dass der Hersteller schließlich Atollic zukaufte und damit die IDE TrueStudio ins Haus holte.

NativeScript hatte ursprünglich eine erstklassige IDE, die Telerik jedoch im Jahre 2017 ersatzlos gestrichen hat. Seither existiert neben einem Kommandozeilen-Werkzeug ein als Sidekick bezeichnetes Tool, das die Ausführungsumgebung überprüft und den Code auf Endgeräte ausliefert. Zum Programmieren dürfen Entwickler den Editor ihrer Wahl nutzen, was ein Euphemismus für das Fehlen eines offiziell empfohlenen Editors ist. Eine vollwertige WYSIWYG-Designumgebung zum Erstellen grafischer Oberflächen sucht man ebenfalls vergebens.

Bei Facebook setzt man in React Native auf ein Kommandozeilenwerkzeug, das die benötigten SDK-Komponenten unter Einsatz von Android Studio herunterlädt. Mit Expo existiert zudem ein Schnellstartsystem, das sich an Webentwickler wendet. Sowohl Telerik als auch Facebook bieten für ihre Systeme zudem Entwicklungsumgebungen im Browser an, die sich für kleine Fingerübungen eignen. Bei React Native heißt das Tool Snack und für NativeScript PlayGround.

Einen WYSIWYG-Editor sucht man für React Native vergeblich, und beim Codeeditor gilt ebenfalls die freie Auswahl separater Werkzeuge. Angemerkt sei, dass die genannten Hilfswerkzeuge schnelle Übertragung von Codeänderungen auf Zielgeräte erlauben. Daher geht der lange Debug-Deploy-Prozess relativ schnell vonstatten.

Ein Ärgernis für erfahrene Entwickler

Vor den Zeiten des Rapid Development erzeugten Entwickler Benutzerschnittstellen durch den Aufruf von APIs, die Strukturen oder Identifier zurückgaben. Darüber ließen sich weitere Attribute festsetzen. Zeitgemäße Tools trennen die Geschäftslogik vom restlichen Code. Die Benutzerschnittstelle ist eine separate Schicht des Programms, die nur teilweise mit dem Rest des Codes verbunden ist. Sowohl Flutter als auch React Native verlangen massive Änderungen, während sich NativeScript vergleichsweise konservativ zeigt.

Eine primitive "Hello World"-Applikation in NativeScript enthält eine .html-Datei, in der sich folgendes Markup findet:

<ActionBar title="Home" class="action-bar">
</ActionBar>
<GridLayout>
<ScrollView class="page">
<StackLayout class="home-panel">
<!--Add your page content here-->
<Label textWrap="true"
text="Play with NativeScript!"
class="h2 description-label"></Label>
</StackLayout>
</ScrollView>
</GridLayout>

Der NativeScript-Interpreter würde diese Datei zur Laufzeit parsen und die einzelnen Tags durch in der Plattform vorliegende Steuerelemente umsetzen. In den CSS-Dateien lassen sich zusätzliche Attribute anliefern, die die Laufzeitumgebung mehr oder weniger umfangreich versucht umzusetzen.

Neben dieser angenehmen Vorgehensweise bietet NativeScript einen weiteren Aspekt: Veränderungen der Eigenschaften von Steuerelementen lassen sich einfach durchführen. Analog zu QML gilt, dass nicht alle Widgets aus dem Code ansprechbar sind. Für die Kommunikation benötigt das gewünschte Label im ersten Schritt ein ID-Feld:

<Label id="lbl" text="{{ title }}" textWrap="true" />

Zur Laufzeit erfolgt der Zugriff folgendermaßen:

const labelModule = require("tns-core-modules/ui/label");
const label = page.getViewById("lbl");

label.text = "NativeScript is Awesome";
label.textWrap = true;
label.textAlignment = "center";

Ärgerlich ist es, dass bei der Interaktion mit NativeScript-Steuerelementen der korrekte Require-String mitunter schwer erkennbar ist. Er lädt die Klasse, die den Zugriff auf die Attribute ermöglicht. Der anschließende Aufruf der Methode getViewById holt eine Instanz des Steuerelements. Der Rest des Codes verhält sich analog zu anderen RAD-Tools wie Visual Basic oder Qt.