热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

基于weex的有赞无线开发框架

出于对开发效率和动态化的要求,无线端的开发框架也一直在更新,从Hybrid、结构化NativeView、ReactNative、Weex,

出于对开发效率和动态化的要求,无线端的开发框架也一直在更新,从 Hybrid、结构化 Native View、React Native、Weex,再到现在正在大受关注的 Flutter。什么样的框架才是适合自己的团队?不仅要有技术追求,而且要考虑实际业务需要。最近,有赞移动选择了 weex 作为无线开发框架,搭建了从开发、Debug、构建、发布、数据一个闭环的流程。本文将对此进行分享。

开发闭环

一、什么是 weex

Weex 是阿里巴巴开源的一套构建高性能、可扩展的原生应用跨平台开发方案。首先总结一下 weex 的特点:

  1. 页面的开发目前支持Rax和Vue

    Weex 也不是只支持 Vue 和 Rax,你也可以把自己喜欢的前端框架集成到 Weex 中,有一个文档扩展前端框架描述了如何实现,但是这个过程仍然非常复杂和棘手,你需要了解关于 js-native 之间通信和原生渲染引擎的许多底层细节。

  2. 一次编写,三端(Android、iOS、前端)运行

    前提是都集成了 weex sdk,另外视觉表现做不到完全一样,有的会有一些差异,需要做一下适配。所以写 weex 页面的时候,如果支持三端,便需要在三端都进行自测。

  3. UI 的绘制通过 native 的组件,Javascript 逻辑在 JS 引擎里运行,两者通过 JavascriptCore 通信

    weex 里使用组件都需要在 native 端注册,这样 weex 里才可以使用,运行的时候通过注册时记录的 map 进行查找。weex sdk 内置注册了一些基础的组件,包括 list、text、input 等。WXJSCoreBridge 封装了 JavascriptCore 实现 native 和 js 之间的通信。

  4. 支持 Native 扩展

    可以将 native 的 UI 组件封装成 component,将 native 的逻辑代码封装成 module。从而在 weex 里可以进行使用。这里的 natiev UI 组件包括 modal、webview、image 等,这里的 native 逻辑代码包括 storage、network 等。

  5. 每个 weex 页面会被打包成一个 js 文件,weex sdk 将 js 文件渲染成一个 view
    weex 的打包通过 webpack,将每个页面打包成独立的一个 js 文件,weex sdk 会将 js 进行解析,将 UI 部分绘制成一个 view, 再绑定 view 的事件与 js 代码绑定。

二、为什么要使用weex进行无线开发

1. 效率问题

1)开发的人力成本

如果不算 web 端,一个页面本来需要 Android 和 iOS 2 个人开发;使用 weex 后只需要 1 个开发页面。

2)开发的编译速度

随着项目渐渐变得庞大,Android 项目一次编译需要 2-3 分钟,机器不好的还需要 10 分钟,iOS 可能会快一点,也需要 1-2 分钟。使用 weex 后,界面修改,只需要十几秒

3)测试效率

提测之后,发现 bug,修复完成,测试总需要重新下载一个包进行安装;使用 weex 后,跟原生无关的 bug,只要测试重启 App 就可以进行验证。

2. 动态化

weex 页面最后打包完是一个 js 文件,只要能做到动态下发 Javascript,那便可以实现动态化,可以热修复,甚至可以热部署,完全替换或者新增页面。

3. 成熟度

在 2016 年阿里双十一中,Weex 在阿里双十一会场中的覆盖率接近 99%,页面数量接近 2000,覆盖了包括主会场、分会场、分分会场、人群会场在内几乎所有的阿里双十一会场业务。阿里双十一主会场秒开率97%,全部会场页面达到 93%。
2016 年 12 月 15 日,阿里巴巴宣布将移动开源项目 Weex 捐赠给 Apache 基金会开始孵化。
2017 年,weex 在阿里业务里增长如下图,来自 WeexConf 2018。

阿里业务增长

4. 接入成本

经过实践,一个移动端开发,一周时间就可以开始进行使用 weex 进行业务开发。

三、如何使用 weex 进行无线开发

weex 其实是一套方案,各个流程很多东西需要自己建设,把它建设得让小伙伴可以以较小成本开始使用 weex,把它建设得融入已有的系统。这方面,我们目前做了下面这几个方面,还任重道远。

zanweex 建设

1. 开发工具 zweex-toolkit

