写点什么

死磕小程序!快应用宣布支持第三方 DSL

  • 2019-04-09
  • 本文字数:6093 字

    阅读完需:约 20 分钟

死磕小程序!快应用宣布支持第三方DSL

背景介绍

大家好,这里是快应用联盟的前端研发团队;


自去年 3 月,快应用联盟成立之后,已经有很多开发者使用快应用的标准 DSL(以 ux 文件后缀的项目形式)上线了对应产品。


以“旅游出行”的品类为例,就有:携程、去哪儿、高铁管家等。



关于更多的快应用产品与体验,读者可以在 Android 手机的应用商店 -> 分类 -> 快应用 栏目中查看;


今天,研发团队带来一个好消息,就是:快应用开放平台接口,可以支持第三方的 DSL 啦!


接下来分享主题:以流行的 Vue 框架为例,让快应用支持第三方 DSL 的开发能力。


那么为什么做这个事呢?主要还是为了满足前端同学的开发习惯,提升开发者的体验与效率。所以借助这种契机与接口开放的能力,快应用可以支持其他更多的 DSL。

过往回溯

自从微信小程序从 16 年 10 月内测以来,前端开发在端适配上迎来了巨大的变化;开发者写的代码,不仅要满足 WEB 平台、原生渲染平台(RN 开发),而且还要增加对小程序的支持。


18 年 3 月成立了国内手机厂商成立了快应用联盟,随后又涌现了百度/阿里/头条等多个小程序生态,给开发者提出了更高要求,从"面向模块的开发"到"面向多端适配"。


可喜的是:在这种背景下,前端圈子里逐渐衍生出新的框架,就是希望能够提供统一的 DSL,让开发者编写一套代码,完成多端自适应的运行效果;


面对市场上众多的框架,新手开发者如何粗略了解与选择呢?

当前现状

从历史发展与职责目标的角度看,当前市场上的 DSL 框架可以分为以下 4 类:


1)WEB 型

比如:React、Vue、Angular 等轻量级的数据驱动框架。


简述:主要用于浏览器的页面开发,因为语法简单、容易上手、调试方便而备受开发者的喜欢。


发展:因为拥有广泛的用户基础,逐渐发展多个子方向,如:UI 组件库方向(如:Ant Design、ElementUI),简化版方向(移动端性能好,扩展更多能力)。


职责:提供开发者钟爱的语法,解决前端项目中组件化、分层架构、工程组织、数据流等问题,让开发者以最优雅的方式管理项目。

2)平台型

比如:Weex 初期的 we 文件语法,微信小程序的 wxml 语法,快应用提供的 ux 文件、百度智能小程序的 swan 文件、Flutter 的 dart。


简述:主流的大互联网公司都会推出自有的渲染平台,从而为满足初期自身平台的渲染而提供一套自己实现的前端框架。


发展:每个平台拥有独特的语法,让开发者水土不服,针对该平台重新开发一套产品代码,学习成本较大。


职责:这类前端框架的存在主要是为了满足初版与迭代,更多服务于平台的系统能力提供,研发方向着重于技术深度的底层渲染(绘制、合成);对于前端框架而言,仅满足开发需求,期望培养开发者习惯,并引领开发潮流较难,除非这类 DSL 可以同时生成到移动端等的适配。

3)适配型

比如:Weex 上支持 Vue 语法,微信小程序中使用 Wepy 和 mpvue,以及本次介绍的快应用平台上引入 Vue 开发方式。


简述:介于诸多开发者对于上述平台型 DSL 不适应,从而引入前端受欢迎的 WEB 型 DSL。


发展:这里的发展思路差异比较大,有的是平台自身开发支持的,有的是通过 DSL 爱好者移植适配完成的,经历二次编译(WEB 型 DSL 先转成平台型 DSL,然后平台型 DSL 再转换成可以直接运行的平台编译代码)。


二次编译的优势在于:它不需要了解平台内部是如何实现的,仅需要根据官方提供的 DSL 能力进行能力适配即可;缺点在于:比较依赖平台型 DSL 能力,如果不支持某个特性则适配困难,或者容易造成性能瓶颈。


