整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

5 个主流跨端框架的评测

近前端届多端框架频出,相信很多有代码多端运行需求的开发者都会产生一些疑惑:这些框架都有什么优缺点?到底应该用哪个?

作为 Taro 开发团队一员,笔者想在本文尽量站在一个客观公正的角度去评价各个框架的选型和优劣。但宥于利益相关,本文的观点很可能是带有偏向性的,大家可以带着批判的眼光去看待,权当抛砖引玉。

那么,当我们在讨论多端框架时,我们在谈论什么:

多端

笔者以为,现在流行的多端框架可以大致分为三类:

1. 全包型

这类框架最大的特点就是从底层的渲染引擎、布局引擎,到中层的 DSL,再到上层的框架全部由自己开发,代表框架是 Qt 和 Flutter。这类框架优点非常明显:性能(的上限)高;各平台渲染结果一致。缺点也非常明显:需要完全重新学习 DSL(QML/Dart),以及难以适配中国特色的端:小程序。

这类框架是最原始也是最纯正的的多端开发框架,由于底层到上层每个环节都掌握在自己手里,也能最大可能地去保证开发和跨端体验一致。但它们的框架研发成本巨大,渲染引擎、布局引擎、DSL、上层框架每个部分都需要大量人力开发维护。

2. Web 技术型

这类框架把 Web 技术(JavaScript,CSS)带到移动开发中,自研布局引擎处理 CSS,使用 JavaScript 写业务逻辑,使用流行的前端框架作为 DSL,各端分别使用各自的原生组件渲染。代表框架是 React Native 和 Weex,这样做的优点有:

  • 开发迅速;
  • 复用前端生态;
  • 易于学习上手,不管前端后端移动端,多多少少都会一点 JS、CSS。

缺点有:

1. 交互复杂时难以写出高性能的代码,这类框架的设计就必然导致 JS 和 Native 之间需要通信,类似于手势操作这样频繁地触发通信就很可能使得 UI 无法在 16ms 内及时绘制。React Native 有一些声明式的组件可以避免这个问题,但声明式的写法很难满足复杂交互的需求。

2. 由于没有渲染引擎,使用各端的原生组件渲染,相同代码渲染的一致性没有第一种高。

3. JavaScript 编译型

这类框架就是我们这篇文章的主角们:Taro、WePY 、uni-app 、 mpvue 、 chameleon,它们的原理也都大同小异:先以 JavaScript 作为基础选定一个 DSL 框架,以这个 DSL 框架为标准在各端分别编译为不同的代码,各端分别有一个运行时框架或兼容组件库保证代码正确运行。

这类框架最大优点和创造的最大原因就是小程序,因为第一第二种框架其实除了可以跨系统平台之外,也都能编译运行在浏览器中。(Qt 有 Qt for WebAssembly, Flutter 有 Hummingbird,React Native 有 react-native-web, Weex 原生支持)

另外一个优点是在移动端一般会编译到 React Native/Weex,所以它们也都拥有 Web 技术型框架的优点。这看起来很美好,但实际上 React Native/Weex 的缺点编译型框架也无法避免。除此之外,编译型框架的抽象也不是免费的:当 bug 出现时,问题的根源可能出在运行时、编译时、组件库以及三者依赖的库等等各个方面。在 Taro 开源的过程中,我们就遇到过 Babel 的 bug,React Native 的 bug,JavaScript 引擎的 bug,当然也少不了 Taro 本身的 bug。相信其它原理相同的框架也无法避免这一问题。

但这并不意味着这类为了小程序而设计的多端框架就都不堪大用。首先现在各巨头超级 App 的小程序百花齐放,框架会为了抹平小程序做了许多工作,这些工作在大部分情况下是不需要开发者关心的。其次是许多业务类型并不需要复杂的逻辑和交互,没那么容易触发到框架底层依赖的 bug。

那么当你的业务适合选择编译型框架时,在笔者看来首先要考虑的就是选择 DSL 的起点。因为有多端需求业务通常都希望能快速开发,一个能够快速适应团队开发节奏的 DSL 就至关重要。不管是 React 还是 Vue(或者类 Vue)都有它们的优缺点,大家可以根据团队技术栈和偏好自行选择。

如果不管什么 DSL 都能接受,那就可以进入下一个环节。

生态

以下内容均以各框架现在(2019 年 3 月 11 日)已发布稳定版为标准进行讨论。

开发工具

就开发工具而言 uni-app 应该是一骑绝尘,它的文档内容最为翔实丰富,还自带了 IDE 图形化开发工具,鼠标点点点就能编译测试发布。

其它的框架都是使用 CLI 命令行工具,但值得注意的是 chameleon 有独立的语法检查工具,Taro 则单独写了 ESLint 规则和规则集。

