哈啰出行普惠用车 Taro 多端统一技术演进解析

高级前端进阶

共 3330字,需浏览 7分钟

 · 2021-03-18

前言

大家好, 我们是哈啰出行普惠用车前端团队, 在面临诸多业务挑战情况下, 我们团队在2020年all in Taro,  完成了人效与稳定性的提升。本文将分享此技术策略的演进过程。


现状与问题

在2020年上半年, 普惠用车前端团队小程序端主要迭代3个小程序, 哈啰出行微信小程序、哈啰顺风车微信小程序、哈啰出行支付宝小程序。在19年我们已经使用Taro实现了2个微信小程序的代码复用。假设完成顺风车支付宝小程序的需求开发需要4天, 那么3个小程序的人力基本上是这样:



微信顺风车与微信哈啰出行复用同一套代码所以只要开发一端,加上2端测试的时间一共是4人日, 支付宝哈啰出行由于是原生语法需要独立开发4人日, 一共是 4人日支付宝哈啰出行 + 4日的微信 = 8人日, 拆成2个同学做一周可完成迭代, 看上去似乎还可以接受。但是深究其中, 产品想要的效果2端是一样的, 开发却要写2套, 开发与测试人力被浪费了一部分, 2个开发者2种逻辑思路, 如果线上出现问题也要分别排查, 这种情况一直持续到哈啰打车专项..


哈啰打车是2020年哈啰普惠用车团队的新业务, 也是公司重点战略项目, 能够像其他网约车平台一样发布即时单, 目前在珠三角城市陆续开城, 价格优惠. 大家可以进入哈啰出行支付宝小程序和哈啰出行App尝试使用。


哈啰打车是一种新的业务尝试, 产品希望微信与支付宝效果对齐同步迭代, 这就对我们人效提出了巨大的要求, 如果还按照之前2个端2套代码的方式, 哈啰打车一端的前端工作量为85人日, 我们假设先编写支付宝这端, 在开发对业务代码熟悉的情况下按照过往经验推算微信端的代码工作量减半, 那么算下来就是:



一共是 85(支付宝端)+42.5(微信端算支付宝的一半) = 127.5人日, 假设需要在1个月内完成则需要6个同学, 然而, 我们并没有这么多人。产品也不能接受很长的等待时间, 这真是一个挑战. 但好消息是, 打车与顺风车有一些类似的代码。


豪华马车没有五菱宏光快 -- 鲁迅


突破与创新


All in Taro

所以我们决定使用一个能够同时编写支付宝与微信的跨端框架, Taro是我们在19年就在使用的跨端框架, 我们在微信小程序上使用它, 他表现的很好虽然我们只是在微信上使用, 但其与社区接轨的语法和jsx, 给我们的代码增加了不少健壮性。


我们也在19年使用了monorepo的方式实现了2个小程序使用同一套代码, 使得人效提高30%, 我们对它很熟悉, 于是我们决定也在这次的项目中使用它。


Taro已经发布到第三个大版本了, 在比较了一系列数据与综合考量之后, 我们选择最新的Taro3.0。

|               | v3         |  v2  | 
| dist dev size | 2.6M | 416K |
| dist pro size | 272K | 192K |
| package size | (142.5 KB) | 192K |


万事开头难

正如如上所说, 打车与顺风车有一些类似的代码, 但是语法又不太类似, 所以也许我们可以copy过来翻译一下语法, 太好了! 马上开干。

在半小时的复制黏贴之后, 突然发现jsx写错了 似乎是尖括号少了一个那么是哪里呢? 半小时后..

嗯? 还是不对, 忘记导入依赖了? 半小时后..

生命周期居然拼错了.. 好了现在完美了, 第一个页面跑起来了, 等等!? 也就是说我第二个页面第三个都需要重复这个步骤? 真是有些枯燥啊


真正的圣斗士同一份代码不会编写2次 -- 鲁迅


alipay2taro

为什么我们不把这个这个过程自动化呢? 这听起来真不错.