这是一个脚手架工具,基于 weex 官方的 weex-toolkit,用于新建 weex 工程,目前只支持 vue。

随着页面的增多,业务的复杂,工程会慢慢变得庞大,每次运行的时候如果全部页面都运行起来比较慢。为了解决这个问题,使用 zweex-toolkit 创建建的工程模板支持运行的时候,支持只运行指定目录下的页面,只要在 npm start 后加上参数即可,如:

npm run start hi,helloworld

这样就表示只运行 hi 目录下和 helloworld 下的页面。
另外,我们支持:

  • 新增页面zweex page
  • 开启调试zweex debug

2. ZanWeex SDK 的实现

官方 weex sdk 做的事情,就是输入一个 js 文件,然后返回一个view。考虑到每个应用的路由和个性化的需要,这一点,ZanWeex SDK 没有做其他工作,也还是返回了一个view,业务方可以根据自己的需要将view添加到自己想要展示的地方。ZanWeex SDK 做的事情主要有如下几方面:

1)支持下发配置,支持动态化,可以完成整个页面的替换

weex 页面打包后的结果是一个 js 文件,所以可以进行下发进行动态更新,那么就需要有一份配置,来关联页面路由和 js 文件的关系,于是我们设计了这样的数据结构:

h5:页面路由地址,可以直接使用发布平台生成的 h5 地址

js:打包后的 js 文件地址

version:支持的最低 App 版本,因为新页面如果需要 native 扩展,那就需要发布新版本进行支持

md5:为了校验完整性,我们在配置里添加每个 js 文件的 md5。

2)支持多模块独立配置,互不影响
一个App里会有多个模块,每个模块可能由独立的团队进行负责,所以为了减少耦合,我们将配置独立,每个模块可以独立管理自己的配置,独立接入weex,不依赖于宿主App。

3)预加载页面模板,支持页面模板缓存和配置缓存

  • 如果没有缓存,每次都从服务端拉取页面模板,那么是不可能达到秒开的,跟没有做缓存的H5页面就区别不大了。我们SDK会预加载页面模板到本地,打开过的页面会缓存到内存。这样渲染的时间就更接近原生的渲染时间了。

4)支持开发时的hot reloading,前端开发般的体验

  • 如果没有hot reloading,那么每次修改完页面,都得退出页面重新进入。为了省去这个操作,hot reloading是必须的。
  • weex 工程里本地开发时候,通过webpack-dev-server来启动一个websocket,zan weex sdk 打开一个weex页面后,去与它建立连接。webpack-dev-server将工程的编译状态发送给ZanWeex SDK,当接收到渲染完成的指令时,就重新渲染页面,从而达到 hot reloading的目的。

5)支持页面的适配,提供环境变量
ZanWeex SDK 会提供以下四个变量共 weex 页面使用,方便完成页面配置。

  • 容器的高度:weex.config.yzenv.viewHeight
  • 容器的宽度:weex.config.yzenv.viewWidth
  • 状态栏高度:weex.config.yzenv.statusBarHeight
  • 底部栏高度(针对iPhone X,其他为0):weex.config.yzenv.bottomHeight

6)开发阶段日志的查看
在开发阶段,weex sdk 源码里输出的日志以及 js 里通过 console.log 输出的日志,还有 js 运行的报错,都只能通过 XCode 和 Android Studio 进行查看。这对于一个只了解一端的开发人员是非常不方便的。于是我们做了一个入口,在打开 weex 页面的时候,会显示该入口,点击即可查看所输出的日志。

7)参数传递
正向传参:从 A 页面跳转到 B 页面,参数传递是开发过程肯定会遇见的一个场景。SDK 对外提供的渲染接口 renderByH5 的参数包括 url,params,data。业务方进行渲染的时候,可以将参数直接跟在 url 后面,或者通过 params、data 传入,不同方式,取的方式也不一样:

  • url 后面的参数,会传入 data,weex 页面里直接在 data 里定义参数就会自动赋值;
  • params的参数,在 weex 页面里可以通过 weex.config.name 来获取;
  • data 传入的参数,获取方式同第一种。
  • 反向传参:从 B 页面返回到 A 页面的时候,携带参数返回也是很常见的一个场景。SDK 提供了统一的存储类 ZParamStorage 来临时存储参数。页面 B 要返回的时候先把数据存入存储区,A 页面显示的时候再从存储区获取,然后清空存储区。
  • 非跳转的参数传递:weex 页面之间,可以采用 BroadcastChannel 进行传参,weex 与 native 之间的传递可以通过自己封装 Module 进行实现。

