มาร์กอัปมินิแอป การจัดรูปแบบ การเขียนสคริปต์ และการอัปเดต

Markup languages

ตามที่ระบุไว้ก่อนหน้านี้ มินิแอปเขียนด้วยรูปแบบต่างๆ ของ HTML ไม่ใช่ HTML ธรรมดา หากคุณเคยจัดการกับคำสั่งและการประมาณค่าในช่วงข้อความ Vue.js คุณจะรู้สึกเหมือนอยู่บ้านทันที แต่ก็มีแนวคิดที่คล้ายกันเกิดขึ้นในการแปลง XML (XSLT) ด้านล่างนี้คือตัวอย่างโค้ดจาก WXML ของ WeChat แต่แนวคิดนี้เหมือนกันสำหรับแพลตฟอร์มมินิแอปทั้งหมด ได้แก่ AXML ของ Alipay, Swan Element ของ Baidu, TTML ของ ByteDance (แม้ว่าเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะเรียกว่า Bxml) และ HTML ของ Quick App เช่นเดียวกับ Vue.js แนวคิดการเขียนโปรแกรมแอปขนาดเล็กพื้นฐานคือ model-view-viewmodel (MVVM)

การเชื่อมโยงข้อมูล

การเชื่อมโยงข้อมูลสอดคล้องกับการแทรกข้อความของ Vue.js

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

การแสดงรายการ

การแสดงรายการทำงานเหมือนกับคำสั่ง v-for ของ Vue.js

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

การแสดงผลแบบมีเงื่อนไข

การแสดงผลแบบมีเงื่อนไขจะทำงานเหมือนกับคำสั่ง v-if ของ 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",
  },
});

เทมเพลต

แทนที่จะต้องใช้คำสั่งการโคลน content ของเทมเพลต HTML คุณสามารถใช้เทมเพลต WXML แบบประกาศผ่านแอตทริบิวต์ is ที่ลิงก์กับคําจํากัดความของเทมเพลตได้

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

การจัดรูปแบบ

การจัดรูปแบบจะเกิดขึ้นกับภาษาถิ่นของ CSS ของ WeChat จะชื่อ WXSS สำหรับ Alipay เรียกว่า ACSS, Baidu เรียกว่า CSS และ ByteDance เรียกว่า TTSS สิ่งที่เหมือนกันคือทั้ง 2 รูปแบบจะขยาย CSS ด้วยพิกเซลที่ปรับเปลี่ยนตามพื้นที่โฆษณา เมื่อเขียน CSS ปกติ นักพัฒนาซอฟต์แวร์ต้องแปลงหน่วยพิกเซลทั้งหมดให้เหมาะกับหน้าจออุปกรณ์เคลื่อนที่ที่แตกต่างกันซึ่งมีความกว้างและอัตราส่วนพิกเซลต่างกัน TTSS รองรับหน่วย rpx เป็นเลเยอร์พื้นฐาน ซึ่งหมายความว่ามินิแอปจะรับหน้าที่จากนักพัฒนาแอปและแปลงหน่วยในนามของนักพัฒนาแอป โดยอิงตามความกว้างหน้าจอที่ระบุของ 750rpx ตัวอย่างเช่น ในโทรศัพท์ Pixel 3a ที่มีความกว้างหน้าจอ 393px (และอัตราส่วนพิกเซลของอุปกรณ์ 2.75) 200rpx แบบปรับเปลี่ยนขนาดได้จะกลายเป็น 104px ในอุปกรณ์จริงเมื่อตรวจสอบด้วยเครื่องมือสำหรับนักพัฒนาเว็บใน Chrome (393 พิกเซล / 750rpx * 200rpx ≈ 104 พิกเซล) ใน Android แนวคิดเดียวกันนี้เรียกว่าพิกเซลที่ไม่ขึ้นกับความหนาแน่น

การตรวจสอบมุมมองด้วยเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์ของ Chrome ซึ่งระบุการเว้นวรรคพิกเซลแบบตอบสนองด้วย `200rpx` พบว่าค่าจริงคือ `104px` ในอุปกรณ์ Pixel 3a
การตรวจสอบระยะขอบจริงในอุปกรณ์ Pixel 3a ด้วยเครื่องมือสำหรับนักพัฒนาเว็บใน 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;
}

เนื่องจากคอมโพเนนต์ (ดูภายหลัง) ไม่ได้ใช้ Shadow DOM ดังนั้นสไตล์ที่ประกาศเมื่อเข้าถึงหน้าเว็บลงในคอมโพเนนต์ทั้งหมด การจัดระเบียบไฟล์สไตล์ชีตทั่วไปคือให้มีสไตล์ชีตรูท 1 รายการสำหรับรูปแบบส่วนกลาง และสไตล์ชีตแต่ละหน้าสำหรับแต่ละหน้าของแอปมินิ คุณสามารถนำเข้ารูปแบบด้วยกฎ @import ที่ทํางานเหมือนกฎ at ของ @import CSS เช่นเดียวกับใน HTML คุณยังประกาศรูปแบบในบรรทัดได้ รวมถึงการแทรกข้อความแบบไดนามิก (ดูก่อนหน้านี้)

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

