小程序开发者,为什么你应该尝试下MPX

MPX框架是滴滴出行推出的一款专注小程序开发的增强型框架。本篇文章将从使用角度谈谈mpx的优势与好处。如果嫌内容太长,每个小节都有简单的一句话总结,可以快速阅读。如果想了解更多设计细节,可以阅读 前一篇文章 - MPX2.0发布

背景

在小程序逐渐火热的今天,越来越多的开发者需要进行小程序的开发。

小程序的开发者往往面临着选择,是按微信小程序官方文档来开发,还是使用各种五花八门的框架。

那么今天,我们要给大家安利一下MPX框架。

优势

之所以建议开发者们考虑使用mpx来开发小程序,当然是因为mpx框架具有一些别的框架所没有的优点。

原生兼容

TL;DR: MPX完全兼容原生,坑少。渐进接入简单。

从语法风格上,我们可以看到目前市面上流行的小程序框架基本是基于web框架(taro/nanachi - react,uniapp/megalo/mpvue - vue)或者自建一套全新(chameleon)/半全新(wepy)的标准。

但是不知道有没有人意识到,使用这些框架,你写的代码,根本不是小程序代码。而是react/vue或者什么别的。

所以你的源码到小程序代码,会经过一次转换,这个在框架良好维护时期不是什么问题,任何的问题都会被很快响应并解决。

但随着时间,很多框架可能会慢慢疏于维护,而小程序本身不会等你,它会做出更多的功能特性,提供更好的组件、方法,这个时候你如何用上最新的东西呢?

在这个问题上,mpx的答案是,全面拥抱原生

口说无凭,我们来看个典型的mpx组件长什么样。

mpx组件示例

乍一看好像和vue没什么区别,也就多了个json块,template里写的是小程序的标签。

但是由于这一块全是符合微信小程序原生语法,我们是不会做任何转换的,所以你写什么就是什么,坑少可以理解了吧。(如果用了mpx的增强特性,还是会小转换一下的,后续我们也会出文章详细解释mpx的增强是如何实现的,相对来说,我们的转换比较轻量、透明、易理解)

当微信出了新的能力、新的标签、新的生命周期钩子,使用mpx框架来编写的小程序只需要直接用起来就行。

所以!使用mpx框架,你可以轻易地使用 自定义组件的relations 来搞定组件间关系,使用 wxs 来更好地构建页面。

mpx几乎支持原生的每一个特性,在 .mpx 文件里,模板部分写的是原生小程序的模板语法,脚本部分写的是原生小程序的脚本语法,json部分写的是原生小程序的配置信息。用MPX,你才是真的在开发小程序。

所以你可以看到别家框架为了“忽悠”原生小程序开发者使用他们的框架,会提供一些转换工具可以让你把原生小程序代码转成框架代码(上车容易下车难啊),而在mpx框架中,你可以直接使用原生小程序的页面、组件。

目前很多原生小程序开发者可能想尝试下框架,老项目上mpx肯定是最简单的了。口说无凭,我们搞了个demo来给大家打个样:在我们GitHub项目中有examples文件夹,里面的 原生项目渐进接入mpx示例

第三方组件库

TL;DR: MPX提供了完备的第三方组件库支持

上面说了mpx对原生的极致兼容,能让你想到什么?对,就是对第三方组件库的完美支持。

支持第三方组件库的重要性大家都知道,所以这个能力大部分框架都支持了。但是支持和完美支持还是有区别的。据简单观察,taro/mpvue/uniapp对于第三方组件库的支持都是以复制的形式进行的,也就是和微信小程序本来的行为很像。

那么mpx是怎么支持第三方组件库的呢,这里有个demo:也在我们的GitHub里的examples文件夹下,MPX使用第三方组件库示例 ,核心代码见下图:

mpx使用第三方组件库代码示例

乍一眼看不太出来有什么特别的?没用过别的框架引第三方组件,简单找了找其他框架好像也没提供相应的demo,用过的朋友可以自行对比下。

在MPX里使用第三方组件库,仅需要像web项目一样npm安装即可,并不需要复制文件。然后在json里直接写包名就会去node_modules下面查找了。再配合webpack alias可以做到更简单、更语义化。

然而这还没有结束~