3. 页面的开发

前面有提到,weex 的页面目前可以采用 vue 或者 Rax 编写。对于 Vue 和 Rax 的语法这里不做陈述。这里主要总结了容易在实际开发中卡住小伙伴的几个问题。

1)如何判断一个页面是否用 weex 来实现?

可以认为所有的新页面都可以采取 weex 来开发,区别在于这个页面使用的 native 能力有多少。可以通过自定义 Module 来调用 native 的能力,通过自定义 component 来使用 native 的组件;

2)什么时候需要自定义 Module?

  • 需要原生的能力的时候,比如:

    • 要调用系统选择图片的接口
    • 调用打电话、发短信的功能
    • 打开其他应用
  • 调用已有的业务逻辑,比如:

    • 加密、解密逻辑
    • 登录逻辑

3)什么时候需要自定义 component?

  • 如果一个组件已经使用 native 实现,为了保持统一一致,那么可以将原有的组件封装成 component
  • 如果一个组件不能使用 weex 实现,比如地图组件、超长图显示等

4)多个弹层的布局如何实现?

weex 页面渲染的层级,是从上而下的,越在下面的布局,显示越上层。所以要作为弹层的布局,就把它放到最下面。

5)页面的动画如何实现?

官方 weex sdk 已经封装了 animation 的 module 可以直接使用,复杂的动画可以使用 BindingX 实现。

6)weex 的代码如何复用?

代码都可以抽离出组件。

  • 作为一个 UI 组件,抽离成一个组件,向外暴露属性参数和事件接口;
  • 作为独立的 js 函数,抽离成一个 js 供其他页面引入;
  • css 样式也可以抽离成一个 css 文件,供其他页面引入;
  • 如果包含多个组件形式,可以通过 mixins 来引入。

4. 构建和打包平台

我们开发了以项目为单位的构建平台:

  • 每个项目可以添加多个分支,可以是不同仓库的分支。因为一个项目有可能是跨团队跨模块的,但是需要一起发布。
  • 构建通过 webpack 构建,构建之后,支持发布线下存储和线上 cdn

我们还开发了以应用为单位的 weex 发布平台:

  • 这里的应用是一个抽象概念,不是传统的“应用”,可以理解成模块
  • 业务方可以在构建平台构建完成后,一键跳转到发布平台进行发布,除了需要第一次填写最低支持的版本号,其他均无需操作。
  • 发布平台支持灰度发布、全量发布和回滚。
  • 发布平台会展示 weex 在端上的使用情况,渲染时间、渲染错误、下载时间等

四、遇到的问题以及解决方案

在开发过程中,很多问题,可以通过阅读源码来解决,比如:

  • 使用 iconfont 的时候,是否已支持缓存?

    答:已支持,包括内存缓存和文件缓存,内存缓存使用 familyname 来做 key,文件缓存使用 md5(url) 来做本地文件名

  • module实现的函数能不能返回参数?

    答:module 的函数氛围 UIThread 和 JSThread,JSThread 对于 js 线程来说是同步的,支持直接返回参数;UIThread 对于 JS 线程来说是异步的,不支持直接返回参数,只能使用 callback

另外,很多常见的问题,我们已经在 ZanWeexSDK 进行了解决,包括实现动态化、多模块的支持、缓存管理、Hot Reloading、日志查看、页面适配、参数传递等。

此外,还会有一些常见的问题,在此罗列一下:

  1. 配置的更新机制是怎样的?更新失败,如何打开 weex 页面?

    答: 配置的更新接口开放给业务方调用,由业务方决定什么时候调用更新接口;SDK 里做了三种处理,来尽量保证配置可以更新成功:

    1)配置接口拉取失败后,会有三次重试;

    2)网络从无网变成有网时,sdk 会检查配置是否已拉取,如果未拉取就主动拉取

    3)允许业务方内置配置和 js 文件,当拉取失败后,SDK里会从内置配置里读取

  2. 配置的版本管理是怎样的?

    答:配置每次发布的时候,都会指定该发布支持的 App 最低版本号。每次请求,会携带 App 版本号,服务端只会返回符合该版本号的最新配置。

  3. 支持不支持屏幕旋转?

    答:答案是支持的。旋转之后,屏幕变成了横屏,weex 就按照横屏的尺寸来渲染,问题是只要你写的页面符合这种变化就可以了,跟 native 来实现页面没有什么区别。