การเขียนสคริปต์

มินิแอปรองรับ "ชุดย่อยที่ปลอดภัย" ของ JavaScript ที่มีการรองรับโมดูลที่ใช้ไวยากรณ์ที่หลากหลายซึ่งย้ำเตือนถึง CommonJS หรือ RequireJS โค้ด JavaScript ไม่สามารถเรียกใช้ได้ผ่าน eval() และไม่สามารถสร้างฟังก์ชันด้วย new Function() บริบทการเรียกใช้สคริปต์คือ V8 หรือ JavaScriptCore ในอุปกรณ์ และ V8 หรือ NW.js ในเครื่องจำลอง โดยทั่วไปแล้ว คุณเขียนโค้ดด้วยไวยากรณ์ ES6 หรือใหม่กว่าได้ เนื่องจากเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะเปลี่ยนรูปแบบโค้ดเป็น ES5 โดยอัตโนมัติหากเป้าหมายการสร้างเป็นระบบปฏิบัติการที่มีการใช้งาน WebView เวอร์ชันเก่า (ดูส่วนถัดไป) เอกสารประกอบของผู้ให้บริการแอปอัจฉริยะระบุไว้อย่างชัดเจนว่าภาษาสคริปต์ของผู้ให้บริการนั้นแตกต่างจาก JavaScript อย่างไรก็ตาม ข้อความนี้ส่วนใหญ่หมายถึงวิธีการทำงานของข้อบังคับ ซึ่งก็คือข้อบังคับยังไม่รองรับข้อบังคับ ES มาตรฐาน

ดังที่ได้กล่าวไปก่อนหน้านี้ แนวคิดการเขียนโปรแกรมสำหรับแอปขนาดเล็กคือ model-view-viewmodel (MVVM) เลเยอร์ตรรกะและเลเยอร์มุมมองจะทำงานในเทรดที่ต่างกัน ซึ่งหมายความว่าอินเทอร์เฟซผู้ใช้จะไม่ถูกบล็อกจากการดำเนินการที่ใช้เวลานาน ในแง่ของเว็บ คุณอาจนึกถึงสคริปต์ที่ทำงานใน Web Worker

ภาษาสคริปต์ของ WeChat เรียกว่า WXS, ของ Alipay เรียกว่า SJS และของ ByteDance เรียกว่า SJS Baidu พูดถึง JS เมื่อพูดถึง บุคคลดังกล่าว สคริปต์เหล่านี้ต้องรวมอยู่โดยใช้แท็กประเภทพิเศษ เช่น <wxs> ใน WeChat ในทางตรงกันข้าม Quick App จะใช้แท็ก <script> ปกติและไวยากรณ์ JS ของ ES6

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

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

นอกจากนี้ คุณยังโหลดโมดูลผ่านแอตทริบิวต์ src หรือนําเข้าผ่าน 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 บริดจ์ JavaScript

บริดจ์ JavaScript ที่เชื่อมต่อมินิแอปกับระบบปฏิบัติการช่วยให้คุณใช้ความสามารถของระบบปฏิบัติการได้ (ดูการเข้าถึงฟีเจอร์ที่มีประสิทธิภาพ) รวมถึงมีวิธีการต่างๆ ที่สะดวกมากมาย ดูภาพรวมได้ที่ API ต่างๆ ของ WeChat, Alipay, Baidu, ByteDance และ Quick App

การตรวจหาฟีเจอร์นั้นทําได้ง่ายๆ เนื่องจากแพลตฟอร์มทั้งหมดมีวิธี (เรียกชื่อแบบนี้จริงๆ) canIUse() ซึ่งชื่อดูเหมือนว่าได้รับแรงบันดาลใจมาจากเว็บไซต์ caniuse.com ตัวอย่างเช่น tt.canIUse() ของ ByteDance อนุญาตให้ตรวจสอบการรองรับ API, เมธอด, พารามิเตอร์, ตัวเลือก, คอมโพเนนต์ และแอตทริบิวต์

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

อัปเดต

มินิแอปไม่มีกลไกการอัปเดตที่เป็นมาตรฐาน (การพูดคุยเรื่องมาตรฐานที่เป็นไปได้) แพลตฟอร์มแอปขนาดเล็กทั้งหมดมีระบบแบ็กเอนด์ ซึ่งช่วยให้นักพัฒนาแอปขนาดเล็กสามารถอัปโหลดมินิแอปเวอร์ชันใหม่ได้ จากนั้น Super App จะใช้ระบบแบ็กเอนด์ดังกล่าวเพื่อตรวจหาและดาวน์โหลดอัปเดต ซูเปอร์แอปบางแอปจะอัปเดตในเบื้องหลังทั้งหมด โดยมินิแอปไม่มีสิทธิ์ที่จะส่งผลต่อขั้นตอนการอัปเดต ซูเปอร์แอปอื่นๆ ให้การควบคุมมินิแอปได้มากกว่า

