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 der Textinterpolation und den Direktiven von Vue.js gearbeitet haben, werden Sie sich sofort zurechtfinden. Ähnliche Konzepte gab es aber schon viel früher in XML-Transformationen (XSLT). Unten sehen Sie Codebeispiele aus dem WXML von WeChat. Das Konzept ist jedoch für alle Mini-App-Plattformen gleich, 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 zugrunde liegende Programmierkonzept für Mini-Apps auf dem 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 Rendern von Listen funktioniert wie die v-for-Direktive von Vue.js.

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

Bedingtes Rendern

Das bedingte Rendern funktioniert wie die v-if-Direktive 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 Klonen des content einer HTML-Vorlage zu erfordern, können WXML-Vorlagen deklarativ über das Attribut is verwendet werden, das auf eine Vorlagendefinition verweist.

<!-- 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

Die Gestaltung erfolgt mit Dialekten von CSS. Der Name von WeChat ist WXSS. Bei Alipay heißt es ACSS, bei Baidu einfach CSS und bei ByteDance TTSS. Sie alle haben gemeinsam, dass sie CSS mit responsiven Pixeln erweitern. Beim Schreiben von regulärem CSS müssen Entwickler alle Pixeleinheiten konvertieren, um sie an verschiedene Mobilgerätebildschirme mit unterschiedlichen Breiten und Pixelverhältnissen anzupassen. TTSS unterstützt die Einheit rpx als zugrunde liegende Ebene. Das bedeutet, dass die Mini-App die Aufgabe vom Entwickler übernimmt und die Einheiten in seinem Namen basierend auf einer angegebenen Bildschirmbreite von 750rpx konvertiert. Auf einem Pixel 3a mit einer Bildschirmbreite von 393px und einem Geräte-Pixelverhältnis von 2.75 werden responsive 200rpx auf dem tatsächlichen Gerät zu 104px, wenn sie mit den Chrome-Entwicklertools untersucht werden (393 px / 750 rpx * 200 rpx ≈ 104 px). In Android wird dasselbe Konzept als dichteunabhängiges Pixel bezeichnet.

Wenn Sie eine Ansicht mit den Chrome-Entwicklertools untersuchen, deren responsives Pixel-Padding mit „200rpx“ angegeben wurde, sehen Sie, dass es auf einem Pixel 3a-Gerät 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. In der Regel gibt es ein Stylesheet für globale Stile und individuelle Stylesheets für jede Seite der Mini-App. 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 der dynamischen Textinterpolation (siehe vorher).

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

Skripting

Mini-Apps unterstützen eine „sichere Teilmenge“ von JavaScript, die Unterstützung für Module mit unterschiedlichen Syntaxen umfasst, die an CommonJS oder RequireJS erinnern. JavaScript-Code kann nicht über eval() ausgeführt werden und es können keine Funktionen mit new Function() erstellt werden. Der Kontext für die Skriptausführung ist V8 oder JavaScriptCore auf Geräten und V8 oder NW.js im Simulator. Die Programmierung mit ES6 oder neuerer Syntax ist in der Regel möglich, da die jeweiligen DevTools den Code automatisch in ES5 transpiliert, 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 Scripting-Sprachen 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 Standard-ES-Module noch nicht unterstützen.

Wie bereits erwähnt, ist das Programmierkonzept für Mini-Apps das Model-View-ViewModel (MVVM). Die Logik- und die Ansichtsebene werden in unterschiedlichen Threads ausgeführt. Das bedeutet, dass die Benutzeroberfläche nicht durch lang andauernde Vorgänge blockiert wird. Im Web können Sie sich das so vorstellen, dass Skripts in einem Web Worker ausgeführt werden.

Die Scripting-Sprache von WeChat heißt WXS, die von Alipay SJS und die von ByteDance ebenfalls SJS. Baidu spricht von JS, wenn es sich auf seine eigene Lösung bezieht. Diese Skripts müssen mit einer speziellen Art von Tag eingebunden werden, z. B. <wxs> in WeChat. Bei Quick Apps werden dagegen reguläre <script>-Tags und die ES6-JS-Syntax verwendet.

<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 sie eine Reihe von Hilfsmethoden. Eine Übersicht über die verschiedenen APIs von WeChat, Alipay, Baidu, ByteDance und Quick App finden Sie hier.

Die Funktionserkennung ist unkompliziert, da alle Plattformen eine (buchstäblich so genannte) canIUse()-Methode bereitstellen, deren Name von der Website caniuse.com inspiriert zu sein scheint. Mit der tt.canIUse() von ByteDance lassen sich beispielsweise Unterstützungstests für APIs, Methoden, Parameter, Optionen, Komponenten und Attribute durchführen.

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

Updates

Für Mini-Apps gibt es keinen standardisierten Aktualisierungsmechanismus (Diskussion über eine mögliche Standardisierung). Alle Mini-App-Plattformen haben ein Backend-System, über das 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 durch, ohne dass die Mini-App selbst den Updatevorgang beeinflussen kann. Andere Super-Apps bieten den Mini-Apps mehr Kontrolle.

Als Beispiel für einen komplexen Prozess werden in den folgenden Absätzen WeChat-Update-Mechanismus für Mini-Apps näher beschrieben. WeChat sucht in den folgenden zwei Szenarien nach verfügbaren Updates:

  1. WeChat sucht regelmäßig nach Updates für kürzlich verwendete Mini-Apps, solange WeChat ausgeführt wird. Wenn ein Update gefunden wird, wird es heruntergeladen und synchron angewendet, wenn der Nutzer die Mini-App das nächste Mal kalt startet. Ein Kaltstart einer Mini-App erfolgt, wenn die Mini-App beim Öffnen durch den Nutzer nicht ausgeführt wurde (WeChat schließt Mini-Apps nach 5 Minuten im Hintergrund).
  2. WeChat sucht auch nach Updates, wenn eine Mini-App kalt gestartet wird. Bei Mini-Apps, die der Nutzer längere Zeit nicht geöffnet hat, wird das Update synchron geprüft und heruntergeladen. Während das Update heruntergeladen wird, muss der Nutzer warten. Wenn 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 vor Kurzem geöffnet hat, werden alle potenziellen Updates asynchron im Hintergrund heruntergeladen und beim nächsten Kaltstart der Mini-App angewendet.

Mini-Apps können frühere Updates über die UpdateManager API aktivieren. Sie bietet die folgenden 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 der Mini-App, ein verfügbares Update zu erzwingen, wodurch die App neu gestartet wird. (applyUpdate)

WeChat bietet Mini-App-Entwicklern in seinem Backend-System auch zusätzliche Optionen zur Anpassung von Updates: 1. Mit einer Option können Entwickler synchrone Updates für Nutzer deaktivieren, die bereits eine bestimmte Mindestversion der Mini-App installiert haben. Stattdessen werden die Updates dann asynchron erzwungen. 2. Entwickler können auch 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 neu geladen. Außerdem wird das Öffnen einer älteren Version der Mini-App blockiert, wenn das Herunterladen des Updates fehlschlägt.

Danksagungen

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