如果是平台自身支持的,那么开发者代码,直接就可以完成对 UI 的操作,跳过官方标准 DSL 的模型,减少中间调用,完成加速渲染;这种方式的难点在于:平台自身需要提供稳定的 UI 操作接口,做到向后兼容。毫无疑问,平台自身的支持,能够比二次转换,带来更好的效果;


职责:尽管各自思路不同,但是目标一致,完成开发者从 WEB 到具体平台的顺利过渡。

4) 全能型

比如:滴滴的 chameleon、去哪儿的 nanachi、京东的 taro 等。


简述:该类型从上面的适配型开始萌芽,围绕如何解决多端适配问题,但这仅仅只是表象问题;对于后续壮大发展,需要思考面更广,对抽象概念理解更深刻,如: APP 容器管理,渲染设计,系统功能调用,动态加载等概念。


发展:尽量抹平 WEB、原生、快应用、小程序等渲染的差异,抽象应用模型,完成页面渲染设计,最后适配到各平台;当然适配时如果能够直接完成对平台 API 的操作,要比二次转换效果要好的多。


职责:完成较全面的多端适配,达到一套代码多端适配的目标。


那么本文讲述的快应用引入 Vue DSL,属于上述的适配型,让平台自身支持,同时开发平台接口,为往后出现的全能高效型框架服务。

近期趋势

在作者看来,新的 19 年,全能型框架会逐渐取代适配型,并且从规范、架构、设计等角度上,提出新的理念与原则;基于此,各平台通过自身或者开源爱好者完成适配转换。


当然,各平台负责方(快应用、小程序)也会加深对统一的认识,借助于 W3C 研讨会、兴趣组、前端会议,促教交流,考虑抽象出自己的渲染 API 与能力通道,让更友好的全能型框架完成高效适配,这块敬请期待吧;中间也必定会产生一些兼容性类库,完成 polyfill 的辅助角色;所以基于这种趋势,快应用采用了这样的路线:开放页面渲染接口,轻松支持第三方的 DSL。

实现方案

那么快应用本次支持 Vue 的 DSL 能力,都做了哪些事情呢?


接下来我们从渲染流程、架构设计、开发体验、项目代码、加载过程、平台解耦、测试保证的多个角度阐述。

渲染流程

要想完成适配,首先需要对比两方平台的页面渲染过程是否相似;经过抽象汇总,得出主体过程都是这样的:



步骤 1:工程化工具编译开发者使用某种 DSL 而编写的业务代码。


步骤 2:JS 引擎运行时加载完 DSL 框架后,执行开发者的业务代码。


步骤 3:基于 DSL 的核心逻辑,生成 MVVM 的模型。


步骤 4:业务中对数据的操作,触发对 DOM 节点的更新。


步骤 5:DOM 更新后渲染引擎,发出 VSync 申请,标记脏值节点。


步骤 6:遍历待更新节点,依次样式布局计算、绘制合成,完成渲染。


当前两者实现的区别主要在于:线程的工作分配与协调机制、渲染实现的具体逻辑;然而这些对于 DSL 框架而言,是不需要关注深度实现的。


同时快应用自身会构建一套页面 UI 的 DOM 树,因此抽象出了一套 DOM 的 API 提供给 DSL;DSL 只需要调用快应用提供的节点操作接口,即可轻易完成适配。


为了方便理解,我们在 Github 上增加了 Vue 版本的 TodoMVC 的示例项目quickappcn/todomvc-vue


实际效果可以访问下面地址:


https://github.com/quickappcn/todomvc-vue/raw/master/preview.gif


既然流程一致,那接下来就看如何架构设计,分层组织了。

架构设计

以当前支持 Vue 的适配为例,主要工作在于:编译时、运行时两方面;

编译时

提供针对 DSL 的项目模板化、DSL 的解析编译能力,期间可以使用快应用组件与样式的校验解析接口;当前快应用项目的开发,使用的是官方 hap-toolkit 工具,这是一个基于 NodeJS 的 npm 库。


关于项目的构建打包、调试等非 DSL 专有能力的,均已模块独立;项目结构采用模块化的开发方式,借助于 lerna 完成耦合分离;DSL 开发者只需要开发对应的 DSL 模块,增加模板化、语法解析,即可完成适配。

运行时

负责执行开发者的业务代码,管理 DSL 中的驱动模型,完成数据更新到 DOM 操作的转换。


