Markup, Stile, Skripte und Updates für Mini-Apps

Markup languages

Wie bereits erwähnt, werden Mini-Apps nicht in reinem HTML, sondern in HTML-Dialekten geschrieben. Wenn Sie schon einmal mit Textinterpolation und Vue.js-Direktiven gearbeitet haben, werden Sie sich sofort zu Hause fühlen. Ähnliche Konzepte gab es aber schon viel früher in XML-Transformationen (XSLT). Unten sehen Sie Codebeispiele aus WXML von WeChat. Das Konzept ist jedoch für alle Mini-App-Plattformen identisch, nämlich AXML von Alipay, Swan Element von Baidu, TTML von ByteDance (obwohl es in den DevTools als Bxml bezeichnet wird) und HTML von Quick App. Genau wie bei Vue.js ist das zugrunde liegende Mini-App-Programmierkonzept das model-view-viewmodel (MVVM).

Datenbindung

Die Datenbindung entspricht der Textinterpolation in Vue.js.

<!-- wxml -->
<view>{{message}}</view>
// page.js
Page({
  data: {
    message: "Hello World!",
  },
});

Listenrendering

Das Listen-Rendering funktioniert wie die Vue.js-Direktive v-for.

<!-- wxml -->
<view wx:for="{{array}}">{{item}}</view>
// page.js
Page({
  data: {
    array: [1, 2, 3, 4, 5],
  },
});

Bedingtes Rendering

Das bedingte Rendering funktioniert ähnlich wie die v-if-Anweisung in Vue.js.

<!-- wxml -->
<view wx:if="{{view == 'one'}}">One</view>
<view wx:elif="{{view == 'two'}}">Two</view>
<view wx:else="{{view == 'three'}}">Three</view>
// page.js
Page({
  data: {
    view: "three",
  },
});

Vorlagen

Anstatt das content einer HTML-Vorlage imperativ zu klonen, können WXML-Vorlagen deklarativ über das Attribut is verwendet werden, das mit einer Vorlagendefinition verknüpft ist.

<!-- wxml -->
<template name="person">
  <view>
    First Name: {{firstName}}, Last Name: {{lastName}}
  </view>
</template>
<template is="person" data="{{...personA}}"></template>
<template is="person" data="{{...personB}}"></template>
<template is="person" data="{{...personC}}"></template>
// page.js
Page({
  data: {
    personA: { firstName: "Alice", lastName: "Foo" },
    personB: { firstName: "Bob", lastName: "Bar" },
    personC: { firstName: "Charly", lastName: "Baz" },
  },
});

Stile

Das Styling erfolgt mit CSS-Dialekten. Bei WeChat lautet er WXSS. Bei Alipay heißt er ACSS, bei Baidu einfach CSS und bei ByteDance TTSS. Sie haben gemeinsam, dass sie CSS um responsive Pixel erweitern. Beim Erstellen von regulärem CSS müssen Entwickler alle Pixeleinheiten konvertieren, um sie an die Bildschirme verschiedener Mobilgeräte mit unterschiedlichen Breiten und Pixelverhältnissen anzupassen. TTSS unterstützt die rpx-Einheit als zugrunde liegende Ebene. Das bedeutet, dass die Mini-App den Job vom Entwickler übernimmt und die Einheiten für ihn konvertiert, basierend auf einer angegebenen Bildschirmbreite von 750rpx. Auf einem Pixel 3a mit einer Bildschirmbreite von 393px (und einem Geräte-Pixel-Verhältnis von 2.75) wird der responsive 200rpx auf dem echten Gerät beispielsweise zu 104px, wenn er mit den Chrome-Entwicklertools überprüft wird (393 px ÷ 750 rpx × 200 rpx Θ 104 px). In Android wird dieses Konzept als dichteunabhängige Pixel bezeichnet.

Bei der Prüfung einer Ansicht mit den Chrome-Entwicklertools, deren responsives Pixel-Abstand mit „200rpx“ angegeben wurde, zeigt sich, dass es auf einem Pixel 3a tatsächlich „104px“ beträgt.
Das tatsächliche Padding auf einem Pixel 3a mit den Chrome-Entwicklertools prüfen.
/* app.wxss */
.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 200rpx 0; /* ← responsive pixels */
  box-sizing: border-box;
}