细心的朋友会发现,这段示例代码中既有vant的组件,也有iview的组件,如果按照微信的规范,这些组件库会通过miniprogram字段指定自己的构建文件生成目录,开发者工具会把这个目录完全拷贝到最终发布的代码里去,我们就会有两个巨大的组件库占据宝贵的空间。

我们当然是希望用多少引多少,而不是一股脑全引进去,对,于是MPX提供了按需引用的能力,在下一章按需引用细讲。

以及,组件库目前很少有跨小程序平台的组件库啊,如果我用了vant,支付宝、QQ里没有vant怎么办?也许这是别的框架不怎么推荐使用第三方库的原因,而MPX里,我们帮你把别人的组件库也转了,细节看下下章跨小程序平台

按需引用

TL;DR: 通过webpack依赖分析收集,使用第三方组件库或者拆分开发大型项目时MPX能保证构建的代码全是要用到的代码

看了上面的描述,有的朋友可能会有一个疑惑:怎么感觉MPX全是原生?那为什么我不直接编写原生小程序代码?

原因有两点:

  1. 原生小程序确实存在一些痛点问题,而这些问题在web开发领域其实已经有了很好的解决方案,mpx就是把这些解决方案移植到小程序开发上,通过解决这些痛点问题,来提升小程序开发体验,来增强小程序能力。
  2. MPX立足原生小程序,又提供了一些能力增强的特性,以帮助开发者更好更快开发小程序。

下面我们列举一下原生小程序存在的问题:

  1. 文件冗杂,一个小程序页面/组件由4个文件组成,而为了便于组合又或是细分职责等方面考虑,整个项目往往会由特别多但是不算大的页面/组件来组成。
  2. npm支持不够完善,微信小程序对于npm的支持是通过一个新的字段来指定需要被整个拷入小程序的文件夹来实现的,不便于按需使用。
  3. 团队合作能力缺失,一个大型项目可能拆分成不同的部分由不同的开发者/小组维护,所以项目的分拆、组合能力很重要。
  4. 无数据响应式(computed/watch),双向数据绑定等做起来较麻烦。

好的我们来看看解决方案。

对于第一点,各种主流框架其实都较好地解决了这个问题,一个组件都揉到了一个文件里去了。第四点我们后面讲能力增强时细讲。

本节的重点就是MPX如何解决第二第三点问题啦。

我们提供的@mpxjs/webpack-plugin插件,会解析mpx文件的json部分或原生的json文件,将依赖收集到webpack中统一处理,而不是基于文件遍历。

带来的好处就是:如果你喜欢vant的按钮,iview的输入框,wux的布局,欢迎尝试mpx,让你能同时使用多个UI框架的同时不用担心应用的体积爆炸。

同理,面对一个大型项目,我们可以拆成不同的部分,由不同的团队完成后发npm包,在一个主项目中引入即可,具体内容可以看文档JSON增强 - packages一节。

收集依赖的细节可以查阅文档编译构建一节。

跨小程序平台

TL;DR: MPX朴素的跨平台方法能带着第三方组件库一起跨小程序平台,同时提供了充足完善的条件编译能力。

在 MPX 1.0 时代,MPX框架是专注提升微信小程序的开发体验,虽然也提供了支付宝版,但代码完全要另写。

而随着越来越多的 super app 提供了小程序能力,目前至少有5种体系的小程序(微信、支付宝系列、百度系列、头条系列、QQ),如果每一个平台都需要维护一份代码,工程师人数明显不够用了,所以跨小程序平台的能力也是 MPX 2.0 的主打特性。

我们的跨平台的方法也比较质朴,就是转换。都是小程序,语法基本一样,配置、钩子的差异靠运行时抹平,其他最大的区别也就是模板上的标签和指令。所以我们内部实现了一套转换的架子,再编写一份转换规则,即可完成微信小程序到支付宝、百度、头条小程序的转换。

虽然思路和方法都比较朴素,但是结合前面一直在说的我们对原生的支持多么多么完美,就可以撞出一点不一样的东西,比如,前文提到的第三方组件库跨小程序平台。

对,我们能帮你把针对微信编写的ui组件库在支付宝、百度上运行起来,带着组件库一起跨小程序平台。

