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

Markup languages

Wie bereits erwähnt, werden Mini-Apps nicht mit einfachem HTML, sondern mit 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. Wie bei Vue.js basiert das Programmierkonzept für Mini-Apps auf 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 wie die v-if-Anweisung von 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 jedoch gemeinsam, dass sie CSS mit responsiven Pixeln 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). Unter Android wird dasselbe Konzept als dichteunabhängiges 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 weiter unten) kein Shadow DOM verwenden, können auf einer Seite deklarierte Stile in alle Komponenten übertragen werden. Die gängige Organisation von Stylesheet-Dateien besteht aus einem Stamm-Stylesheet für globale Stile und individuellen Stylesheets pro Seite, die für jede Seite der Mini-App spezifisch sind. Stile können mit einer @import-Regel importiert werden, die sich wie die CSS-At-Rule @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 Kontext für die Skriptausführung ist auf Geräten V8 oder JavaScriptCore und im Simulator V8 oder NW.js. Das Codieren mit ES6 oder einer neueren Syntax ist in der Regel möglich, da die jeweiligen DevTools den Code automatisch in ES5 transpilieren, wenn das Build-Ziel ein Betriebssystem mit einer älteren WebView-Implementierung ist (siehe unten). 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 Anweisung bezieht sich jedoch größtenteils nur auf die Funktionsweise der Module, 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 Skripts vorstellen, die in einem Web Worker ausgeführt werden.

Die Skriptsprache von WeChat heißt WXS, SJS von Alipay, SJS von ByteDance. Baidu spricht von JS, wenn es auf seine eigene Version Bezug nimmt. 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 praktischer 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 Updatemechanismus (Diskussion über potenzielle 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 Backend-System, um nach Updates zu suchen und sie herunterzuladen. Einige Super-Apps führen Updates vollständig im Hintergrund aus, ohne dass die Mini-App selbst den Update-Ablauf beeinflussen kann. Bei anderen Super-Apps haben die Mini-Apps mehr Kontrolle.

Als Beispiel für einen ausgefeilten Prozess wird in den folgenden Absätzen der Aktualisierungsmechanismus von WeChat für Mini-Apps näher beschrieben. WeChat prüft in den folgenden zwei Fällen, ob Updates verfügbar sind:

  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 in letzter Zeit geöffnet hat, wird jedes potenzielle Update asynchron im Hintergrund heruntergeladen und beim nächsten Kaltstart der Mini-App angewendet.

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 geprüft.