快应用平台运行时会提供 DOM 的 API,针对每个页面提供一个 document 节点。


DSL 层除了包含官方 Vue 的源码逻辑之外,还有两部分:


  • DOM API 调用:完成对节点的操作;

  • 容器适配模块:提供针对应用/页面概念的适配。


针对这块,快应用在 Github 提供了以下几个项目:


1.项目quickappcn/Vue


从官方 Vue 站点克隆而来,保存 Vue 核心源码、以及针对快应用 DOM API 的适配。


2.项目quickappcn/quickapp-dsl-vue


负责 DSL 在快应用平台上的应用容器适配,如:生命周期、事件通知等。


有了编译时/运行时的核心支持,其它工作(如:IDE 支持)就是相对较小的任务拆解了。

开发体验

对于使用 DSL Vue 的快应用开发者来说,会不会与标准 DSL(标准 DSL:ux 作为后缀名)开发方式,差别很大呢?


其实开发过程,与快应用标准的 DSL 项目开发方式基本完全一致,标准 DSL 的项目中展示的 ux 文件,DSL Vue 中展示的是 vue 文件。


使用方式如下:


步骤 1:全局安装 npm 库:npm install -g hap-toolkit


步骤 2:初始化项目:hap init --vue


步骤 3:构建项目:npm run build


步骤 4:运行在快应用的 APK 平台,开发者可以选择“本地安装“或者” 在线更新“的方式,与标准开发方式一致。

项目代码

总结一下,本次快应用为引入 Vue DSL 而提供的项目:


1.项目quickappcn/todomvc-vue


展示在快应用平台上运行该 DSL 项目的实际开发示例。


项目使用了组件化的开发方式,完成展示与表单的页面交互,文件组织结构如下图所示:



熟悉快应用开发的读者,会发现与标准 DSL 一样,这样方便快速上手。


2.项目quickappcn/Vue


从官方 Vue 站点克隆而来,提供针对快应用 DOM API 的适配;项目中新建了一个 quickapp-initial 的分支,放置适配代码。


3.项目quickappcn/quickapp-dsl-vue


提供了 DSL 在平台上的应用容器适配,如:生命周期、事件通知等;同时包含针对上一个核心 DSL 源码项目的构建后代码。


为了辅助开发,开发者可以补充测试用例,完成单元测试、项目测试的功能保证。


其中的单元测试:测试 Vue 的自身功能表现正常;


其中的项目测试:测试 Vue 在基于 NodeJS 的快应用模拟平台上,是否表现正常。


4.项目 quickappcn/hap-toolkit


提供对开发者写的 DSL 的模板化、语法校验、项目打包等功能。


采用 lerna 模块化改造后,目前划分的模块的依赖关系如下图所示:



对于 DSL 开发者来说,只需要关注:hap-dsl-vue 的模块即可,这块的代码以源码的形式保存;其中的 templates 文件夹存放项目模板,src 文件夹存放相关的编译解析能力。


对于其他的部分模块,比如:hap-compiler,hap-server 属于所有的 DSL 共用模块,开发者一般无需更新;同时部分模块并未仅提供了编译后代码,如需开放源码,开发者可以下来联系。


为了保证稳定性,也可以增加测试用例(当前使用的是 Jest),完成单元测试与项目测试的编译功能确认。


hap-toolkit@0.3.0 版本上增加了对 Vue DSL 的支持,不过并未采用 lerna 管理,后续发布的 0.4 版本以后会用这种方式。


注意:由于新业务功能的开发,当前模块化组织结构可能还会继续调整。

加载过程

在快应用完成编译时/运行时的开发后,DSL 是如何加载并调用渲染的呢?大家看下下面的图例就明白了:



快应用的运行可以分为三个阶段:


第一阶段:环境准备


底层平台启动,暴露 DOM 等相关 API,加载 DSL 代码,并完成与平台的桥接通讯。


第二阶段:业务代码执行


加载并执行开发者项目中的 vue 业务代码(编译后转换为 JS),建立驱动模型,完成 VDOM 的对比。


第三阶段:平台渲染


上一层 VDOM 对比的结果,转换成对平台的 DOM API 的实际调用,平台线程然后做布局计算、绘制等完成界面的展示。


