Znaczniki, styl, skrypt i aktualizowanie miniaplikacji

Język znaczników

Jak wspomnieliśmy wcześniej, miniaplikacje są pisane w dialektach HTML, a nie w zwykłym HTML-u. Jeśli kiedykolwiek miałeś(-aś) do czynienia z interpolacją tekstu i dyrektywami Vue.js, od razu poczujesz się jak u siebie. Podobne koncepcje istniały jednak już wcześniej w transformacjach XML (XSLT). Poniżej znajdziesz przykłady kodu z WXML WeChata, ale koncepcja jest taka sama w przypadku wszystkich platform miniaplikacji, czyli AXML Alipay, Swan Element Baidu, TTML ByteDance (mimo że narzędzia deweloperskie nazywają go Bxml) i HTML Quick App. Podobnie jak w przypadku Vue.js, podstawową koncepcją programowania miniaplikacji jest model-widok-model widoku (MVVM).

Wiązanie danych

Powiązanie danych odpowiada interpolacji tekstu w Vue.js.

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

Renderowanie listy

Renderowanie listy działa podobnie jak v-fordyrektywa Vue.js.

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

Renderowanie warunkowe

Renderowanie warunkowe działa podobnie jak dyrektywa v-ifVue.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",
  },
});

Szablony

Zamiast wymagać imperatywnego klonowania content szablonu HTML, szablony WXML można używać deklaratywnie za pomocą atrybutu is, który łączy się z definicją szablonu.

<!-- 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" },
  },
});

Styl

Stylizacja odbywa się za pomocą dialektów CSS. WeChat ma nazwę WXSS. W przypadku Alipay jest to ACSS, w przypadku Baidu – po prostu CSS, a w przypadku ByteDance – TTSS. Łączy je to, że rozszerzają CSS o elastyczne piksele. Podczas pisania zwykłego kodu CSS programiści muszą przekonwertować wszystkie jednostki pikseli, aby dostosować je do różnych ekranów urządzeń mobilnych o różnej szerokości i proporcjach pikseli. TTSS obsługuje jednostkę rpx jako warstwę bazową, co oznacza, że miniaplikacja przejmuje zadanie od dewelopera i konwertuje jednostki w jego imieniu na podstawie określonej szerokości ekranu 750rpx. Na przykład na telefonie Pixel 3a o szerokości ekranu 393px (i współczynniku pikseli urządzenia 2.75) elastyczne jednostki 200rpx po sprawdzeniu w narzędziach deweloperskich Chrome stają się jednostkami 104px na rzeczywistym urządzeniu (393 piksele / 750 rpx * 200 rpx ≈ 104 piksele). W Androidzie to samo pojęcie nosi nazwę piksel niezależny od gęstości.

