Đánh dấu, định kiểu, viết tập lệnh và cập nhật ứng dụng nhỏ

Ngôn ngữ đánh dấu

Như đã trình bày trước đó, thay vì sử dụng HTML thuần tuý, các ứng dụng thu nhỏ được viết bằng các phương ngữ của HTML. Nếu đã từng xử lý tính năng nội suy văn bản và chỉ thị Vue.js, bạn sẽ cảm thấy quen thuộc ngay lập tức. Tuy nhiên, các khái niệm tương tự đã xuất hiện từ trước đó trong Biến đổi XML (XSLT). Dưới đây, bạn có thể xem các mẫu mã từ WXML của WeChat, nhưng khái niệm này giống nhau đối với tất cả các nền tảng ứng dụng thu nhỏ, cụ thể là AXML của Alipay, Swan Element của Baidu, TTML của ByteDance (mặc dù DevTools gọi là Bxml) và HTML của Quick App. Giống như Vue.js, khái niệm lập trình ứng dụng nhỏ cơ bản là model-view-viewmodel (MVVM).

Liên kết dữ liệu

Liên kết dữ liệu tương ứng với nội suy văn bản của Vue.js.

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

Kết xuất danh sách

Quá trình hiển thị danh sách hoạt động giống như chỉ thị v-for của Vue.js.

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

Kết xuất có điều kiện

Hiển thị có điều kiện hoạt động giống như chỉ thị v-if của 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",
  },
});

Mẫu

Thay vì yêu cầu sao chép bắt buộc content của một mẫu HTML, bạn có thể sử dụng mẫu WXML một cách khai báo thông qua thuộc tính is liên kết đến một định nghĩa mẫu.

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

Định kiểu

Việc tạo kiểu diễn ra bằng các phương ngữ của CSS. WeChat có tên là WXSS. Đối với Alipay, CSS của họ được gọi là ACSS, CSS của Baidu chỉ đơn giản là CSS và đối với ByteDance, phương ngữ của họ được gọi là TTSS. Điểm chung của các đơn vị này là chúng mở rộng CSS bằng các pixel thích ứng. Khi viết CSS thông thường, nhà phát triển cần chuyển đổi tất cả các đơn vị pixel để thích ứng với các màn hình thiết bị di động có chiều rộng và tỷ lệ pixel khác nhau. TTSS hỗ trợ đơn vị rpx làm lớp cơ bản, tức là ứng dụng thu nhỏ sẽ đảm nhận công việc của nhà phát triển và chuyển đổi các đơn vị thay cho họ, dựa trên chiều rộng màn hình được chỉ định là 750rpx. Ví dụ: trên điện thoại Pixel 3a có chiều rộng màn hình là 393px (và tỷ lệ pixel trên thiết bị là 2.75), 200rpx thích ứng sẽ trở thành 104px trên thiết bị thực khi được kiểm tra bằng Công cụ cho nhà phát triển của Chrome (393px / 750rpx * 200rpx ≈ 104px). Trong Android, khái niệm tương tự được gọi là pixel không phụ thuộc vào mật độ.

