APP下载

滴滴开源小程式框架 Mpx2.0

消息来源:baojiabao.com 作者: 发布时间:2024-06-17

报价宝综合消息滴滴开源小程式框架 Mpx2.0

作者:滴滴出行

来源:https://github.com/didi/mpx

滴滴Mpx框架负责人@hiyuki,滴滴出行网约车webapp乘客团队的负责人,也是滴滴开源的小程式框架Mpx的负责人和核心作者

Mpx是一款致力于提高小程式开发体验和效率的增强型小程式框架,目前在滴滴公司内部支撑了包括滴滴出行小程式,滴滴出行广场小程式,青桔单车,黑马摩托车,小桔养车,小桔加油在内的小程式生态;自去年11月开源以来,Mpx也吸纳了众多外部开发者的加入,基于Mpx开发了开走吧,好免街,花忆等小程式。

长期以来,Mpx优秀的开发体验和强大的稳定性得到了内外开发者的一致认可和好评,这非常符合Mpx的设计初衷。但是在各大厂商陆续推出自己的小程式平台,且各家的技术标准都不统一的今天,单纯地提高某一个平台的开发体验已经不能满足广大小程式开发者们的诉求,一套程式码在多小程式平台执行已经成为一个现实上的刚需。为了解决这个小程式开发的痛点,Mpx释出了2.0版本,适配了目前业内已经发布的所有小程式平台(微信、支付宝、百度、头条、qq),并且提供了直接将现有微信小程式编译输出到其他平台执行的能力。

Mpx2.0版本新增的主要特性主要包含:

完整支援了目前业内已释出的所有小程式平台(微信,支付宝,百度,qq,头条);Mpx小程式跨平台开发,支援将已有的Mpx微信专案编译输出到其他已支援的小程式平台中执行,详情检视:https://didi.github.io/mpx/platform.html#跨平台编译;小程式原生元件跨平台编译,支援将已有的微信原生元件编译输出到其他已支援的小程式平台中执行;深度分包优化,编译过程中进行精准分包资源判断,所有分包only的资源(元件、js、外部样式、外部模板、wxs,影象媒体等)都会精确输出到分包目录中;render函式中完整支援wxs模组,关于render函式点选检视详情:https://didi.github.io/mpx/understanding/understanding.html#资料响应与效能优化;支援了模板引入,内联wxs,自定义tabbar,独立分包,workers,云开发等原生能力,进一步完善原生相容性。同业内主流的小程式跨端框架相比,Mpx更专注于小程式开发本身,在小程式开发中具备以下优势:

基于小程式自身的技术标准进行增强,没有进行过重的DSL转换,开发时遇到的坑会更少;完全相容原生小程式技术规范,0成本迁移原生小程式专案;跨平台开发以跨小程式平台为目标,大部分差异抹平工作在编译阶段进行,大大减少执行时适配层增加的包体积;支援业内微信小程式元件库(如vant、iView等)直接转换到其他小程式平台执行;非常重视小程式效能,提供了深度的setData和包体积优化。关于Mpx更详细的介绍可以检视官方文件:https://didi.github.io/mpx/和这篇文章:https://didi.github.io/mpx/articles/1.0.html。

跨平台开发

作为2.0版本的核心能力,Mpx的跨平台开发能力允许使用者直接将已有小程式专案编译输出到其他已支援的小程式平台中执行。微信小程式作为小程式概念的提出者,有着最广泛的生态覆盖,因此我们优先支援了将微信小程式编译为其他平台小程式的能力。基于这个能力,使用者不仅能跨平台编译微信Mpx专案,甚至能够将微信的原生自定义元件也编译到其他小程式平台进行执行,这意味着我们的跨平台专案能够直接使用一些社群内已有的UI元件库生态(如vant、iView等),极大地提高了跨平台开发的适用范围。

设计理念

Mpx框架的核心设计理念在于增强,增强是指在小程式已有的原生能力基础上做加法,拓展小程式的开发能力,提高小程式的开发体验和效率。这个设计理念使Mpx给开发者带来了更强的确定性和可预期性,更低的学习上手和除错成本。基于这个理念,Mpx在不同的小程式平台中进行了差异性的增强适配,并参考各个平台的模板指令风格提供了不同的增强模板指令集,让使用者在各小程式平台中都可以以增强的方式去最大限度地使用平台自有的原生能力。

我们在对Mpx提供跨平台能力的支援时也遵循了增强的核心设计理念。简单来讲,Mpx的跨平台能力是在多平台能力的基础上,在编译和执行时增加了一层转换层,将源平台的程式码转换为目标平台的程式码之后,再按照既有的目标平台的处理逻辑进行增强,同时我们也提供了一套完善的条件编译机制,让使用者自行实现少数框架无法转换的部分。

Mpx跨平台开发流程示意图

