ترميز التطبيقات المصغّرة وتصميمها وبرمجتها وتحديثها

اللغات الترميزية

كما وضحنا من قبل، بدلاً من استخدام HTML العادي، تتم كتابة التطبيقات المصغرة بلهجات HTML. إذا سبق لك أن تعاملت مع استقراء نص Vue.js وتوجيهاته، ستشعر بالوعي التام، ولكن كانت هناك مفاهيم مشابهة تظهر قبل ذلك في عمليات تحويل XML (XSLT). يمكنك الاطّلاع أدناه على عيّنات التعليمات البرمجية من ملف WXML في WeChat، لكنّ المفهوم نفسه ينطبق على جميع الأنظمة الأساسية للتطبيقات الصغيرة، وهي AXML من Alipay، وSwan Element من Baidu، وTTML من ByteDance، (على الرغم من أنّ أدوات DevTools تطلق عليها Bxml) ورمز HTML في التطبيق السريع. كما هو الحال مع 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، أي CSS ببساطة من Baidu، أمّا في ByteDance، فيُشار إليها باسم TTSS. القاسم المشترك بينهما هو أنها توسّع CSS باستخدام وحدات بكسل سريعة الاستجابة. عند كتابة CSS عادية، يحتاج المطورون إلى تحويل جميع وحدات البكسل للتكيف مع شاشات الأجهزة الجوّالة المختلفة ذات نسب العرض والبكسل المختلفة. تعتمد تقنية TTSS وحدة rpx كطبقة أساسية، ما يعني أنّ التطبيق المصغَّر يتولى مهام المطوّر ويحوّل الوحدات نيابةً عنه بناءً على عرض الشاشة المحدّد بقيمة 750rpx. على سبيل المثال، على هاتف Pixel 3a الذي يبلغ عرض الشاشة 393px (ونسبة وحدات البكسل في الجهاز 2.75)، تصبح قيمة 200rpx سريعة الاستجابة 104px على الجهاز الفعلي عند فحصها باستخدام "أدوات مطوري البرامج في Chrome" (393 بكسل / 750 دورة بكسل × 200 بكسل × 200 بكسل ≈ 104 بكسل). في نظام Android، يُعرف المفهوم نفسه باسم البكسل المستقل للكثافة.

يُظهر فحص العرض باستخدام &quot;أدوات مطوري البرامج في Chrome&quot; التي تم تحديد مساحة متروكة البكسل المتجاوبة بـ &quot;200rpx&quot; أنّها في الواقع &quot;104px&quot; على جهاز 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، أي الأنماط التي يتم تعريفها على مدى وصول الصفحة إلى جميع المكوّنات. لتنظيم ملف ورقة الأنماط الشائعة، يجب أن يكون لديك ورقة أنماط أساسية واحدة للأنماط العامة، وأوراق أنماط فردية لكل صفحة خاصة بكل صفحة من صفحات التطبيق المصغّر. يمكن استيراد الأنماط باستخدام قاعدة @import تتصرف على غرار @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 وSJS من Alipay وByteDance أيضًا SJS. تتحدث Baidu عن JS عند الإشارة إلى ملفاتها. يجب تضمين هذه النصوص البرمجية باستخدام نوع خاص من العلامات، مثل <wxs> في WeChat. وفي المقابل، يستخدم التطبيق السريع علامات <script> العادية وبنية ES6 JS.

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

واجهة برمجة تطبيقات جسر JavaScript