在语法支持方面,mpvue、uni-app、Taro 、WePY 均支持 TypeScript,四者也都能通过 typing 实现编辑器自动补全。除了 API 补全之外,得益于 TypeScript 对于 JSX 的良好支持,Taro 也能对组件进行自动补全。

CSS 方面,所有框架均支持 SASS、LESS、Stylus,Taro 则多一个 CSS Modules 的支持。

所以这一轮比拼的结果应该是:

uni-app > Taro > chameleon > WePY、mpvue

多端支持度

只从支持端的数量来看,Taro 和 uni-app 以六端略微领先(移动端、H5、微信小程序、百度小程序、支付宝小程序、头条小程序),chameleon 少了头条小程序紧随其后。

但值得一提的是 chameleon 有一套自研多态协议,编写多端代码的体验会好许多,可以说是一个能戳到多端开发痛点的功能。uni-app 则有一套独立的条件编译语法,这套语法能同时作用于 js、样式和模板文件。Taro 可以在业务逻辑中根据环境变量使用条件编译,也可以直接使用条件编译文件(类似 React Native 的方式)。

在移动端方面,uni-app 基于 weex 定制了一套 nvue 方案 弥补 weex API 的不足;Taro 则是暂时基于 expo 达到同样的效果;chameleon 在移动端则有一套 SDK 配合多端协议与原生语言通信。

H5 方面,chameleon 同样是由多态协议实现支持,uni-app 和 Taro 则是都在 H5 实现了一套兼容的组件库和 API。

mpvue 和 WePY 都提供了转换各端小程序的功能,但都没有 h5 和移动端的支持。

所以最后一轮对比的结果是:

chameleon > Taro、uni-app > mpvue > WePY

组件库 / 工具库 /demo

作为开源时间最长的框架,WePY 不管从 Demo,组件库数量 ,工具库来看都占有一定优势。

uni-app 则有自己的插件市场和 UI 库,如果算上收费的框架和插件比起 WePy 也是完全不遑多让的。

Taro 也有官方维护的跨端 UI 库 taro-ui ,另外在状态管理工具上也有非常丰富的选择(Redux、MobX、dva),但 demo 的数量不如前两个。但 Taro 有一个转换微信小程序代码为 Taro 代码的工具,可以弥补这一问题。

而 mpvue 没有官方维护的 UI 库,chameleon 第三方的 demo 和工具库也还基本没有。

所以这轮的排序是:

WePY > uni-app 、taro > mpvue > chameleon

接入成本

接入成本有两个方面:

第一是框架接入原有微信小程序生态。由于目前微信小程序已呈一家独大之势,开源的组件和库(例如 wxparse、echart、zan-ui 等)多是基于原生微信小程序框架语法写成的。目前看来 uni-app 、Taro、mpvue 均有文档或 demo 在框架中直接使用原生小程序组件 / 库,WePY 由于运行机制的问题,很多情况需要小改一下目标库的源码,chameleon 则是提供了一个按步骤大改目标库源码的迁移方式。

第二是原有微信小程序项目部分接入框架重构。在这个方面 Taro 在京东购物小程序上进行了大胆的实践,具体可以查看文章《Taro 在京东购物小程序上的实践》。其它框架则没有提到相关内容。

而对于两种接入方式 Taro 都提供了 taro convert 功能,既可以将原有微信小程序项目转换为 Taro 多端代码,也可以将微信小程序生态的组件转换为 Taro 组件。

所以这轮的排序是:

Taro > mpvue 、 uni-app > WePY > chameleon


流行度

从 GitHub 的 star 来看,mpvue 、Taro、WePY 的差距非常小。从 NPM 和 CNPM 的 CLI 工具下载量来看,是 Taro(3k/week)> mpvue (2k/w) > WePY (1k/w)。但发布时间也刚好反过来。笔者估计三家的流行程度和案例都差不太多。

uni-app 则号称有上万案例,但不像其它框架一样有一些大厂应用案例。另外从开发者的数量来看也是 uni-app 领先,它拥有 20+ 个 QQ 交流群(最大人数 2000)。

所以从流行程度来看应该是:

uni-app > Taro、WePY、mpvue > chameleon

开源建设

一个开源作品能走多远是由框架维护团队和第三方开发者共同决定的。虽然开源建设不能具体地量化,但依然是衡量一个框架 / 库生命力的非常重要的标准。

从第三方贡献者数量来看,Taro 在这一方面领先,并且 Taro 的一些核心包 / 功能(MobX、CSS Modules、alias)也是由第三方开发者贡献的。除此之外,腾讯开源的 omi 框架小程序部分也是基于 Taro 完成的。