那么一定会有这样一个问题,就算mpx对原生的支持再怎么牛逼,有的基础能力只有微信平台有,别的平台没有,mpx的转换还能无中生有吗?

当然不能,其实这个问题对于所有的跨端框架都是一个问题,所以跨端最核心的问题是,如何搞定差异化部分。

MPX提供了丰富的条件编译能力,可以以文件为维度差别构建,可以以代码块为维度,也可以以代码维度进行差别构建。

而且MPX的差异化构建能力也是完全基于webpack实现的,所以上面提到的第三方组件库如果确实存在转换不了的地方,比如vant的picker组件使用内联wxs写了一个小方法叫isSimple在模板里调用了,但是这个方法的写法在百度小程序的filter脚本(filter可以理解为百度小程序的wxs)里不支持,因为百度的filter要求必须导出一个对象包裹方法。

最好的解决办法当然是给vant-weapp提pr帮他们解决一下这个问题,但时间可能会比较慢,所以在mpx里,可以利用webpack的alias能力:

通过alias解决第三方组件的跨平台问题

当尝试构建百度小程序时,会优先去查找pick/index.swan.wxml,再被alias到一个src下的文件,自己修改一下第三方包里有一些小问题的部分即可。

关于跨平台的条件编译,更多具体信息可以查阅我们的官方文档 - 跨平台条件编译

能力增强

TL;DR: 通过数据响应式、编译时预处理提供了computed/watch,完备的样式类型绑定,双向数据绑定,动态组件等一系列方便开发者更好开发小程序的能力增强

能力增强应该是一个框架提供的最核心最重要的能力了,不过其实各个框架在能力增强上做得都大同小异吧,所以本节篇幅不多,简单介绍,细节还是翻文档的好。

和别家框架相比MPX取了个巧,因为别家的框架是基于react/vue的,往往会给个列表不支持哪些能力,用户写的时候习惯使然,往往用了后可能才反应过来哦这个不支持。MPX则是原生的小程序语法写着难受时候突然想起mpx有这个能力。

举一个比较有意思的小特性吧,比如Vue里的动态组件,一些基于Vue的小程序框架都声明不支持,mpx里却可以使用,其实就是收集json里注册的组件,生成一堆带wx:if判断componentName是否等于自己组件名,替换模板上的component标签。

最显著的能力是数据响应式,衍生出computed/watch,以及双向数据绑定等。这个能力和Vue比较像,但是MPX是由mobx提供的数据响应能力。

但是同样是数据响应式,我们做了一些不一样的优化,看下一节。

性能优势

TL;DR: 通过对模板的解析抽象出访问的数据以保证在提供了数据响应式的同时不至于劣化性能。

mpvue/wepy/megalo等框架也提供了数据响应的能力,但是数据响应在小程序领域有个较大的问题,微信开发指南里明确提到要注意setData的调用频次和数据量的大小。

而数据响应式最基本的做法就是数据变了就去set数据,这会极大劣化小程序的性能表现。

而MPX通过对模板进行解析,抽象出对应的render函数,在调用setData发送数据前执行render函数找到真正需要发送的数据。

效果如图:

小程序性能分析

小程序开发者工具的audits面板能辅助用户分析出可能需要优化的点。正如前文所说,MPX在红框部分,尤其是红框里的第三条,不将模板上未使用的数据发送到渲染层上做了极大的优化。

只要不出现渲染函数执行失败(会有warning在console里提示,同时兜底逻辑会进行全量setData以保证程序仍可正常运行),使用MPX开发的小程序就永远不用担心发送了模板未使用的数据。

虽然只是一个小小的TODO MVC示例,但是这个优化和应用的规模没关系,而且同时大家可以尝试别家的小demo对比看看。

这个优化的细节可以看前一篇文章,或者我们的文档mpx运行机制 - 数据响应与性能优化

总结

与目前市面上的诸多框架相比,MPX希望以原生小程序为基础,全面拥抱原生小程序,在原生小程序的基础上做增强,通过尽可能少的转换实现尽可能多的能力增强,在提升小程序开发体验的同时,保证不因转换或框架的问题产生过多的坑。

MPX框架的目标用户是对小程序质量有较高要求的开发者,如果你是原生小程序开发者,或者厌倦了解决某些以web框架DSL语法为基础的转换框架造成的坑,欢迎尝试MPX框架。