Da Komponenten (siehe unten) kein Shadow-DOM verwenden, wirken sich auf einer Seite deklarierte Stile auf alle Komponenten aus. Die gängige Organisation von Stylesheet-Dateien besteht darin, ein Stamm-Stylesheet für globale Stile und individuelle Stylesheets pro Seite für jede Seite der Mini-App zu haben. Stile können mit einer @import-Regel importiert werden, die sich wie die CSS-At-Regel @import verhält. Wie in HTML können Stile auch inline deklariert werden, einschließlich dynamischer Textinterpolation (siehe oben).

<view style="color:{{color}};" />

Skripting

Mini-Apps unterstützen eine „sichere Teilmenge“ von JavaScript mit Unterstützung für Module mit unterschiedlichen Syntaxen, die an CommonJS oder RequireJS erinnern. JavaScript-Code kann nicht über eval() ausgeführt und mit new Function() keine Funktionen erstellt werden. Der Ausführungskontext für Scripts ist auf Geräten V8 oder JavaScriptCore und im Simulator V8 oder NW.js. Die Codierung mit ES6 oder einer neueren Syntax ist in der Regel möglich, da die jeweiligen Entwicklertools den Code automatisch in ES5 transpilieren, wenn das Build-Ziel ein Betriebssystem mit einer älteren WebView-Implementierung ist (siehe später). In der Dokumentation der Super-App-Anbieter wird ausdrücklich darauf hingewiesen, dass ihre Scriptsprachen nicht mit JavaScript verwechselt werden dürfen und sich von JavaScript unterscheiden. Diese Aussage bezieht sich jedoch hauptsächlich auf die Funktionsweise von Modulen, d. h., dass sie noch keine standardmäßigen ES-Module unterstützen.

Wie bereits erwähnt, basiert das Programmierkonzept für Mini-Apps auf dem Model-View-View-Modell (MVVM). Die Logikschicht und die Ansichtsschicht werden in verschiedenen Threads ausgeführt. Das bedeutet, dass die Benutzeroberfläche nicht durch lang laufende Vorgänge blockiert wird. Im Web können Sie sich Scripts als in einem Webworker ausgeführt vorstellen.

Die Scriptsprache von WeChat heißt WXS, die von Alipay SJS und die von ByteDance SJS. In Baidu wird von JS gesprochen, wenn sie auf dieses verweist. Diese Scripts müssen mit einem speziellen Tag eingefügt werden, z. B. <wxs> in WeChat. Quick App verwendet dagegen reguläre <script>-Tags und die ES6-JS-Syntax.

<wxs module="m1">
  var msg = "hello world";
  module.exports.message = msg;
</wxs>

<view>{{m1.message}}</view>

Module können auch über ein src-Attribut geladen oder über require() importiert werden.

// /pages/tools.wxs
var foo = "'hello world' from tools.wxs";
var bar = function (d) {
  return d;
};
module.exports = {
  FOO: foo,
  bar: bar,
};
module.exports.msg = "some msg";
<!-- page/index/index.wxml -->
<wxs src="./../tools.wxs" module="tools" />
<view>{{tools.msg}}</view>
<view>{{tools.bar(tools.FOO)}}</view>
// /pages/logic.wxs
var tools = require("./tools.wxs");

console.log(tools.FOO);
console.log(tools.bar("logic.wxs"));
console.log(tools.msg);

JavaScript Bridge API

Die JavaScript-Bridge, die Mini-Apps mit dem Betriebssystem verbindet, ermöglicht die Nutzung von Betriebssystemfunktionen (siehe Zugriff auf leistungsstarke Funktionen). Außerdem bietet es eine Reihe von praktischen Methoden. Eine Übersicht finden Sie in den API-Dokumenten von WeChat, Alipay, Baidu, ByteDance und Quick App.