WePY 在腾讯开源计划的加持下在这一方面也有不错的表现;mpvue 由于停滞开发了很久就比较落后了;可能是产品策略的原因,uni-app 在开源建设上并不热心,甚至有些部分代码都没有开源;chameleon 刚刚开源不久,但它的代码和测试用例都非常规范,以后或许会有不错的表现。

那么这一轮的对比结果是:

Taro > WePY > mpvue > chameleon > uni-app

最后补一个总的生态对比图表:

未来

从各框架已经公布的规划来看:

WePY 已经发布了 v2.0.alpha 版本,虽然没有公开的文档可以查阅到 2.0 版本有什么新功能 / 特性,但据其作者介绍,WePY 2.0 会放大招,是一个「对得起开发者」的版本。笔者也非常期待 2.0 正式发布后 WePY 的表现。

mpvue 已经发布了 2.0 的版本,主要是更新了其它端小程序的支持。但从代码提交, issue 的回复 / 解决率来看,mpvue 要想在未来有作为首先要打消社区对于 mpvue 不管不顾不更新的质疑。

uni-app 已经在生态上建设得很好了,应该会在此基础之上继续稳步发展。如果 uni-app 能加强开源开放,再加强与大厂的合作,相信未来还能更上一层楼。

chameleon 的规划比较宏大,虽然是最后发的框架,但已经在规划或正在实现的功能有:

  • 快应用和端拓展协议;
  • 通用组件库和垂直类组件库;
  • 面向研发的图形化开发工具;
  • 面向非研发的图形化页面搭建工具。

如果 chameleon 把这些功能都做出来的话,再继续完善生态,争取更多第三方开发者,那么在未来 chameleon 将大有可为。

Taro 的未来也一样值得憧憬。Taro 即将要发布的 1.3 版本就会支持以下功能:

  • 快应用支持;
  • Taro Doctor,自动化检查项目配置和代码合法性;
  • 更多的 JSX 语法支持,1.3 之后限制生产力的语法只有只能用 map 创造循环组件一条;
  • H5 打包体积大幅精简。

同时 Taro 也正在对移动端进行大规模重构;开发图形化开发工具;开发组件 / 物料平台以及图形化页面搭建工具。


结语

那说了那么多,到底用哪个呢?

如果不介意尝鲜和学习 DSL 的话,完全可以尝试 WePY 2.0 和 chameleon ,一个是酝酿了很久的 2.0 全新升级,一个有专门针对多端开发的多态协议。

uni-app 和 Taro 相比起来就更像是「水桶型」框架,从工具、UI 库,开发体验、多端支持等各方面来看都没有明显的短板。而 mpvue 由于开发一度停滞,现在看来各个方面都不如在小程序端基于它的 uni-app 。

当然,Talk is cheap。如果对这个话题有更多兴趣的同学可以去 GitHub 另行研究,有空看代码,没空看提交:

  • chameleon: https://github.com/didi/chameleon
  • mpvue: https://github.com/Meituan-Dianping/mpvue
  • Taro: https://github.com/NervJS/taro
  • uni-app: https://github.com/dcloudio/uni-app
  • WePY: https://github.com/Tencent/wepy

编写代码只是软件开发的一小部分,更多的时间往往花在构建(build)和测试(test)。 为了提高软件开发的效率,构建和测试的自动化工具层出不穷,Travis就是这类工具,用好这个工具不仅可以提高效率,还能使开发流程更可靠和专业。

CI简介

CI(Continuous Integration,持续集成):指的是只要代码有变更,就自动运行构建和测试,反馈运行结果。确保符合预期以后,再将新代码集成到主干。 持续集成的好处在于,每次代码的小幅变更,就能看到运行结果,从而不断累积小的变更,而不是在开发周期结束时,一下子合并一大块代码。

Travis-CI简介

Travis CI提供的是持续集成服务。它绑定GitHub上面的项目,只要有新的代码,就会自动抓取,然后,提供一个运行环境,执行测试,完成构建,还能部署到服务器。 Travis CI与Github结合比较紧密,对GitHub上的开源Repo是免费的,私有Repo收费。

免费Travis-CI:https://travis-ci.org

收费Travis-CI:https://travis-ci.com

启用Travis CI

Step1:使用GitHub账户授权登录Travis CI。

Step2:同步GitHub上的库,对指定的库启用Travis CI

配置.travis.yml

Travis要求项目的根目录下面,必须有一个 .travis.yml文件。这是配置文件,指定了Travis的行为。该文件必须保存在GitHub仓库里面,一旦代码仓库有新的Commit,Travis就会去找这个文件,执行里面的命令。