Taro官方的解决方案

taro其实官方带一个转译器taroize, 能把微信小程序转换成jsx, 我们马上尝试了下, 发现他的实现原理与我们的想要的大相径庭,自带一个runtime框架, 变量名称也不好维护.


  • 只能对整个项目

  • 依赖runtime框架

  • 生命周期没有转译

  • 变量名比较奇怪

  • 维护性差


或者? 我们可以学习改造他, 然后编写我们自己的转换器!


我们需要做些什么

我们需要将xml, config, js转换成tsx


首先我们来看看2种语言有什么区别


我们需要:

  • 导入一个react声明,

  • 去掉"Compent"

  • 把data变成state

  • defaultprops变成props

  • onload映射成didmount

  • xml转换成jsx

  • 在render函数中区分props与data

  • 文件名称组件名称统一重命名

  • 引入react声明

  • 区分组件与页面转换区别

  • 等等..


那我们应该怎么做呢?

我们需要解析输入的3种代码, 需要使用到以下工具。


利用这些工具, 创造一个流程

  • 先通过@babel/parser把代码变成json形式的数据结构(AST)

  • 利用@babel/traverse与@babel/types操作刚刚的AST,进行节点删除和移动新增。这部分很重要下面会详细讲。

  • 随后利用@babel/generator再还原回来变成代码

  • 最后使用prettier格式化成可读性强的代码

简单来说就是这样啦.


@babel/types

babel/types提供了节点的各种构造功能, 接下来我会以创建React声明开始做一个示范,


当我们拿到ast之后, 首先我们如何创造一个import的节点的呢?

我们在babel官网上查找他的构造函数



随后调用这个api, 并把它封装成一个方法, 随后调用它, 最后推进body中去.(taro中taroize包的相关实现)。



这样我们就有一个react声明了!


不知道结点是什么类型也没关系 可以在https://astexplorer.net/查询到。


@babel/traverse

traverse能够在AST节点中畅游一番,他会遍历所有的结点你可以自由操作他们, 并改变他们。


遇到CallExpression(函数调用)时候, 我们判断是不是pagex或者是Component调用, 是的话则抓到他的对象.(taro中taroize包的实现)。



parsePage函数就是我们的核心, 我们来实现它。

在上图中我们循环了支付宝js对象中的每个属性, 我们判断是不是要我们转换的, 如果是我们就call相应的节点type的构造函数, 最后一个个推进class中。

至此我们已经解决的大部分的关键问题。


xml? jsx?

对了还有render函数呢, 他可是非常重要. 支付宝中使用xml作为视图逻辑, 所以我们可以使用himalaya-wxml把它转为类似ast的结构, 节点的属性会变成key value结构, 我们继续操作他。


看起来我们完成了所有的工作, 于是我决定封装一个npm包, 使他可以被命令行的方式调用。



沉淀与展望

结局的最后, 是我们用一个月时间与4个同学顺利完成了哈啰打车项目。

另外我们转换复用线上顺风车9个页面, 人效提升1.4倍。3个页面测试阶段没有bug, 平滑的完成了迁移, 现在迭代也只需要1个同学1份代码就能完成。



之后, 哈啰出行普惠用车前端团队也会输出更多关于人效、质量提升幸福感的工具与系统。


2021哈啰出行普惠用车前端团队招人啦! 好业务, 有挑战! 广阔天地任君发挥, 欢迎各位小伙伴加入!

简历发至gujiacheng07691@hellobike.com


The End

如果你觉得这篇内容对你挺有启发,我想请你帮我三个小忙:

1、点个 「在看」,让更多的人也能看到这篇内容

2、关注官网 https://muyiy.cn,让我们成为长期关系

3、关注公众号「高级前端进阶」,公众号后台回复 「加群」 ,加入我们一起学习并送你精心整理的高级前端面试题。

》》面试官都在用的题库,快来看看《


“在看”吗?在看就点一下吧
浏览 52
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报