上图所示,可以得出:DSL 与平台的解耦与交互发生在第一阶段的最后一步,即:平台接口暴露之后,业务代码执行之前;因此整个运行,DSL 框架仅会加载一次。

平台解耦

那么 DSL 与平台需要考虑哪些方面的解耦事项呢?主要分为三个部分:

1)容器管理

快应用是一个应用形态,包含多个页面,这点不同于浏览器,所以就会存在应用/页面的生命周期。


开发者需要监听这些生命周期,用于完成:数据请求、统计、性能监控。


为了保持解耦合,平台使用了 Publish/Subscribe 模型,DSL 只需要订阅相关的事件,即可暴露给开发者。


开发者可以从项目 quickappcn/quickapp-dsl-vue 的 src/shared 文件夹 中得到提示。

2)页面渲染

对于每个页面来说,页面的渲染依赖于组件树的构建,为了方便对组件进行操作,平台提供了一套类似浏览器的组件操作接口,称为:平台 DOM API。


为了提升 DSL 适配的简易性,快应用的 DOM 与浏览器中的 DOM 非常相似。


比如:创建节点的 API(document.createElement())、节点增删的 API(element.appendChild()、element.insertBefore())。


在 Vue DSL 中,开发者都会使用哪些接口进行节点操作呢?


可以从项目 quicappcn/vue 的 src/platforms/quickapp/node-ops.js 文件中得到提示。

3)接口功能

业务开发中,开发者肯定需要调用系统功能,如:fetch 请求:require(’@sysem.fetch’)、地理位置:require(’@system.geolocation’)。


这方面的语法与平台的标准 DSL 语法保持一致,会在编译时进行转换,如:fetch 请求转换为:("@app-module/system.fetch")$。


平台执行开发者的 JS 代码时,会自动注入一个全局函数;那么 JS 执行时就会通过该函数完成系统功能的获取。


所以关于这块,DSL 适配不会有实际工作量;可以项目 quickappcn/quickapp-dsl-vue 的 src/dsls/vue/page/interface.js 文件中得到提示。

测试保证

对于 DSL 开发者来说,通过测试用例保证功能稳定是必不可缺的;


针对编译时,测试相对简单,查看项目 quickapp/hap-toolkit 即可读懂。


针对运行时,如果每次对源码修改后,都需要在手机设备上测试运行,确认功能的话,将会很浪费时间。


为了解决这一难题,快应用平台的前端层面,提供了在 NodeJS 环境上的平台模拟能力;因此开发者可以通过两方面的测试用例来保证稳定。

单元测试

完成对 DSL 的基本功能进行测试,如:指令、filter、数据驱动等各种 DSL 自身特性。


相关代码请参考:项目 quickappcn/quickapp-dsl-vue 的 test/suite/dsls/vue/unit 文件夹。


测试命令请参考:项目 quickappcn/quickapp-dsl-vue 的 package.json 中的"test:suite:framework:main:vue:unit"命令。

项目测试

开发者像开发正式的快应用项目一样,编写 DSL 页面;模拟平台会将测试项目编译打包,然后逐个执行开发者的页面代码;开发者可以在这里,测试 DOM 树的结构一致性、生命周期、接口功能等。


相关代码请参考:项目 quickappcn/quickapp-dsl-vue 的 test/suite/dsls/vue/project 文件夹;


测试命令请参考:项目 quickappcn/quickapp-dsl-vue 的 package.json 中的"test:suite:framework:main"命令。

合作交流

如果您是快应用的开发者,或者其他角色,对于前端开发生态感兴趣,欢迎提出各类建议,或合作意向。


快应用平台对 DSL 能力的支持,前端与底层研发团队做了很多耦合分离工作,开源工作得以推进;同时感谢联盟内各家厂商研发的鼎力支持,大家合作共同管理项目源码与规范制定。

使用 DSL 开发

如果您也是 Vue 框架深度爱好者的话,可以考虑使用 Vue 来做快应用产品的开发。


围绕 Vue DSL 的最新能力与运行体验,我们将会在项目 quickappcn/quickapp-dsl-vue 中保持更新,您可以向这里提交 issue 反馈需求。


快应用的 Vue DSL 会在 1050 版本邀请内测,待功能稳定后,平台将内置正式版本的 Vue DSL。