代码语言:javascript
复制
language: android jdk: oraclejdk8 # 开启基于容器的Travis CI任务,让编译效率更高 sudo: false android: components: # 构建项目所用的BuildTools版本 - build-tools-28.0.3 # 用来编译项目的SDK版本 - android-28 # 添加Android Support Repository组件 - extra-android-m2repository # 添加Support Library组件 - extra-android-support before_script: - chmod +x gradlew script: # 生成release apk包 - ./gradlew assembleRelease

Travis生命周期

  1. before_install
  2. install:安装依赖
  3. before_script
  4. script:运行脚本
  5. aftersuccess or afterfailure:script阶段执行成功或失败时执行
  6. [OPTIONAL] before_deploy
  7. [OPTIONAL] deploy:部署
  8. after_script

保证自动化构建的密码和证书安全

Android项目发布需要证书文件和密码,将原始正常和密码放入到代码库是很不安全的。 Travis CI为此提供了两种解决方案:

  1. 对敏感信息、密码、证书等进行对称加密,在CI构建环境时进行解密;
  2. 将密码等通过Travis CI的控制台设置为构建时的环境变量。

加密签名证书

因为Travis CI控制台无法上传文件,因此涉及到文件加密的部分,选择第一种方案。

Step1:本地安装Travis CLI命令行工具

代码语言:javascript
复制
gem install travis

Step2:命令行登录Travis(第一次登录才要),并输入GitHub的用户名和密码

代码语言:javascript
复制
travis login --org

Step3:进入项目根目录,加密证书

代码语言:javascript
复制
travis encrypt-file xch_android.jks --add

命令执行结果

1. 在Travis CI控制台自动生成一对秘钥,形如: encrypted_d71df9144721_ivencrypted_d71df9144721_key

2. 基于秘钥通过 openssl对文件进行加密,并在根目录生成 xch_android.jks.enc文件

3. 在 .travis.yml中自动生成Travis CI环境下解密文件的配置。

  1. before_install:
  2. -openssl aes-256-cbc-K $encrypted_d71df9144721_key -iv $encrypted_d71df9144721_iv
  3. -inxch_android.jks.enc-outxch_android.jks-d

加密证书密码

Step1. 在Travis CI控制台配置 KEYSTORE_PASSALIAS_NAMEALIAS_PASS三个环境变量。

Step2. 在项目的根目录下创建一个名为 keystore.properties文件(用于本地命令打包),并包含以下信息:

代码语言:javascript
复制
KEYSTORE_PASS=myStorePassword ALIAS_NAME=myKeyAlias ALIAS_PASS=myKeyPassword

Step3. 在 app module 的 build.gradle配置签名信息, System.getenv()用来获取Travis CI控制台配置的变量。

代码语言:javascript
复制
apply plugin: 'com.android.application' // 加载本地keystore.properties中的签名配置 def keyPropertiesFile = rootProject.file("keystore.properties") def keyProperties = new Properties() if (keyPropertiesFile.exists()) { keyProperties.load(new FileInputStream(keyPropertiesFile)) } android { compileSdkVersion 28 defaultConfig { applicationId "com.github.xch168.androidtravisci" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } signingConfigs { release { storeFile file("../xch_android.jks") storePassword keyProperties.containsKey("KEYSTORE_PASS") ? keyProperties['KEYSTORE_PASS'] : System.getenv("KEYSTORE_PASS") keyAlias keyProperties.containsKey("ALIAS_NAME") ? keyProperties['ALIAS_NAME'] : System.getenv("ALIAS_NAME") keyPassword keyProperties.containsKey("ALIAS_PASS") ? keyProperties['ALIAS_PASS'] : System.getenv("ALIAS_PASS") } } buildTypes { release { minifyEnabled false signingConfig signingConfigs.release proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } }

配置缓存机制

Travis CI在每次构建完成后,就会删除所有文件,设置缓存机制,可以保证规定的缓存文件不需要每次下载,提高每次构建的速度;但是如果在更好的基础配置的情况(比如更新Gradle版本等,建议先清除缓存在跑CI)。

.travis.yml文件添加如下配置:

代码语言:javascript
复制
before_cache: - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ cache: #指定缓存目录 directories: - $HOME/.gradle/caches/ - $HOME/.gradle/wrapper/ - $HOME/.android/build-cache

可以在后台手动删除Travis CI Cache:

Travis CI自动发布apk到GitHub Release

Step1. 执行travis命令自动生成deploy配置

代码语言:javascript
复制
travis setup releases

命令执行完后会自动在 .travis.yml添加如下配置:

代码语言:javascript
复制
deploy: provider: releases api_key: secure: b7dhz7j5tY73qbQo2GNccev7NgI6BNWNeEpEfmLTxRZ7DJptxtQuJIHF026zhHtXfRom/pSXw7qlRJXamPWl7Bc1i1lUNKX7Mdt3Fo7Z70ZAyT/6vak3EGlKqDU7Ta96MOB2+5+2nQ7nlTX4kkkeObSTbD6py4eUzktoxsPSwtjiWrq7KM4KgcJTAEGnZx4LJdFm6pgE3drkbN83J0ZP3fT7sf+5Ggv4WLa8y3l/gM3rQ0tARebDo4OuigJOmknOfcxkiAlTtVt1qw1STMaW4H/M47K1mSvQK9DxSHUCD7ngvxEJlUMtqvYSIqQItyT7D8SvDxUqpZZM6y6qAcp+q5qrnA/uC7Qa3kju3skH1XBXyA20TN/pLYKk1yuH7TLg9W+512Pmgtpr4AiZayChnNn4morhhhncsdnQf1T6ziWUNGHmMK8QcUzjBdZHOVsNHGUuaGk4hOPeTRi7ozHYMnNF1E8HJEhtLf7/BHH4o17x5wI2QuSmgwqlCbhAYEwL8m9ZtyJ7saqimGo6m37XfBlomBgaTMrCDIybqOABjPxASlMVRh84XZeeAHHLgjSRMoP2cb+lksiyhO2TsCOvQEOmofFcjj4+iN+qIynPMb3bonuce/iD9nNC2cusibYaIrr1+r2VWE61EdIiLlamw99fFT1VZtliJuJe9tugMgA= file: app/build/outputs/apk/app-release.apk # 这句手动添加 skip_cleanup: true on: repo: xch168/AndroidTravisCI # 这句手动添加 tags: true

说明

  • provider:发布目标为GitHub Release,除了GitHub外,Travis CI还支持发布到AWS、Google App Engine等数十种provider。
  • secure:是加密后的GitHub Access Token。
  • file:发布的文件。
  • skip_cleanup:默认情况下Travis CI在完成编译后会清除所有生成的文件,因此要将 skip_cleanup设置为 true来忽略此操作。
  • on:发布的时机,这里配置为 tags:true,即只在有 tag的情况才发布。

Step2: 打 tag

代码语言:javascript
复制
git tag -a v0.0.1-alpha.1 -m "这里是Tag注释,说清楚这个版本的主要改动,也可以省略-m参数直接写长文本" git push origin --tags

Step3: 自动化构建、部署

  • 当打完tag并推送到GitHub仓库时,就会触发Travis CI任务。

  • 当Travis CI任务执行成功后,在GitHub就能看到发布的apk。

上传apk到蒲公英

蒲公英是APP内测分发平台,提供免费的APP内测分发托管,不但允许游客下载,还提供了二维码,下载速度快。

Step1. 使用GitHub授权登录https://www.pgyer.com/user/login

Step2. 获取API Key

Step3. 将获取的API Key配置到Travis CI的环境变量 PGYER_API_KEY

Step4. 在 .travis.yml文件中,添加如下配置:

代码语言:javascript
复制
# 添加蒲公英上传脚本 before_install: - cd $TRAVIS_BUILD_DIR - wget -c https://raw.githubusercontent.com/Pgyer/TravisFile/master/pgyer_upload.sh -O pgyer_upload.sh - chmod +x pgyer_upload.sh # 在apk上传到GitHub后,使用蒲公英的上传脚本将apk上传到蒲公英 after_deploy: - set -e - $TRAVIS_BUILD_DIR/pgyer_upload.sh "${TRAVIS_BUILD_DIR}/app/build/outputs/apk/release/app-release.apk" $PGYER_API_KEY

Step5. 打完tag,Travis CI自动构建后,将在蒲公英的控制台看到上传的apk

上传apk到http://fir.im

http://fir.im和蒲公英的一样,都是免费的应用内测分发平台。

Step1. 登录https://fir.im/

Step2. 获取API Token。

Step3. 将获取的API Token配置到Travis CI的环境变量 FIR_API_TOKEN

Step4. 在 .travis.yml文件中,添加如下配置:

代码语言:javascript
复制
before_install: - gem install fir-cli after_deploy: - fir p app/build/outputs/apk/release/app-release.apk -T $FIR_API_TOKEN -c "`git cat-file tag $TRAVIS_TAG`"

Step5. 打完tag,Travis CI自动构建后,将在http://fir.im的控制台看到上传的apk

发送完毕后自动发送邮件通知

虽然Travis CI也有邮件通知功能,但是不能定制模板,通知内容仅仅为提示CI运行的结果,显然更适合开发人员。我们希望最终能以更友好的方式通知团队成员,同时考虑到邮件送达率,可优先选择 Submail、SendCloud等国内邮件发送服务。

