미니 앱 마크업, 스타일 지정, 스크립팅, 업데이트

토마스 슈타이너
토마스 슈타이너

마크업 언어

앞에서 설명한 것처럼 미니 앱은 일반 HTML이 아닌 HTML 방언으로 작성됩니다. Vue.js 텍스트 보간 유형 및 지시어를 사용해 본 적이 있다면 즉시 친숙하게 느끼겠지만, 이전에 XML 변환(XSLT)에도 유사한 개념이 존재했습니다. 아래에서 WeChat의 WXML 코드 샘플을 볼 수 있지만 개념은 모든 미니 앱 플랫폼, 즉 Alipay의 AXML, Baidu의 Swan Element, ByteDance의 TTML(DevTools를 Bxml로 지칭함) 및 Quick App의 HTML에서 동일합니다. Vue.js와 마찬가지로 기본적인 미니 앱 프로그래밍 개념은 model-view-viewmodel (MVVM)입니다.

데이터 결합

데이터 결합은 Vue.js의 텍스트 보간 유형에 상응합니다.

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

목록 렌더링

목록 렌더링은 Vue.js v-for 지시어처럼 작동합니다.

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

조건부 렌더링

조건부 렌더링은 Vue.js의 v-if 지시어처럼 작동합니다.

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

템플릿

WXML 템플릿은 HTML 템플릿의 content를 명령형으로 복제할 필요 없이 템플릿 정의에 연결되는 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라고 합니다. 두 속성의 공통점은 반응형 픽셀을 사용하여 CSS를 확장한다는 점입니다. 일반 CSS를 작성할 때 개발자는 너비와 픽셀 비율이 다른 다양한 휴대기기 화면에 맞게 모든 픽셀 단위를 변환해야 합니다. TTSS는 rpx 단위를 기본 레이어로 지원합니다. 즉, 미니 앱이 개발자의 작업을 인계받아 지정된 화면 너비 750rpx에 따라 단위를 대신 변환합니다. 예를 들어 화면 너비가 393px이고 기기 픽셀 비율이 2.75인 Pixel 3a 휴대전화의 경우 Chrome DevTools로 검사하면 반응형 200rpx가 실제 기기에서 104px가 됩니다(393px / 750rpx * 200rpx 부터는 104px). Android에서는 동일한 개념을 밀도 독립형 픽셀이라고 합니다.