يتيح جسر JavaScript الذي يربط التطبيقات الصغيرة بنظام التشغيل إمكانية استخدام إمكانات نظام التشغيل (راجِع الوصول إلى ميزات فعّالة. كما أنه يوفر عددًا من طرق الراحة. للحصول على نظرة عامة، يمكنك الاطّلاع على واجهات برمجة التطبيقات المختلفة في WeChat وAlipay وBaidu وByteDance والتطبيق السريع.

إنّ ميزة رصد الميزات سهلة وبسيطة لأنّها توفّر طريقة (تُعرف حرفيًا على هذا النحو) canIUse() ويبدو اسمها مستوحى من الموقع الإلكتروني caniuse.com. على سبيل المثال، تتيح سمة tt.canIUse() في ByteDance إجراء عمليات تحقّق للتأكّد من إمكانية استخدام واجهات برمجة التطبيقات والطرق والمعلَمات والخيارات والمكوّنات والسمات.

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

التحديثات

لا تتضمن التطبيقات المصغّرة آلية تحديث موحّدة (مناقشة حول إمكانية توحيد المقاييس). تحتوي جميع منصات التطبيقات الصغيرة على نظام خلفية يسمح لمطوّري التطبيقات الصغيرة بتحميل إصدارات جديدة من تطبيقاتهم الصغيرة. ثم يستخدم تطبيق متميّز نظام الخلفية هذا للبحث عن التحديثات وتنزيلها. تُجري بعض التطبيقات المتميزة تحديثات بالكامل في الخلفية، بدون أي وسيلة يمكن من خلالها أن يؤثر التطبيق المصغر نفسه في عملية التحديث. تمنح التطبيقات المتميّزة الأخرى إمكانية التحكّم بشكل أكبر في التطبيقات الصغيرة نفسها.

كمثال على عملية معقدة، تشرح الفقرات التالية بالتفصيل آلية تحديث التطبيقات الصغيرة في WeChat. يبحث تطبيق WeChat عن التحديثات المتاحة في حالتَي السيناريوهَين التاليَين:

  1. سيبحث تطبيق WeChat بانتظام عن تحديثات التطبيقات المصغّرة المستخدَمة مؤخرًا طالما أنّ التطبيق يعمل. في حال العثور على تحديث، يتم تنزيل التحديث وتطبيقه بشكل متزامن في المرة التالية التي يشغّل فيها المستخدم التطبيق المصغَّر على البارد. يحدث التشغيل البارد للتطبيقات المصغّرة عندما لا يكون التطبيق المصغَّر قيد التشغيل عند فتحه من المستخدم (يفرض تطبيق WeChat إغلاق التطبيقات الصغيرة بعد ظهورها في الخلفية لمدة 5 دقائق).
  2. يبحث تطبيق WeChat أيضًا عن التحديثات عند بدء تشغيل تطبيق مصغّر على البارد. بالنسبة إلى التطبيقات الصغيرة التي لم يفتحها المستخدم لفترة طويلة، يتم البحث عن التحديث وتنزيله بشكل متزامن. أثناء تنزيل التحديث، يتعين على المستخدم الانتظار. بعد انتهاء عملية التنزيل، يتم تطبيق التحديث وفتح التطبيق المصغَّر. وفي حالة إخفاق التنزيل، على سبيل المثال بسبب ضعف الاتصال بالشبكة، يتم فتح التطبيق المصغر بغض النظر عن ذلك. وبالنسبة إلى التطبيقات الصغيرة التي فتحها المستخدم مؤخرًا، يتم تنزيل أي تحديث محتمل في الخلفية بشكل غير متزامن وسيتم تطبيقه في المرة التالية التي يبدأ فيها المستخدم تشغيل التطبيق المصغر.

يمكن للتطبيقات الصغيرة الموافقة على التحديثات السابقة باستخدام واجهة برمجة التطبيقات UpdateManager. ويوفر الوظائف التالية:

  • يرسل إشعارًا إلى التطبيق المصغَّر عند البحث عن تحديثات. (onCheckForUpdate)
  • لإعلام التطبيق المصغَّر عند تنزيل تحديث وعندما يكون متاحًا. (onUpdateReady)
  • يتم إشعار التطبيق المصغَّر عند تعذُّر تنزيل تحديث. (onUpdateFailed)
  • يسمح هذا الإذن للتطبيق المصغّر بتثبيت تحديث متاح من المؤسّسة، ما سيؤدي إلى إعادة تشغيل التطبيق. (applyUpdate)

يوفر WeChat أيضًا خيارات إضافية لتخصيص التحديث لمطوِّري التطبيقات المصغَّرة في نظامه الخلفي: 1- أحد الخيارات يسمح للمطوّرين بإيقاف التحديثات المتزامنة للمستخدمين الذين سبق لهم تثبيت إصدار حد أدنى معيّن من التطبيق المصغَّر، ويؤدي بدلاً من ذلك إلى أن تكون التحديثات غير متزامنة. 2. يتيح خيار آخر للمطوّرين ضبط أدنى إصدار مطلوب من تطبيقهم المصغّر. سيؤدي هذا الإجراء إلى إجراء تحديثات غير متزامنة من إصدار أقل من الحد الأدنى المطلوب للإصدار ثم فرض إعادة تحميل التطبيق المصغَّر بعد تثبيت التحديث. وسيتم أيضًا حظر فتح إصدار قديم من التطبيق المصغَّر في حال تعذُّر تنزيل التحديث.

شكر وتقدير

تمت مراجعة هذه المقالة من قِبل جو ميدلي وكايس باسك وميلييكا ميهاجيليا وآلان كينت وكيث جو.