Mpx跨平台能力设计思路明显区别于业内已有的其他小程式跨平台框架,主要差异在于:

Mpx以小程式本身的DSL作为基准,而没有使用web框架(React,Vue)的DSL;Mpx主要通过编译和执行时转换的方式处理平台差异,没有提供额外的差异抹平层(基础元件库等)。之所以采用这种设计,主要基于以下原因:

Mpx主要以跨小程式平台为目标,目前各大小程式平台的技术规范具有一定相似性,绝大部分平台差异能够通过编译和执行时手段抹平,同时省去的差异抹平层也能够进一步减少框架执行时体积;使用小程式本身的DSL作为基准允许使用者直接在已有专案中使用跨平台能力,对于原生小程式专案或元件也能够使用该能力进行跨平台输出;结合完善的条件编译支援,该方案能够在满足使用者跨平台需求的同时仍然允许使用者最大限度地使用各个小程式平台提供的能力,完全延续了Mpx增强的核心设计理念。使用方法

Mpx跨平台开发的使用方式非常简单,使用者只需在MpxWebpackPlugin建立时传入mode和srcMode引数指定源平台和目标平台,当srcMode和mode不一致时,框架会读取相应的配置对专案进行编译和执行时转换。

// 微信转支付宝new MpxWebpackPlugin({

// mode指定目标平台,可选值有(wx|ali|swan|qq|tt)

mode: 'ali',

// srcMode指定源代码平台,预设值同目标平台一致

srcMode: 'wx'

})

差异抹平

目前各大厂商的小程式技术规范在宏观层面上大致保持一致,但是技术细节方面存在很多差异,大致划分为以下几个部分:

模板语法/基础元件差异json配置差异wxs语法差异页面/元件物件差异api呼叫差异webview bridge差异其中,对于模板语法/基础元件、json配置和wxs中的静态差异,我们主要通过编译手段进行转换处理,对于这部分差异中无法转换的部分会在编译阶段报错指出;而对于页面/元件物件、api呼叫和webview bridge中js执行时的差异,我们主要通过执行时手段进行处理,对应无发转换部分也会在执行时中报错指出。

值得注意的是,我们在跨平台转换中做的工作不仅是对可转换的技术标准进行转换对映,对于一些目标平台中不存在的能力,我们也尽可能地通过编译和执行时手段提供了模拟和支援,最大限度地减少使用者在跨平台开发中需要付出的额外工作量。以差异性最大但现实场景也最多的微信转支付宝为例,Mpx模拟提供了许多微信中支援但支付宝中未支援的能力:

元件自定义事件元件间关系获取子元件例项observers/property observer内联wxs对于原生自定义元件的跨平台转换,我们会对其进行简单的执行时注入,使其能够使用Mpx框架提供的执行时转换能力。

条件编译

对于框架无法抹平的差异部分,会在编译和执行时报错指出,对于这部分错误,我们提供了完善的条件编译机制让使用者能够自行编写目标平台的patch进行修复,该能力也能用于实现具有平台差异性的业务逻辑。

上文中提到Mpx通过读取使用者传入的mode和srcMode来决定是否以及如何对专案进行转换,mode和srcMode分别代表整个专案构建的目标平台和源平台,条件编译能够让使用者在专案中建立声明了自身平台属性(localSrcMode)的档案和程式码块。在专案构建中,框架会优先载入带有localSrcMode宣告且localSrcMode与专案目标平台匹配(localSrcMode===mode)的档案和程式码块,这部分档案和程式码块需要完全依照自身宣告的平台标准进行编写,Mpx不会对其进行任何编译和执行时的跨平台转换。

Mpx提供了三种维度的条件编译,分别是档案维度,区块维度和程式码维度,使用者可以根据差异范围和自身需要自行选择使用。

效能优化

Mpx框架专注于小程式开发,在效能优化方面我们做过很多尝试和努力,主要集中在两个方面:

执行时的setData优化编译构建时的包体积优化setData优化

资料响应是Mpx执行时增强的核心能力,该能力让使用者在小程式开发中能够像Vue中一样使用watch和computed特性,并且用直接赋值的方式操作资料驱动检视更新,而不需要手动呼叫setData方法,换言之框架接管了小程式中的setData呼叫。

通过各大小程式平台的设计原理和效能优化建议可以得知,setData对于小程式的效能表现非常重要,而setData优化的两大方向在于:

尽可能减少setData呼叫的频次尽可能减少单次setData传输的资料为了实现setData的优化,我们在模板编译过程中对于每个元件的模板都生成了一个渲染函式(render function),该函式模拟模板的渲染逻辑,在每次执行时访问当次渲染所需的资料,并将当次访问过的资料路径记录下来作为函式返回值返回。