반응형 픽셀 패딩이 `200rpx` 로 지정된 Chrome DevTools로 뷰를 검사하면 실제로 Pixel 3a 기기에서 `104px` 인 것을 보여줍니다.
Chrome DevTools로 Pixel 3a 기기의 실제 패딩을 검사합니다.
/* 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 CSS at-rule과 같이 작동하는 @import 규칙을 사용하여 스타일을 가져올 수 있습니다. HTML에서와 마찬가지로 스타일은 동적 텍스트 보간 유형을 포함하여 인라인으로 선언할 수도 있습니다 (이전 참고).

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

스크립트 작성

미니 앱은 JavaScript의 '안전한 하위 집합'을 지원하며, 여기에는 CommonJS 또는 RequireJS를 상기하는 다양한 구문을 사용하는 모듈을 지원하는 기능이 포함됩니다. JavaScript 코드는 eval()를 통해 실행할 수 없으며 new Function()로 함수를 만들 수 없습니다. 스크립팅 실행 컨텍스트는 기기의 경우 V8 또는 JavaScriptCore이고 시뮬레이터의 경우 V8 또는 NW.js입니다. 빌드 타겟이 이전 WebView 구현이 있는 운영체제 (이후 참고)인 경우 특정 DevTools가 코드를 ES5로 자동으로 변환하므로 일반적으로 ES6 이상 구문으로 코딩할 수 있습니다. Super 앱 제공업체의 문서에서는 스크립트 언어가 자바스크립트와 혼동되어서는 안 되며 자바스크립트와 구별된다는 점을 명시적으로 언급합니다. 하지만 이 문은 대부분 모듈이 작동하는 방식, 즉 아직 표준 ES 모듈을 지원하지 않는다는 의미입니다.

에서 언급했듯이 미니 앱 프로그래밍 개념은 model-view-viewmodel (MVVM)입니다. 로직 레이어와 뷰 레이어는 서로 다른 스레드에서 실행됩니다. 즉, 사용자 인터페이스가 장기 실행 작업에 의해 차단되지 않습니다. 웹 측면에서는 웹 워커에서 실행되는 스크립트를 생각할 수 있습니다.

WeChat의 스크립트 언어는 WXS, Alipay의 SJS, ByteDance의 경우 SJS라고 합니다. Baidu는 자신의 JS를 참조할 때 JS라고 합니다. 이러한 스크립트는 특별한 종류의 태그(예: WeChat의 <wxs>)를 사용하여 포함해야 합니다. 반면에 빠른 앱은 일반 <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 Bridge API

미니 앱을 운영체제와 연결하는 자바스크립트 브리지를 통해 OS 기능을 사용할 수 있습니다 (강력한 기능 액세스 참고). 또한 여러 가지 편의 메서드도 제공합니다. 개요를 보려면 WeChat, Alipay, Baidu, ByteDance, Quick App의 다양한 API를 확인하세요.

모든 플랫폼에서 이름 그대로 caniuse.com 웹사이트에서 영감을 얻은 canIUse() 메서드를 제공하기 때문에 특징 감지는 간단합니다. 예를 들어 ByteDance의 tt.canIUse()는 API, 메서드, 매개변수, 옵션, 구성요소, 속성에 관한 지원 검사를 허용합니다.

// 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이 실행되는 한 최근에 사용한 미니 앱의 업데이트를 정기적으로 확인합니다. 업데이트가 발견되면 업데이트가 다운로드되고 사용자가 미니 앱을 콜드 스타트할 때 동기식으로 적용됩니다. 미니 앱을 콜드 스타트하는 것은 사용자가 미니 앱을 열 때 현재 실행되고 있지 않았을 때 발생합니다 (WeChat은 미니 앱을 5분 동안 백그라운드 상태가 된 후 강제 종료함).
  2. 또한 WeChat은 미니 앱이 콜드 스타트될 때 업데이트를 확인합니다. 사용자가 오랫동안 열지 않은 미니 앱의 경우 업데이트를 동기식으로 확인하고 다운로드합니다. 업데이트가 다운로드되는 동안 사용자는 기다려야 합니다. 다운로드가 완료되면 업데이트가 적용되고 미니 앱이 열립니다. 네트워크 연결 불량 등의 이유로 다운로드가 실패하더라도 미니 앱이 열립니다. 사용자가 최근에 연 미니 앱의 경우 잠재적인 업데이트는 백그라운드에서 비동기식으로 다운로드되며 사용자가 다음에 미니 앱을 콜드 스타트할 때 적용됩니다.

미니 앱은 UpdateManager API를 사용하여 이전 업데이트를 선택할 수 있습니다. 이 API는 다음과 같은 기능을 제공합니다.

  • 업데이트 확인이 완료되면 미니 앱에 알립니다. (onCheckForUpdate)
  • 업데이트가 다운로드되어 사용할 수 있게 되면 Mini 앱에 알립니다. (onUpdateReady)
  • 업데이트를 다운로드할 수 없는 경우 Mini 앱에 알립니다. (onUpdateFailed)
  • 미니 앱이 사용 가능한 업데이트를 강제 설치하여 앱을 다시 시작하도록 허용합니다. (applyUpdate)

또한 WeChat은 백엔드 시스템에서 미니 앱 개발자를 위한 추가 업데이트 맞춤설정 옵션을 제공합니다. 1. 한 가지 옵션은 개발자가 이미 미니 앱의 특정 최소 버전이 설치된 사용자를 대상으로 동기식 업데이트를 선택 해제하고, 업데이트를 비동기식으로 진행하도록 하는 것입니다. 2. 또 다른 옵션을 사용하면 개발자가 미니 앱의 최소 필수 버전을 설정할 수 있습니다. 그러면 최소 필수 버전보다 낮은 버전에서 비동기 업데이트가 이루어지므로 업데이트를 적용한 후 미니 앱을 강제로 새로고침합니다. 또한 업데이트 다운로드에 실패할 경우 이전 버전의 미니 앱을 열지 못하게 됩니다.

감사의 말씀

이 문서는 Joe Medley, Kayce Basques, Milica Mihajlija, Alan Kent, Keith Gu가 검토했습니다.