这里以Submail为例:

Step1. 注册登录Submail

Step2. 添加发信域名(这需要有自己的域名)

Step3. 创建APPID,并将APPKEY配置到Travis CI控制台的环境变量 SUBMAIL_SIGN

Step4. 创建一封触发式邮件模板

代码语言:javascript
复制
@var(TRAVIS_REPO_SLUG)新版本@var(TRAVIS_TAG)已经发布了,功能更新: @var(TAG_DESCRIPTION) 去下载: https://fir.im/gkq1

Step5. 配置 .travis.yml

代码语言:javascript
复制
- curl -d "appid=14017&to=xucanhui168@gmail.com&subject=[自动通知] 安卓新版本$TRAVIS_TAG发布&project=Cpyvk2&signature=$SUBMAIL_SIGN&vars={\"TRAVIS_REPO_SLUG\":\"$TRAVIS_REPO_SLUG\",\"TRAVIS_TAG\":\"$TRAVIS_TAG\",\"TAG_DESCRIPTION\":\"$(git cat-file tag $TRAVIS_TAG | awk 1 ORS='<br>')\"}" https://api.submail.cn/mail/xsend.json

Step5. 运行结果

本文Demo:https://github.com/xch168/AndroidTravisCI

参考链接

  1. https://avnpc.com/p/197)](https://avnpc.com/pages/android-auto-deploy-workflow-on-travis-ci
  2. http://kescoode.com/travis-ci-android-github-release/
  3. http://www.ruanyifeng.com/blog/2017/12/traviscitutorial.html
  4. https://www.jianshu.com/p/2935b96d3059
  5. https://juejin.im/entry/57070b048ac247004c0e3d8f
  6. https://fandean.github.io/blog/2017/07/31/%E4%BD%BF%E7%94%A8Travis-CI%E6%9E%84%E5%BB%BAAndroid%E9%A1%B9%E7%9B%AE%E5%B9%B6%E8%87%AA%E5%8A%A8%E6%89%93%E5%8C%85%E9%83%A8%E7%BD%B2%E5%88%B0GitHub-Release/
  7. https://www.jianshu.com/p/6dba7d6f79ff
  8. https://www.jianshu.com/p/745bea00dba7
  9. https://www.pgyer.com/doc/view/travis_android
  10. http://blog.fir.im/fir_cli/
  11. https://developer.android.com/studio/build/gradle-tips
  12. https://docs.travis-ci.com/user/languages/android/

近前端届多端框架频出,相信很多有代码多端运行需求的开发者都会产生一些疑惑:这些框架都有什么优缺点?到底应该用哪个?那么有请我们今天的主角:Taro、WePY 、uni-app 、 mpvue 、 chameleon。下面小编将从多个角度详细为大伙分析说明各个框架的优缺点。

何为多端

全包型

这类框架最大的特点就是从底层的渲染引擎、布局引擎,到中层的 DSL,再到上层的框架全部由自己开发,代表框架是 Qt 和 Flutter。这类框架优点非常明显:性能(的上限)高;各平台渲染结果一致。缺点也非常明显:需要完全重新学习 DSL(QML/Dart),以及难以适配中国特色的端:小程序。

这类框架是最原始也是最纯正的的多端开发框架,由于底层到上层每个环节都掌握在自己手里,也能最大可能地去保证开发和跨端体验一致。但它们的框架研发成本巨大,渲染引擎、布局引擎、DSL、上层框架每个部分都需要大量人力开发维护。

Web 技术型

这类框架把 Web 技术(JavaScript,CSS)带到移动开发中,自研布局引擎处理 CSS,使用 JavaScript 写业务逻辑,使用流行的前端框架作为 DSL,各端分别使用各自的原生组件渲染。代表框架是 React Native 和 Weex,这样做的优点有:

  1. 开发迅速
  2. 复用前端生态
  3. 易于学习上手,不管前端后端移动端,多多少少都会一点 JS、CSS

缺点有:

  1. 交互复杂时难以写出高性能的代码,这类框架的设计就必然导致 JS 和 Native 之间需要通信,类似于手势操作这样频繁地触发通信就很可能使得 UI 无法在 16ms 内及时绘制。React Native 有一些声明式的组件可以避免这个问题,但声明式的写法很难满足复杂交互的需求。
  2. 由于没有渲染引擎,使用各端的原生组件渲染,相同代码渲染的一致性没有第一种高。

JavaScript 编译型

像我们今天要介绍的几大框架,它们的原理也都大同小异:先以 JavaScript 作为基础选定一个 DSL 框架,以这个 DSL 框架为标准在各端分别编译为不同的代码,各端分别有一个运行时框架或兼容组件库保证代码正确运行。