Sprawdzanie widoku za pomocą Narzędzi deweloperskich w Chrome, w którym do określenia dopełnienia w pikselach elastycznych użyto wartości `200rpx`, pokazuje, że na urządzeniu Pixel 3a jest to w rzeczywistości `104px`.
Sprawdzanie rzeczywistego dopełnienia na urządzeniu Pixel 3a za pomocą Narzędzi deweloperskich w Chrome.
/* 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;
}

Komponenty (patrz dalej) nie używają modelu Shadow DOM, więc style zadeklarowane na stronie docierają do wszystkich komponentów. Typowa organizacja plików arkusza stylów polega na używaniu jednego głównego arkusza stylów dla stylów globalnych i osobnych arkuszy stylów dla poszczególnych stron, które są specyficzne dla każdej strony miniaplikacji. Style można importować za pomocą reguły @import, która działa jak reguła CSS @import. Podobnie jak w HTML-u style można też deklarować w wierszu, w tym interpolację tekstu dynamicznego (patrz wcześniej).

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

Tworzenie scenariusza

Miniaplikacje obsługują „bezpieczny podzbiór” JavaScriptu, który obejmuje obsługę modułów z użyciem różnych składni przypominających CommonJS lub RequireJS. Za pomocą funkcji eval() nie można wykonywać kodu JavaScript, a za pomocą funkcji new Function() nie można tworzyć funkcji. Kontekst wykonywania skryptów to V8 lub JavaScriptCore na urządzeniach oraz V8 lub NW.js w symulatorze. Kodowanie w składni ES6 lub nowszej jest zwykle możliwe, ponieważ konkretne Narzędzia deweloperskie automatycznie transpilują kod do ES5, jeśli docelową platformą jest system operacyjny ze starszą implementacją WebView (patrz dalej). Dokumentacja dostawców superaplikacji wyraźnie wspomina, że ich języki skryptowe nie powinny być mylone z JavaScriptem i są od niego odrębne. To stwierdzenie odnosi się jednak głównie do sposobu działania modułów, czyli do tego, że nie obsługują one jeszcze standardowych modułów ES.

Jak wspomnieliśmy wcześniej, koncepcja programowania miniaplikacji opiera się na wzorcu model-widok-model widoku (MVVM). Warstwa logiki i warstwa widoku działają w różnych wątkach, co oznacza, że interfejs użytkownika nie jest blokowany przez długotrwałe operacje. W terminologii internetowej skrypty można traktować jako działające w Web Workerze.

Język skryptowy WeChat to WXS, Alipay to SJS, a ByteDance to SJS. Baidu używa terminu JS, gdy odnosi się do własnych modeli. Te skrypty muszą być umieszczane za pomocą specjalnego rodzaju tagu, np. <wxs> w WeChat. Z kolei Quick App używa zwykłych tagów <script> i składni ES6 JS.

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

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

Moduły można też wczytywać za pomocą atrybutu src lub importować za pomocą require().

// /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);

Interfejs JavaScript Bridge API

Mostek JavaScript, który łączy miniaplikacje z systemem operacyjnym, umożliwia korzystanie z funkcji systemu operacyjnego (patrz Dostęp do zaawansowanych funkcji). Oferuje też wiele wygodnych metod. Aby uzyskać ogólne informacje, zapoznaj się z różnymi interfejsami API WeChat, Alipay, Baidu, ByteDanceQuick App.

Wykrywanie funkcji jest proste, ponieważ wszystkie platformy udostępniają metodę (dosłownie taką), której nazwa wydaje się inspirowana witryną caniuse.com. Na przykład tt.canIUse() firmy ByteDance umożliwia sprawdzanie obsługi interfejsów API, metod, parametrów, opcji, komponentów i atrybutów.canIUse()

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

Aktualizacje

Miniaplikacje nie mają standardowego mechanizmu aktualizacji (dyskusja na temat potencjalnej standaryzacji). Wszystkie platformy miniaplikacji mają system backendu, który umożliwia deweloperom przesyłanie nowych wersji miniaplikacji. Superaplikacja używa tego systemu backendu do sprawdzania i pobierania aktualizacji. Niektóre superaplikacje przeprowadzają aktualizacje w całości w tle, bez możliwości wpływania przez samą miniaplikację na proces aktualizacji. Inne superaplikacje dają większą kontrolę samym miniaplikacjom.

Przykładem zaawansowanego procesu jest mechanizm aktualizacji miniaplikacji w WeChat, który opisujemy szczegółowo w kolejnych akapitach. WeChat sprawdza dostępność aktualizacji w tych 2 przypadkach:

  1. WeChat będzie regularnie sprawdzać aktualizacje ostatnio używanych miniaplikacji, o ile WeChat jest uruchomiony. Jeśli aktualizacja zostanie znaleziona, zostanie pobrana i synchronicznie zastosowana przy następnym uruchomieniu miniaplikacji przez użytkownika. Uruchomienie miniaplikacji następuje, gdy nie była ona uruchomiona w momencie otwarcia przez użytkownika (WeChat zamyka miniaplikacje po 5 minutach działania w tle).
  2. WeChat sprawdza też dostępność aktualizacji, gdy miniaplikacja jest uruchamiana po raz pierwszy. W przypadku miniaplikacji, których użytkownik nie otwierał od dłuższego czasu, aktualizacja jest sprawdzana i pobierana synchronicznie. Podczas pobierania aktualizacji użytkownik musi czekać. Po zakończeniu pobierania aktualizacja zostanie zastosowana i otworzy się miniaplikacja. Jeśli pobieranie się nie powiedzie, np. z powodu słabego połączenia sieciowego, miniaplikacja i tak się otworzy. W przypadku miniaplikacji, które użytkownik ostatnio otworzył, wszelkie potencjalne aktualizacje są pobierane asynchronicznie w tle i zostaną zastosowane przy następnym uruchomieniu miniaplikacji.

Miniaplikacje mogą włączyć wcześniejsze aktualizacje za pomocą interfejsu UpdateManager API. Umożliwia ona:

  • Powiadamia miniaplikację o sprawdzeniu dostępności aktualizacji. (onCheckForUpdate)
  • Powiadamia miniaplikację o pobraniu i dostępności aktualizacji. (onUpdateReady)
  • Powiadamia miniaplikację, gdy nie można pobrać aktualizacji. (onUpdateFailed)
  • Umożliwia wymuszenie instalacji dostępnej aktualizacji miniaplikacji, co spowoduje jej ponowne uruchomienie.applyUpdate

WeChat udostępnia też deweloperom miniaplikacji dodatkowe opcje dostosowywania aktualizacji w systemie backendowym:1. Jedna z opcji pozwala deweloperom zrezygnować z synchronizowanych aktualizacji w przypadku użytkowników, którzy mają już zainstalowaną określoną minimalną wersję miniaplikacji, i zamiast tego wymusić aktualizacje asynchroniczne. 2. Inna opcja umożliwia deweloperom ustawienie minimalnej wymaganej wersji miniaplikacji. Spowoduje to, że asynchroniczne aktualizacje z wersji niższej niż minimalna wymagana wersja będą wymuszać ponowne wczytanie miniaplikacji po zastosowaniu aktualizacji. Zablokuje też otwarcie starszej wersji miniaplikacji, jeśli pobieranie aktualizacji się nie powiedzie.

Podziękowania

Ten artykuł został sprawdzony przez Joe Medleya, Kayce Basques, Milicę Mihajliję, Alana Kenta i Keitha Gu.