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

Markup languages

Wie bereits erwähnt, werden Mini-Apps mit HTML-Dialekten geschrieben statt mit reinem HTML-Code. Wenn Sie sich schon einmal mit Vue.js-Textinterpolation und -Anweisungen beschäftigt haben, werden Sie sich sofort zu Hause fühlen, aber ähnliche Konzepte gab es bereits lange in XML Transformations (XSLT). Unten sehen Sie Codebeispiele der 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 die Entwicklertools Bxml nennen) und HTML von Quick App. Genau wie bei Vue.js ist das zugrunde liegende Programmierkonzept für Mini-Apps model-view-viewmodel (MVVM).

Datenbindung

Die Datenbindung entspricht der Textinterpolation von Vue.js.

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

Listen-Rendering

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

<!-- 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 die content einer HTML-Vorlage zu klonen, 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 CSS-Dialekten. WeChat heißt WXSS. Bei Alipay heißt deren Dialekt ACSS, das einfache CSS von Baidu, und bei ByteDance wird ihr Dialekt als TTSS bezeichnet. Sie haben jedoch gemeinsam, dass sie CSS um responsive Pixel erweitern. Beim Schreiben von regulärem CSS-Code müssen Entwickler alle Pixeleinheiten so konvertieren, dass sie sich an verschiedene Mobilgerätebildschirme mit unterschiedlichen Breiten und Pixelverhältnissen anpassen. TTSS unterstützt die rpx-Einheit als zugrunde liegende Ebene. Das bedeutet, dass die Mini-App den Job vom Entwickler übernimmt und die Einheiten in ihrem Namen konvertiert, basierend auf einer festgelegten Bildschirmbreite von 750rpx. Auf einem Pixel 3a-Smartphone mit einer Bildschirmbreite von 393px (und einem Pixelverhältnis auf dem Gerät von 2.75) wird der responsive 200rpx beispielsweise auf dem echten Gerät zu 104px, wenn er mit den Chrome-Entwicklertools geprüft wird (393 px ÷ 750 rpx × 200 rpx Δ 104 px). In Android wird das gleiche Konzept als dichteunabhängige Pixel bezeichnet.

Die Überprüfung einer Ansicht mit den Chrome-Entwicklertools, deren responsives Pixel-Padding auf einem Pixel 3a-Gerät mit „200rpx“ angegeben wurde, zeigt, dass es sich tatsächlich um „104 px“ handelt.
Mit den Chrome-Entwicklertools wird der tatsächliche Abstand auf einem Pixel 3a-Gerät geprüft.
/* 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 später) kein Schatten-DOM verwenden, erstrecken sich die auf einer Seite deklarierten Stile in allen Komponenten. Die übliche Stylesheet-Dateiorganisation besteht darin, ein Stamm-Stylesheet für globale Stile und individuelle Stylesheets für jede Seite der Mini-App zu verwenden. 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 vorher).

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

Skripting

Mini-Apps unterstützen eine „sichere JavaScript-Teilmenge“, die auch Module mit unterschiedlichen Syntaxen unterstützt, 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. In der Regel ist die Codierung mit ES6 oder neuerer Syntax 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 Skriptsprachen nicht mit JavaScript verwechselt werden dürfen und sich von JavaScript unterscheiden. Diese Anweisung bezieht sich jedoch hauptsächlich auf die Funktionsweise der Module, d. h., sie unterstützen noch keine standardmäßigen ES-Module.

Wie bereits erwähnt, ist das Konzept der Minianwendung-Programmierung model-view-viewmodel (MVVM). Die Logikebene und die Ansichtsebene laufen in verschiedenen Threads, sodass die Benutzeroberfläche nicht durch lang andauernde Vorgänge blockiert wird. Mit der Webversion können Sie sich Skripts vorstellen, die in einem Web Worker ausgeführt werden.

Die Skriptsprache von WeChat heißt WXS, SJS von Alipay, ebenso wie SJS von ByteDance. Baidu spricht bei Verweisen auf JS. Diese Skripts müssen mithilfe einer speziellen Art von Tag eingefügt werden, z. B. <wxs> in WeChat. Im Gegensatz dazu verwendet Quick App 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). Es bietet auch eine Reihe von praktischen Methoden. Sie können sich einen Überblick über die verschiedenen APIs von WeChat, Alipay, Baidu, ByteDance und Quick App ansehen.

Die Funktionserkennung ist einfach, da alle Plattformen eine canIUse()-Methode bereitstellen, deren Name von der Website caniuse.com inspiriert zu sein scheint. So ermöglicht beispielsweise tt.canIUse() von ByteDance Support-Prüfungen für APIs, Methoden, Parameter, Optionen, Komponenten und Attribute.

// 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 mögliche Standardisierung). Alle Mini-App-Plattformen haben ein Back-End-System, mit dem Entwickler von Mini-Apps neue Versionen ihrer Mini-Apps hochladen können. Eine Super-App sucht dann mithilfe dieses Back-End-Systems nach Updates und lädt diese herunter. Einige Super-Apps führen Updates vollständig im Hintergrund aus, ohne dass die Mini-App selbst den Updatefluss beeinflussen kann. Andere Super-Apps bieten mehr Kontrolle über die Mini-Apps selbst.

Als Beispiel für einen anspruchsvollen Prozess wird in den folgenden Abschnitten der Update-Mechanismus von WeChat für Mini-Apps genauer beschrieben. WeChat sucht in den folgenden zwei Szenarien nach verfügbaren Updates:

  1. Solange WeChat ausgeführt wird, sucht WeChat regelmäßig nach Updates für kürzlich verwendete Mini-Apps. Wenn ein Update gefunden wird, wird das Update heruntergeladen und beim nächsten Kaltstart durch den Nutzer synchron angewendet. Der Kaltstart einer Mini-App tritt auf, wenn die Mini-App nicht ausgeführt wurde, als der Nutzer sie geöffnet hat. WeChat erzwingt das Schließen von Mini-Apps, nachdem sie fünf Minuten im Hintergrund ausgeführt wurde.
  2. WeChat sucht auch nach Updates, wenn eine Mini-App neu 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. Sobald der Download abgeschlossen ist, wird das Update installiert und die Mini-App 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 neu startet.

Mini-Apps können frühere Updates über die UpdateManager API aktivieren. Es bietet folgende Funktionen:

  • Benachrichtigt die Mini-App, wenn eine Suche nach Updates durchgeführt 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, die Installation eines verfügbaren Updates zu erzwingen, wodurch die App neu gestartet wird. (applyUpdate)

WeChat bietet in seinem Back-End-System außerdem zusätzliche Anpassungsoptionen für Entwickler von Mini-Apps: 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 eine asynchrone Aktualisierung erzwingen. 2. Mit einer anderen Option können Entwickler eine Mindestversion ihrer Mini-App festlegen. Dadurch werden asynchrone Updates von einer Version, die niedriger als die Mindestversion ist, erzwungen, um ein erneutes Laden der Mini-App nach der Anwendung des Updates zu erzwingen. 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 überprüft.