这类框架的一个优点是在移动端一般会编译到 React Native/Weex,所以它们也都拥有 Web 技术型框架的优点。这看起来很美好,但实际上 React Native/Weex 的缺点编译型框架也无法避免。除此之外,编译型框架的抽象也不是免费的:当 bug 出现时,问题的根源可能出在运行时、编译时、组件库以及三者依赖的库等等各个方面。

但这并不意味着这类为了小程序而设计的多端框架就都不堪大用。首先现在各巨头超级 App 的小程序百花齐放,框架会为了抹平小程序做了许多工作,这些工作在大部分情况下是不需要开发者关心的。其次是许多业务类型并不需要复杂的逻辑和交互,没那么容易触发到框架底层依赖的 bug。

那么当你的业务适合选择编译型框架时,在笔者看来首先要考虑的就是选择 DSL 的起点。因为有多端需求业务通常都希望能快速开发,一个能够快速适应团队开发节奏的 DSL 就至关重要。不管是 React 还是 Vue(或者类 Vue)都有它们的优缺点,大家可以根据团队技术栈和偏好自行选择。

生态

以下内容均以各框架现在(2019 年 3 月 11日)已发布稳定版为标准进行讨论。

开发工具

就开发工具而言 uni-app 应该是一骑绝尘,它的文档内容最为翔实丰富,还自带了 IDE 图形化开发工具,鼠标点点点就能编译测试发布。

其它的框架都是使用 CLI 命令行工具,但值得注意的是 chameleon 有独立的语法检查工具,Taro 则单独写了 ESLint 规则和规则集。

在语法支持方面,mpvue、uni-app、Taro 、WePY 均支持 TypeScript,四者也都能通过 typing 实现编辑器自动补全。除了 API 补全之外,得益于 TypeScript 对于 JSX 的良好支持,Taro 也能对组件进行自动补全。

CSS 方面,所有框架均支持 SASS、LESS、Stylus,Taro 则多一个 CSS Modules 的支持。

所以这一轮比拼的结果应该是(排序仅为笔者个人结论):

uni-app > Taro > chameleon > WePY、mpvue

下面我们一起来看一张表格:

多端支持度

只从支持端的数量来看,Taro 和 uni-app 以六端略微领先(移动端、H5、微信小程序、百度小程序、支付宝小程序、头条小程序),chameleon 少了头条小程序紧随其后。

但值得一提的是 chameleon 有一套自研多态协议,编写多端代码的体验会好许多,可以说是一个能戳到多端开发痛点的功能。uni-app 则有一套独立的条件编译语法,这套语法能同时作用于 js、样式和模板文件。Taro 可以在业务逻辑中根据环境变量使用条件编译,也可以直接使用条件编译文件(类似 React Native 的方式)。

在移动端方面,uni-app 基于 weex 定制了一套 nvue 方案 弥补 weex API 的不足;Taro 则是暂时基于 expo 达到同样的效果;chameleon 在移动端则有一套 SDK 配合多端协议与原生语言通信。

H5 方面,chameleon 同样是由多态协议实现支持,uni-app 和 Taro 则是都在 H5 实现了一套兼容的组件库和 API。

mpvue 和 WePY 都提供了转换各端小程序的功能,但都没有 h5 和移动端的支持。

所以最后一轮对比的结果是(排序仅为笔者个人结论):

chameleon > Taro、uni-app > mpvue、WePY

下面我们一起来看一张表格:

组件库/工具库/demo

作为开源时间最长的框架,WePY 不管从 Demo,组件库数量 ,工具库来看都占有一定优势。

uni-app 则有自己的插件市场和 UI 库,如果算上收费的框架和插件比起 WePy 也是完全不遑多让的。

Taro 也有官方维护的跨端 UI 库 taro-ui ,另外在状态管理工具上也有非常丰富的选择(Redux、MobX、dva),但 demo 的数量不如前两个。但 Taro 有一个转换微信小程序代码为 Taro 代码的工具,可以弥补这一问题。

而 mpvue 没有官方维护的 UI 库,chameleon 第三方的 demo 和工具库也还基本没有。

所以这轮的排序是(排序仅为笔者个人结论):

WePY > uni-app 、taro > mpvue > chameleon

下面我们一起来看一张表格:

接入成本

接入成本有两个方面:

第一是框架接入原有微信小程序生态。由于目前微信小程序已呈一家独大之势,开源的组件和库(例如 wxparse、echart、zan-ui 等)多是基于原生微信小程序框架语法写成的。目前看来 uni-app 、Taro、mpvue 均有文档或 demo 在框架中直接使用原生小程序组件/库,WePY 由于运行机制的问题,很多情况需要小改一下目标库的源码,chameleon 则是提供了一个按步骤大改目标库源码的迁移方式。