ตัวอย่างของกระบวนการที่ซับซ้อนคือย่อหน้าต่อไปนี้จะอธิบายกลไกการอัปเดตของ WeChat สำหรับมินิแอปโดยละเอียด WeChat จะตรวจสอบการอัปเดตที่พร้อมใช้งานใน 2 กรณีต่อไปนี้

  1. WeChat จะตรวจสอบการอัปเดตของมินิแอปที่ใช้ล่าสุดเป็นประจำ ตราบใดที่ WeChat ทำงานอยู่ หากพบการอัปเดต ระบบจะดาวน์โหลดการอัปเดตนั้นและใช้แบบซิงค์กันเมื่อผู้ใช้เปิดมินิแอปแบบ Cold Start ในครั้งถัดไป การเริ่มมินิแอปแบบ Cold Start เกิดขึ้นเมื่อมินิแอปไม่ได้ทำงานอยู่ขณะที่ผู้ใช้เปิด (WeChat จะบังคับปิดมินิแอปหลังจากทำงานอยู่เบื้องหลังเป็นเวลา 5 นาที)
  2. WeChat จะตรวจหาการอัปเดตด้วยเมื่อมีการเริ่มมินิแอปแบบ Cold Start สำหรับมินิแอปที่ผู้ใช้ไม่ได้เปิดใช้งานเป็นเวลานาน ระบบจะตรวจสอบและดาวน์โหลดการอัปเดตพร้อมกัน ผู้ใช้ต้องรอขณะที่ดาวน์โหลดการอัปเดต เมื่อดาวน์โหลดเสร็จแล้ว ระบบจะใช้การอัปเดตและมินิแอปจะเปิดขึ้น หากการดาวน์โหลดไม่สำเร็จ เช่น เนื่องจากการเชื่อมต่อเครือข่ายไม่ดี มินิแอปจะเปิดขึ้นอยู่ดี สำหรับมินิแอปที่ผู้ใช้เปิดเมื่อเร็วๆ นี้ ระบบจะดาวน์โหลดการอัปเดตที่เป็นไปได้แบบไม่พร้อมกันในเบื้องหลัง และจะนำไปใช้เมื่อผู้ใช้เปิดมินิแอปอีกครั้ง

มินิแอปเลือกใช้การอัปเดตเวอร์ชันเก่าได้โดยใช้ UpdateManager API โดยมีฟังก์ชันการทำงานดังต่อไปนี้

  • แจ้งเตือนแอปมินิเมื่อตรวจหาการอัปเดต (onCheckForUpdate)
  • แจ้งให้มินิแอปทราบเมื่อดาวน์โหลดอัปเดตและพร้อมใช้งานแล้ว (onUpdateReady)
  • แจ้งให้มินิแอปทราบเมื่อดาวน์โหลดอัปเดตไม่ได้ (onUpdateFailed)
  • อนุญาตให้แอปขนาดเล็กบังคับติดตั้งอัปเดตที่พร้อมใช้งาน ซึ่งจะรีสตาร์ทแอป (applyUpdate)

WeChat ยังมอบตัวเลือกการปรับแต่งการอัปเดตเพิ่มเติมสำหรับนักพัฒนาแอปขนาดเล็กในระบบแบ็กเอนด์ของตน ดังนี้ 1. ตัวเลือกหนึ่งช่วยให้นักพัฒนาแอปเลือกไม่ใช้การอัปเดตแบบพร้อมกันสำหรับผู้ใช้ที่ได้ติดตั้งแอปมินิเวอร์ชันขั้นต่ำที่กำหนดอยู่แล้ว และบังคับให้การอัปเดตเป็นแบบไม่พร้อมกันแทน 2. อีกตัวเลือกหนึ่งคือนักพัฒนาแอปสามารถกำหนดเวอร์ชันขั้นต่ำที่จำเป็นของแอปมินิได้ ซึ่งจะทำให้การอัปเดตแบบไม่พร้อมกันจากเวอร์ชันที่ต่ำกว่าเวอร์ชันขั้นต่ำที่จำเป็นบังคับให้โหลดแอปมินิอีกครั้งหลังจากใช้การอัปเดต และจะบล็อกการเปิดมินิแอปเวอร์ชันเก่าด้วยหากการดาวน์โหลดอัปเดตไม่สำเร็จ

ขอขอบคุณ

บทความนี้ได้รับการตรวจสอบโดย Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent และ Keith Gu