Die Funktionserkennung ist unkompliziert, da alle Plattformen eine (so genannte) canIUse()-Methode bereitstellen, deren Name von der Website caniuse.com inspiriert zu sein scheint. Mit der tt.canIUse() von ByteDance können beispielsweise APIs, Methoden, Parameter, Optionen, Komponenten und Attribute unterstützt werden.

// Testing if the `<swiper>` component is supported.
tt.canIUse("swiper");
// Testing if a particular field is supported.
tt.canIUse("request.success.data");

Updates

Mini-Apps haben keinen standardisierten Aktualisierungsmechanismus (Diskussion zur möglichen Standardisierung). Alle Mini-App-Plattformen haben ein Backend-System, mit dem Mini-App-Entwickler neue Versionen ihrer Mini-Apps hochladen können. Eine Super-App verwendet dann dieses Back-End-System, um nach Updates zu suchen und diese herunterzuladen. Einige Super-Apps führen Updates vollständig im Hintergrund aus, ohne dass die Mini-App selbst den Update-Ablauf beeinflussen kann. Andere Super-Apps geben den Mini-Apps mehr Kontrolle.

Als Beispiel für einen ausgefeilten Prozess wird in den folgenden Abschnitten der Updatemechanismus für Mini-Apps von WeChat ausführlicher beschrieben. In den folgenden beiden Szenarien wird über WeChat nach verfügbaren Updates gesucht:

  1. Solange WeChat aktiv ist, wird regelmäßig nach Updates für kürzlich verwendete Mini-Apps gesucht. Wenn ein Update gefunden wird, wird es heruntergeladen und beim nächsten Kaltstart der Mini-App synchron angewendet. Ein Kaltstart einer Mini-App erfolgt, wenn die Mini-App beim Öffnen durch den Nutzer nicht aktiv war. WeChat schließt Mini-Apps nach 5 Minuten im Hintergrund zwangsweise.
  2. WeChat sucht auch nach Updates, wenn eine Mini-App neu gestartet wird. Bei Mini-Apps, die der Nutzer seit längerer Zeit nicht geöffnet hat, wird das Update synchron geprüft und heruntergeladen. Während des Herunterladens des Updates muss der Nutzer warten. Sobald der Download abgeschlossen ist, wird das Update angewendet und die Mini-App wird geöffnet. Wenn der Download fehlschlägt, z.B. aufgrund einer schlechten Netzwerkverbindung, wird die Mini-App trotzdem geöffnet. Bei Mini-Apps, die der Nutzer kürzlich geöffnet hat, wird jedes potenzielle Update asynchron im Hintergrund heruntergeladen und angewendet, wenn der Nutzer die Mini-App das nächste Mal kalt startet.

Für Mini-Apps können frühere Updates mithilfe der UpdateManager API aktiviert werden. Es bietet folgende Funktionen:

  • Benachrichtigt die Mini-App, wenn nach Updates gesucht wird (onCheckForUpdate)
  • Benachrichtigt die Mini-App, wenn ein Update heruntergeladen wurde und verfügbar ist. (onUpdateReady)
  • Benachrichtigt die Mini-App, wenn ein Update nicht heruntergeladen werden konnte. (onUpdateFailed)
  • Ermöglicht es der Mini-App, ein verfügbares Update erzwungen zu installieren, wodurch die App neu gestartet wird. (applyUpdate)

WeChat bietet Entwicklern von Mini-Apps in seinem Backend-System auch zusätzliche Anpassungsoptionen für Updates: 1. Mit einer Option können Entwickler synchrone Updates für Nutzer deaktivieren, die bereits eine bestimmte Mindestversion der Mini-App installiert haben, und stattdessen asynchrone Updates erzwingen. 2. Mit einer weiteren Option können Entwickler eine Mindestversion ihrer Mini-App festlegen. Bei asynchronen Updates von einer Version, die niedriger als die Mindestversion ist, wird die Mini-App nach dem Anwenden des Updates zwangsweise neu geladen. Außerdem wird das Öffnen einer älteren Version der Mini-App blockiert, wenn der Download des Updates fehlschlägt.

Danksagungen

Dieser Artikel wurde von Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent und Keith Gu gelesen.