注意:由于当前内测期间,Vue DSL 暂不支持华为设备,联盟内所有剩余厂商均可以无缝支持。

其它 DSL 接入

如果您是某个 DSL(如:React)的爱好者,或者某个全能型框架的设计者,有意向接入到快应用平台中,让更多的开发者受益,欢迎洽谈垂询。


您可以通过联盟的任何成员/各种渠道联系前端团队,或者向我们发送邮件:dongyongqing#xiaomi.com


更多内容,请关注前端之巅。



2019-04-09 14:2111790

评论 1 条评论

发布
用户头像
董老师 怎么可以联系到你哈
2019-04-09 14:35
回复
没有更多了
发现更多内容

Zebec 投票治理机制上线,全新流支付生态正在起航

西柚子

有了HotSpot JVM为什么还需要OpenJ9?

骑牛上青山

Java jdk JVM 虚拟机

2023JAVA面试题全集(超全面!超系统!超实用!)早做准备,早上岸!

架构师之道

Java 编程 程序员 计算机 java面试

ABBYY FineReader16最新版本更新下载

茶色酒

ABBYY FineReader16 ABBYY16

深度剖析 Linux 伙伴系统的设计与实现

bin的技术小屋

Linux 内存管理 Linux内核 内存分配 Linux内核源码

从原理源码到企业级实战,腾讯大佬纯手打的Spring Boot笔记(2023版)真香

程序员小毕

spring 后端 springboot java程序员 java面试

CTO:假如Java微服务随机掉线,你会怎么排查?

Java永远的神

Java 程序员 面试 微服务 架构师

Java高手速成 | EL表达式语言

TiAmo

Java EL

全息电网 数字孪生智慧电网Web3D运维系统

2D3D前端可视化开发

智慧电网 数字电网 智能电网 数字孪生智慧电网 智慧电网三维可视化

信用卡APP评测系列——工银e生活5.0打造个人生活服务平台,引领用户美好生活

易观分析

金融 银行 信用卡

写给go开发者的gRPC教程-protobuf基础

凉凉的知识库

golang 微服务 gRPC protobuf 微服务框架

gcc属性__attribute__((naked))使用场景

SkyFire

GCC 内嵌汇编

Zebec 上线投票治理机制,全新流支付生态正在起航

鳄鱼视界

第三届腾讯Light·技术公益创造营正式启动:聚焦三大议题,探索技术公益可持续路径​

OpenCloudOS

开源

Zebec 上线投票治理机制,全新流支付生态正在起航

股市老人

湖仓一体电商项目(十八):业务实现之编写写入DWD层业务代码

Lansonli

数据湖 湖仓一体电商项目

架构训练营模块四作业

gigifrog

架构训练营

【1.27-2.3】写作社区优秀技术博文一览

InfoQ写作社区官方

热门活动 优质创作周报

活动预告 | 2023 QCon 全球软件开发大会 - AI 基础架构论坛

第四范式开发者社区

人工智能 机器学习 数据库 开源 特征

FLStudio2023水果中文版软件如何下载?

茶色酒

flstudio FLStudio21

案例研究:让线上故障沉淀为团队的经验

石云升

极客时间 2月月更 技术领导力实战笔记

Jackson 的 DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES

HoneyMoose

D触发器 (D-FF)详解

timerring

FPGA

「AVL平衡树专项」带你领略常用的AVL树与红黑树的奥秘(规则篇)

C++后台开发

数据结构 后端开发 红黑树 linux开发 C++开发

我发现买不起自己出版的图书了,这到底是咋回事?

冰河

程序员 并发编程 高并发 架构师 编程开发

喜讯!云起无垠实力入选多项中国网络安全行业全景图

云起无垠

抖音春晚直播观看人数破1.3亿,火山引擎技术助力“新年俗”新体验

火山引擎边缘云

云原生 CDN 边缘计算 抖音 视频云

沿着数字中国的大江大河,领略云上三峡

脑极体

华为云 三峡

Portraiture4.0版本最新永久免费版下载

茶色酒

Portraiture2023 Portraiture

提名倒计时! | 2022 龙蜥社区优秀贡献者

OpenAnolis小助手

技术 操作系统 龙蜥社区 开源贡献者 奖项报名

死磕小程序!快应用宣布支持第三方DSL_大前端_董永清_InfoQ精选文章