在执行时,框架会在每个元件建立时建立一个render watcher,该watcher追踪渲染函式,当渲染依赖资料发生变更时异步执行渲染函式,在render watcher回拨中得到渲染函式返回的资料路径,基于这些路径与上一次的快取资料进行diff比对,过滤掉未发生变化的资料后得到最小必要资料,最后呼叫setData将最小必要资料传送到真实的小程式渲染层更新检视。

基于这个机制,当资料发生变更时,只有当前渲染依赖的那部分资料发生变更才会异步地触发render watcher的执行,而每次执行后也只有实际发生变更的那部分资料会被setData传送到渲染层。这样使用者就能自由地根据业务需求来操作资料,无需关注setData的呼叫优化,框架能够自动进行程式上最优的setData呼叫,在提升使用者开发体验的同时也提升了程式效能。

在1.x版本中,渲染函式内无法执行wxs的逻辑,对于含有wxs的元件有可能降级到全量设定资料的模式,在2.0版本中,我们将wxs模组转译处理为js可执行的程式码后注入到js bundle中,含有wxs的渲染函式也能够正常访问并执行wxs逻辑。

setData优化示意图

包体积优化

类似于执行时对于setData的接管,Mpx在编译阶段接管了专案的资源管理。得益于webpack强大的外挂机制,Mpx开发了一个深度定制的webpack外挂,基于webpack完成小程式的打包构建工作。使用者在使用Mpx开发小程式时可以不受限制地使用npm依赖、最新的es特性和css前处理器等现代web开发能力。与此同时,Mpx在包体积优化上也做了很多工作,让使用者专注于业务开发而无需花费过多精力进行包体积管理,我们所做的优化工作如下:

打包构建工作完全基于依赖分析,任何没有被引用的资源都不会出现在dist当中;对于npm元件和页面的构建也完全基于依赖分析按需打包,不会copy整个miniprogram_dist目录,也不需要执行构建npm,使用体验和包体积均优于微信小程式自身的npm支援方案;基于webpack提供的能力进行公共模组抽取和程式码压缩等优化工作;完善的分包支援,对所有资源进行从属分析,将所有分包only的资源都输出到分包目录中。分包作为微信小程式中优化包体积的核心手段(类似于异步按需载入),Mpx对其进行了完善的支援。为了精确地标记出分包only的资源,我们在构建时将主包和分包的依赖收集步骤拆分开来序列处理,先处理主包,再处理分包。在主包的处理过程中,将主包页面中引用的所有非js资源(元件、外部样式、外部模板、wxs,影象媒体等)都记录下来,在处理分包时,对分包内引用的非js资源都进行检查,如果被主包引用过则输出到主包中,否则标记为分包only的资源输出到分包目录下。

对于js模组资源,我们在脚手架中生成的构建配置中提供了辅助函式,便于使用者进行分包bundle的配置,经过该配置后,分包only的公用模组会被打入分包bundle输出到分包目录下,其余的公共模组会正常打入主bundle中。

在跨平台开发中,我们建议使用者使用Mpx提供的packages:(https://didi.github.io/mpx/single/json-enhance.html#packages来定义分包,这样在转换到不支援分包的小程式平台时会自动降级为同步包进行处理。

分包构建示意图

渐进迁移

Mpx提供了良好的渐进迁移支援,对于使用原生或其他小程式框架的开发者来说,采用渐进迁移的方式逐步引入Mpx进行开发成本并不大。

在2.0版本中我们进一步完善了Mpx的原生相容性,跟进支援了各个小程式平台最新的技术能力,如自定义tabbar,独立分包,分包预载入,workers,云开发等能力,同时补齐了一些1.x版本遗漏的支援。得益于此,对于使用原生小程式开发的开发者来说,迁移Mpx的成本几乎为0,使用者只需将对应页面元件的建构函式替换为Mpx提供的createPage/createCompnent,即可使用Mpx提供的各种增强能力。

对于使用其他框架的开发者,Mpx也提供了局部构建的机制,允许使用者将特定的页面和元件单独构建输出为原生元件,使用者只需手动或者编写指令码输出的原生元件整合进原有专案中即可。

未来规划

作为滴滴公司内部小程式生态的基础设施,我们会对Mpx框架进行长期的维护更新,确保能在第一时间支援各个小程式平台最新的技术特性。与此同时,我们也会进一步完善框架的基础能力,目前已排上日程待支援能力包括:

i18nts支援单元测试支援在跨平台能力方面,我们也会根据社群的反馈和建议,以及小程式的标准化程序,对其进行持续的完善与更新。

最后,如果你专注小程式开发,关注开发体验和产品效能,那Mpx会是你最好的选择。

Github:https://github.com/didi/mpx

官方文件:https://didi.github.io/mpx

看完有没想拿这个框架试一试的冲动呢?

2019-10-02 16:53:00

相关文章