Markup languages
Como descrito anteriormente, em vez de HTML simples, os miniapps são escritos com dialetos de HTML. Se você já trabalhou com interpolação de texto e diretivas Vue.js, vai se sentir em casa imediatamente. No entanto, conceitos semelhantes já existiam muito antes disso em transformações XML (XSLT). Confira abaixo exemplos de código do WXML do WeChat, mas o conceito é o mesmo para todas as plataformas de mini apps, ou seja, o AXML do Alipay, o Swan Element do Baidu, o TTML do ByteDance (apesar de o DevTools chamar de Bxml) e o HTML do Quick App. Assim como no Vue.js, o conceito de programação de mini app subjacente é o model-view-viewmodel (MVVM).
Vinculação de dados
A vinculação de dados corresponde à interpolação de texto do Vue.js.
<!-- wxml -->
<view>{{message}}</view>
// page.js
Page({
data: {
message: "Hello World!",
},
});
Renderização de lista
A renderização de lista funciona como a diretiva v-for do Vue.js.
<!-- wxml -->
<view wx:for="{{array}}">{{item}}</view>
// page.js
Page({
data: {
array: [1, 2, 3, 4, 5],
},
});
Renderização condicional
A renderização condicional funciona como a diretiva v-if do 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",
},
});
Modelos
Em vez de exigir a clonagem imperativa do content de um modelo HTML, os modelos WXML podem ser usados de forma declarativa pelo atributo is, que vincula a uma definição de modelo.
<!-- 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" },
},
});
Estilo
A estilização acontece com dialetos de CSS. O do WeChat se chama
WXSS.
No Alipay, ele é chamado de ACSS, no Baidu, de CSS e, no ByteDance, de TTSS.
O que eles têm em comum é que estendem o CSS com pixels responsivos. Ao escrever CSS normal, os desenvolvedores precisam converter todas as unidades de pixel para se adaptar a diferentes telas de dispositivos móveis com larguras e proporções de pixels diferentes. O TTSS oferece suporte à unidade rpx como camada subjacente. Isso significa que o mini app assume o trabalho do desenvolvedor e converte as unidades em nome dele, com base em uma largura de tela especificada de 750rpx. Por exemplo, em um smartphone Pixel 3a com uma largura de tela de 393px (e uma proporção de pixels do dispositivo de 2.75), 200rpx responsivos se tornam 104px no dispositivo real quando inspecionados com o Chrome DevTools (393 px / 750 rpx * 200 rpx ≈ 104 px). No Android, o mesmo conceito é chamado de pixel independente de densidade.
/* 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;
}
Como os componentes (consulte mais adiante) não usam o Shadow DOM, os estilos declarados em uma página alcançam
todos os componentes. A organização comum de arquivos de folha de estilo é ter uma folha de estilo raiz para estilos globais e folhas de estilo individuais por página específicas para cada página do mini app. Os estilos podem ser importados com uma regra @import que se comporta como a regra at @import do CSS. Assim como no HTML, os estilos também podem ser declarados inline, incluindo a interpolação de texto dinâmico (consulte antes).
<view style="color:{{color}};" />
Roteiro
Os miniapps oferecem suporte a um "subconjunto seguro" de JavaScript que inclui suporte a módulos usando várias sintaxes que lembram CommonJS ou RequireJS.
O código JavaScript não pode ser executado via eval(), e nenhuma função pode ser criada com new Function(). O contexto de execução de script é V8 ou JavaScriptCore em dispositivos e V8 ou NW.js no simulador. Normalmente, é possível programar com ES6 ou sintaxe mais recente,
já que o DevTools específico transpila automaticamente o código para ES5 se o destino do build for um
sistema operacional com uma implementação mais antiga do WebView (consulte mais adiante). A documentação dos provedores de superapps menciona explicitamente que as linguagens de programação deles não devem ser confundidas com o JavaScript e são diferentes dele. No entanto, essa declaração se refere principalmente à forma como os módulos funcionam, ou seja, eles ainda não são compatíveis com os módulos ES padrão.
Como mencionado antes, o conceito de programação de miniapp é o model-view-viewmodel (MVVM). A camada de lógica e a camada de visualização são executadas em linhas de execução diferentes, o que significa que a interface do usuário não é bloqueada por operações de longa duração. Em termos da Web, pense em scripts executados em um Web Worker.
A linguagem de programação do WeChat é chamada de
WXS, a do Alipay de
SJS e a da ByteDance também de
SJS.
O Baidu fala de JS ao se referir ao
próprio. Esses scripts precisam ser incluídos usando um tipo especial de tag, por exemplo, <wxs> no WeChat. Em contraste, o Quick App usa tags <script> regulares e a sintaxe JS do ES6.
<wxs module="m1">
var msg = "hello world";
module.exports.message = msg;
</wxs>
<view>{{m1.message}}</view>
Os módulos também podem ser carregados usando um atributo src ou importados com 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);
API de ponte JavaScript
A ponte JavaScript que conecta miniapps ao sistema operacional permite usar recursos do SO (consulte Acesso a recursos avançados. Ele também oferece vários métodos de conveniência. Para uma visão geral, confira as diferentes APIs do WeChat, Alipay, Baidu, ByteDance e Quick App.
A detecção de recursos é simples, já que todas as plataformas fornecem um método canIUse() (literalmente chamado assim) cujo nome parece inspirado no site caniuse.com. Por exemplo, o tt.canIUse() da ByteDance permite verificações de suporte para APIs, métodos, parâmetros, opções, componentes e atributos.
// Testing if the `<swiper>` component is supported.
tt.canIUse("swiper");
// Testing if a particular field is supported.
tt.canIUse("request.success.data");
Atualizações
Os miniapps não têm um mecanismo de atualização padronizado (discussão sobre possível padronização). Todas as plataformas de mini apps têm um sistema de back-end, que permite que os desenvolvedores façam upload de novas versões dos mini apps. Um superapp usa esse sistema de back-end para verificar e baixar atualizações. Alguns superapps realizam atualizações totalmente em segundo plano, sem que o mini app possa influenciar o fluxo de atualização. Outros superapps dão mais controle aos miniapps.
Como exemplo de um processo sofisticado, os parágrafos a seguir descrevem com mais detalhes o mecanismo de atualização do WeChat para miniapps. O WeChat verifica se há atualizações disponíveis nos dois cenários a seguir:
- O WeChat verifica regularmente se há atualizações dos miniprogramas usados recentemente enquanto o app está em execução. Se uma atualização for encontrada, ela será baixada e aplicada de forma síncrona na próxima vez que o usuário fizer uma inicialização a frio do mini app. A inicialização a frio de um mini app ocorre quando ele não estava em execução quando o usuário o abriu. O WeChat fecha à força os mini apps depois de ficarem em segundo plano por 5 minutos.
- O WeChat também verifica se há atualizações quando um miniapp é iniciado a frio. Para mini apps que o usuário não abre há muito tempo, a atualização é verificada e baixada de forma síncrona. Enquanto o download da atualização é feito, o usuário precisa esperar. Quando o download terminar, a atualização será aplicada e o mini app será aberto. Se o download falhar, por exemplo, devido a uma conectividade de rede ruim, o mini app será aberto mesmo assim. Para mini apps que o usuário abriu recentemente, qualquer atualização em potencial é baixada de forma assíncrona em segundo plano e será aplicada na próxima vez que o usuário iniciar o mini app.
Os mini apps podem ativar atualizações antecipadas usando a API UpdateManager. Ele oferece as seguintes funcionalidades:
- Notifica o mini app quando uma verificação de atualizações é feita.
(
onCheckForUpdate) - Notifica o mini app quando uma atualização é baixada e está disponível.
(
onUpdateReady) - Notifica o mini app quando não é possível baixar uma atualização.
(
onUpdateFailed) - Permite que o mini app force a instalação de uma atualização disponível, o que reinicia o app.
(
applyUpdate)
O WeChat também oferece outras opções de personalização de atualização para desenvolvedores de miniapps no sistema de back-end: 1. Uma opção permite que os desenvolvedores desativem as atualizações síncronas para usuários que já têm uma determinada versão mínima do mini app instalada e, em vez disso, forçam as atualizações a serem assíncronas. 2. Outra opção permite que os desenvolvedores definam uma versão mínima necessária do mini app. Isso fará com que atualizações assíncronas de uma versão inferior à mínima necessária forcem a recarga do mini app após a aplicação da atualização. Ele também impede a abertura de uma versão mais antiga do mini app se o download da atualização falhar.
Agradecimentos
Este artigo foi revisado por Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent, e Keith Gu.