Việc kiểm tra một khung hiển thị bằng Công cụ cho nhà phát triển của Chrome (trong đó khoảng đệm pixel thích ứng được chỉ định bằng &quot;200rpx&quot;) cho thấy rằng khung hiển thị đó thực sự là &quot;104px&quot; trên thiết bị Pixel 3a.
Kiểm tra khoảng đệm thực tế trên thiết bị Pixel 3a bằng Công cụ của Chrome cho nhà phát triển.
/* 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;
}

Vì các thành phần (xem sau) không sử dụng DOM bóng, nên các kiểu được khai báo trên một trang sẽ tác động đến tất cả các thành phần. Cách tổ chức tệp biểu định kiểu phổ biến là có một biểu định kiểu gốc cho các kiểu chung và biểu định kiểu riêng cho từng trang dành riêng cho mỗi trang của ứng dụng thu nhỏ. Bạn có thể nhập các kiểu bằng quy tắc @import hoạt động giống như quy tắc @import CSS. Giống như trong HTML, bạn cũng có thể khai báo các kiểu nội tuyến, bao gồm cả nội suy văn bản động (xem trước).

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

Lên nội dung

Ứng dụng thu nhỏ hỗ trợ "tập hợp con an toàn" của JavaScript, bao gồm cả việc hỗ trợ các mô-đun bằng cách sử dụng nhiều cú pháp gợi nhớ đến CommonJS hoặc RequireJS. Không thể thực thi mã JavaScript thông qua eval() và không thể tạo hàm bằng new Function(). Ngữ cảnh thực thi tập lệnh là V8 hoặc JavaScriptCore trên các thiết bị và V8 hoặc NW.js trong trình mô phỏng. Bạn thường có thể viết mã bằng cú pháp ES6 trở lên, vì DevTools cụ thể sẽ tự động chuyển đổi mã nguồn thành ES5 nếu mục tiêu bản dựng là một hệ điều hành có chế độ triển khai WebView cũ (xem sau). Tài liệu của các nhà cung cấp siêu ứng dụng đề cập rõ ràng rằng ngôn ngữ kịch bản của họ không được nhầm lẫn và khác biệt với JavaScript. Tuy nhiên, câu lệnh này chủ yếu chỉ đề cập đến cách các mô-đun hoạt động, tức là các mô-đun này chưa hỗ trợ Mô-đun ES tiêu chuẩn.

Như đã đề cập trước đó, khái niệm lập trình ứng dụng thu nhỏ là model-view-viewmodel (MVVM). Lớp logic và lớp hiển thị chạy trên các luồng khác nhau, tức là giao diện người dùng không bị chặn bởi các thao tác chạy trong thời gian dài. Theo thuật ngữ web, bạn có thể coi các tập lệnh đang chạy trong một Web Worker.

Ngôn ngữ kịch bản của WeChat được gọi là WXS, SJS của Alipay, SJS của ByteDance. Baidu đề cập đến JS khi tham chiếu đến JS của họ. Bạn cần thêm các tập lệnh này bằng một loại thẻ đặc biệt, chẳng hạn như <wxs> trong WeChat. Ngược lại, Quick App sử dụng các thẻ <script> thông thường và cú pháp JS ES6.

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

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

Bạn cũng có thể tải các mô-đun thông qua thuộc tính src hoặc nhập thông qua 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 cầu nối JavaScript

Cầu nối JavaScript kết nối các ứng dụng nhỏ với hệ điều hành, giúp bạn có thể sử dụng các chức năng của hệ điều hành (xem phần Quyền truy cập vào các tính năng mạnh mẽ). Thư viện này cũng cung cấp một số phương thức tiện lợi. Để biết thông tin tổng quan, bạn có thể xem các API khác nhau của WeChat, Alipay, Baidu, ByteDanceQuick App.

Việc phát hiện tính năng rất đơn giản, vì tất cả các nền tảng đều cung cấp một phương thức canIUse() (theo đúng nghĩa đen là được gọi như vậy) có tên lấy cảm hứng từ trang web caniuse.com. Ví dụ: tt.canIUse() của ByteDance cho phép kiểm tra khả năng hỗ trợ đối với các API, phương thức, tham số, lựa chọn, thành phần và thuộc tính.

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

Nội dung cập nhật

Các ứng dụng thu nhỏ không có cơ chế cập nhật tiêu chuẩn (thảo luận về khả năng tiêu chuẩn hoá). Tất cả các nền tảng ứng dụng nhỏ đều có một hệ thống phụ trợ, cho phép nhà phát triển ứng dụng nhỏ tải các phiên bản mới của ứng dụng nhỏ lên. Sau đó, một siêu ứng dụng sẽ sử dụng hệ thống phụ trợ đó để kiểm tra và tải các bản cập nhật xuống. Một số siêu ứng dụng thực hiện hoàn toàn các bản cập nhật ở chế độ nền mà không có cách nào để chính ứng dụng nhỏ ảnh hưởng đến quy trình cập nhật. Các siêu ứng dụng khác cho phép các ứng dụng nhỏ tự kiểm soát nhiều hơn.

Ví dụ về một quy trình phức tạp, các đoạn sau đây mô tả chi tiết hơn về cơ chế cập nhật ứng dụng của WeChat đối với ứng dụng thu nhỏ. WeChat kiểm tra xem có bản cập nhật hay không trong 2 trường hợp sau:

  1. WeChat sẽ thường xuyên kiểm tra các bản cập nhật của những ứng dụng nhỏ được dùng gần đây, miễn là WeChat đang chạy. Nếu tìm thấy bản cập nhật, bản cập nhật sẽ được tải xuống và áp dụng đồng bộ vào lần tiếp theo người dùng khởi động nguội ứng dụng nhỏ. Quá trình khởi động nguội ứng dụng nhỏ xảy ra khi ứng dụng nhỏ hiện không chạy khi người dùng mở ứng dụng (WeChat buộc đóng ứng dụng nhỏ sau 5 phút chạy trong nền).
  2. WeChat cũng kiểm tra các bản cập nhật khi một ứng dụng thu nhỏ được khởi động lại từ đầu. Đối với những ứng dụng nhỏ mà người dùng chưa mở trong một thời gian dài, bản cập nhật sẽ được kiểm tra và tải xuống đồng bộ. Trong khi bản cập nhật đang tải xuống, người dùng phải chờ. Sau khi tải xong, bản cập nhật sẽ được áp dụng và ứng dụng nhỏ sẽ mở ra. Nếu quá trình tải xuống không thành công (ví dụ: do kết nối mạng kém), thì ứng dụng nhỏ vẫn sẽ mở. Đối với những ứng dụng nhỏ mà người dùng đã mở gần đây, mọi bản cập nhật tiềm năng sẽ được tải xuống không đồng bộ ở chế độ nền và sẽ được áp dụng vào lần tiếp theo người dùng khởi động nguội ứng dụng nhỏ.

Các ứng dụng nhỏ có thể chọn nhận các bản cập nhật trước đó bằng cách sử dụng API UpdateManager. Thẻ này cung cấp những chức năng sau:

  • Thông báo cho ứng dụng nhỏ khi có yêu cầu kiểm tra bản cập nhật. (onCheckForUpdate)
  • Thông báo cho ứng dụng thu nhỏ khi có bản cập nhật đã tải xuống. (onUpdateReady)
  • Thông báo cho ứng dụng nhỏ khi không tải được bản cập nhật. (onUpdateFailed)
  • Cho phép ứng dụng nhỏ buộc cài đặt một bản cập nhật hiện có, thao tác này sẽ khởi động lại ứng dụng. (applyUpdate)

WeChat cũng cung cấp các lựa chọn tuỳ chỉnh nội dung cập nhật bổ sung cho nhà phát triển ứng dụng thu nhỏ trong hệ thống phụ trợ của mình: 1. Một lựa chọn cho phép nhà phát triển chọn không nhận bản cập nhật đồng bộ cho những người dùng đã cài đặt một phiên bản tối thiểu nhất định của ứng dụng thu nhỏ, đồng thời buộc các bản cập nhật phải không đồng bộ. 2. Một lựa chọn khác cho phép nhà phát triển đặt phiên bản tối thiểu bắt buộc cho ứng dụng nhỏ của họ. Điều này sẽ khiến các bản cập nhật không đồng bộ từ phiên bản thấp hơn phiên bản tối thiểu bắt buộc buộc tải lại ứng dụng nhỏ sau khi áp dụng bản cập nhật. Thao tác này cũng sẽ chặn việc mở phiên bản cũ của ứng dụng nhỏ nếu quá trình tải bản cập nhật xuống không thành công.

Lời cảm ơn

Bài viết này được Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent và Keith Gu xem xét.