第二是原有微信小程序项目部分接入框架重构。在这个方面 Taro 在京东购物小程序上进行了大胆的实践,具体可以查看文章《Taro 在京东购物小程序上的实践》。其它框架则没有提到相关内容。

而对于两种接入方式 Taro 都提供了 taro convert 功能,既可以将原有微信小程序项目转换为 Taro 多端代码,也可以将微信小程序生态的组件转换为 Taro 组件。

所以这轮的排序是(排序仅为笔者个人结论):

Taro > mpvue 、 uni-app > WePY > chameleon

流行度

从 GitHub 的 star 来看,mpvue 、Taro、WePY 的差距非常小。从 NPM 和 CNPM 的 CLI 工具下载量来看,是 Taro(3k/week)> mpvue (2k/w) > WePY (1k/w)。但发布时间也刚好反过来。笔者估计三家的流行程度和案例都差不太多。

uni-app 则号称有上万案例,但不像其它框架一样有一些大厂应用案例。另外从开发者的数量来看也是 uni-app 领先,它拥有 20+ 个 QQ 交流群(最大人数 2000)。

所以从流行程度来看应该是(排序仅为笔者个人结论):

uni-app > Taro、WePY、mpvue > chameleon

下面我们一起来看一张表格:

开源建设

一个开源作品能走多远是由框架维护团队和第三方开发者共同决定的。虽然开源建设不能具体地量化,但依然是衡量一个框架/库生命力的非常重要的标准。

从第三方贡献者数量来看,Taro 在这一方面领先,并且 Taro 的一些核心包/功能(MobX、CSS Modules、alias)也是由第三方开发者贡献的。除此之外,腾讯开源的 omi 框架小程序部分也是基于 Taro 完成的。

WePY 在腾讯开源计划的加持下在这一方面也有不错的表现;mpvue 由于停滞开发了很久就比较落后了;可能是产品策略的原因,uni-app 在开源建设上并不热心,甚至有些部分代码都没有开源;chameleon 刚刚开源不久,但它的代码和测试用例都非常规范,以后或许会有不错的表现。

那么这一轮的对比结果是:

Taro > WePY > mpvue > chameleon > uni-app

最后补一个总的生态对比图表:

未来

从各框架已经公布的规划来看:

WePY 已经发布了 v2.0.alpha 版本,虽然没有公开的文档可以查阅到 2.0 版本有什么新功能/特性,但据其作者介绍,WePY 2.0 会放大招,是一个「对得起开发者」的版本。笔者也非常期待 2.0 正式发布后 WePY 的表现。

mpvue 已经发布了 2.0 的版本,主要是更新了其它端小程序的支持。但从代码提交, issue 的回复/解决率来看,mpvue 要想在未来有作为首先要打消社区对于 mpvue 不管不顾不更新的质疑。

uni-app 已经在生态上建设得很好了,应该会在此基础之上继续稳步发展。如果 uni-app 能加强开源开放,再加强与大厂的合作,相信未来还能更上一层楼。

chameleon 的规划比较宏大,虽然是最后发的框架,但已经在规划或正在实现的功能有:

  • 快应用和端拓展协议
  • 通用组件库和垂直类组件库
  • 面向研发的图形化开发工具
  • 面向非研发的图形化页面搭建工具

如果 chameleon 把这些功能都做出来的话,再继续完善生态,争取更多第三方开发者,那么在未来 chameleon 将大有可为。

  • Taro 的未来也一样值得憧憬。Taro 即将要发布的 1.3 版本就会支持以下功能:
  • 快应用支持
  • Taro Doctor,自动化检查项目配置和代码合法性
  • 更多的 JSX 语法支持,1.3 之后限制生产力的语法只有 只能用 map 创造循环组件 一条
  • H5 打包体积大幅精简

同时 Taro 也正在对移动端进行大规模重构;开发图形化开发工具;开发组件/物料平台以及图形化页面搭建工具。

结语

那说了那么多,希望能让你在选择框架的同时给你一点意见和启发。小编觉得如果不介意尝鲜和学习 DSL 的话,完全可以尝试 WePY 2.0 和 chameleon ,一个是酝酿了很久的 2.0 全新升级,一个有专门针对多端开发的多态协议。

uni-app 和 Taro 相比起来就更像是水桶型框架,从工具、UI 库,开发体验、多端支持等各方面来看都没有明显的短板。而 mpvue 由于开发一度停滞,现在看来各个方面都不如在小程序端基于它的 uni-app 。