五、未来还要继续做的事情

  1. 组件库的建设
  2. 性能统计,比如帧率、内存、CPU
  3. 配置和js文件的增量更新、推送更新
  4. 降级处理

图片描述



推荐阅读
  • 唱唱反调:风口上的技术不要盲目追
      对于前端领域的开发者来说,“学不动了”虽然更多是一种调侃,但也真实地反映出了他们面对频繁出新的前端技术时又爱又恨的心情。在经历了移动互联网的大爆发后,前端领域的边界不 ... [详细]
  • Flutter 布局(四) Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth详解
    本文主要介绍Flutter布局中的Baseline、FractionallySizedBox、IntrinsicHeight、IntrinsicWidth四种控件,详细介绍了其布局 ... [详细]
  • Mac OS 升级到11.2.2 Eclipse打不开了,报错Failed to create the Java Virtual Machine
    本文介绍了在Mac OS升级到11.2.2版本后,使用Eclipse打开时出现报错Failed to create the Java Virtual Machine的问题,并提供了解决方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 1,关于死锁的理解死锁,我们可以简单的理解为是两个线程同时使用同一资源,两个线程又得不到相应的资源而造成永无相互等待的情况。 2,模拟死锁背景介绍:我们创建一个朋友 ... [详细]
  • 《数据结构》学习笔记3——串匹配算法性能评估
    本文主要讨论串匹配算法的性能评估,包括模式匹配、字符种类数量、算法复杂度等内容。通过借助C++中的头文件和库,可以实现对串的匹配操作。其中蛮力算法的复杂度为O(m*n),通过随机取出长度为m的子串作为模式P,在文本T中进行匹配,统计平均复杂度。对于成功和失败的匹配分别进行测试,分析其平均复杂度。详情请参考相关学习资源。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • 单页面应用 VS 多页面应用的区别和适用场景
    本文主要介绍了单页面应用(SPA)和多页面应用(MPA)的区别和适用场景。单页面应用只有一个主页面,所有内容都包含在主页面中,页面切换快但需要做相关的调优;多页面应用有多个独立的页面,每个页面都要加载相关资源,页面切换慢但适用于对SEO要求较高的应用。文章还提到了两者在资源加载、过渡动画、路由模式和数据传递方面的差异。 ... [详细]
  • 用Vue实现的Demo商品管理效果图及实现代码
    本文介绍了一个使用Vue实现的Demo商品管理的效果图及实现代码。 ... [详细]
  • 本文概述了JNI的原理以及常用方法。JNI提供了一种Java字节码调用C/C++的解决方案,但引用类型不能直接在Native层使用,需要进行类型转化。多维数组(包括二维数组)都是引用类型,需要使用jobjectArray类型来存取其值。此外,由于Java支持函数重载,根据函数名无法找到对应的JNI函数,因此介绍了JNI函数签名信息的解决方案。 ... [详细]
  • 本文讨论了将HashRouter改为Router后,页面全部变为空白页且没有报错的问题。作者提到了在实际部署中需要在服务端进行配置以避免刷新404的问题,并分享了route/index.js中hash模式的配置。文章还提到了在vueJs项目中遇到过类似的问题。 ... [详细]
  • 腾讯T3大牛亲自教你!2021大厂Android面试经验,经典好文
    本篇将由环境搭建、实现原理、编程开发、插件开发、编译运行、性能稳定、发展未来等七个方面,对当前的ReactNative和Flutter进行全面的分析对比, ... [详细]
  • Flutter第六章(BottomNavigationBar ,AppBar,TabBar ,TabController 以及案例)
    版权声明:本文为作者原创书籍。转载请注明作者和出处,未经授权,严禁私自转载,侵权必究!!!情感语录:如果你想得到从未拥有过的东西,那么你必须去做从未做过的事 ... [详细]
  • 本文记录了在vue cli 3.x中移除console的一些采坑经验,通过使用uglifyjs-webpack-plugin插件,在vue.config.js中进行相关配置,包括设置minimizer、UglifyJsPlugin和compress等参数,最终成功移除了console。同时,还包括了一些可能出现的报错情况和解决方法。 ... [详细]
author-avatar
记忆簿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有