跨平台技术实践案例: 用 reactxp 重写墨刀的移动端

Authors:  Gao CongPerry Poon

Illustrators:  Shena Bian

April 20, 2019

重新编写,又一次,我们又一次重新编写了移动端应用和移动端网站。要重新编写是一个风险很大的决定,但是其必要性以及它所带来的收益是我们无法拒绝的。这篇文章会分享我们为什么这么做,我们是怎么做的,以及这次重写后为我们带来了什么收获。如果你也正在经受和我们一样的遭遇,希望这个分享会带来帮助。

欢迎在 https://org.modao.cc/downloads 下载应用及访问 https://org.modao.cc/mobile 体验我们全新的移动端应用、网站

动机

团队的处境是,我们有使用 Swift 开发的 iOS 客户端,基于 React Native 的 Android 客户端,以及应对国内庞大的微信生态的移动端网站。而墨刀的技术团队保持着精简的人员结构,团队成员不足10人,同时我们的技术栈也主要分布在 JS 和 Ruby,没有全职移动客户端经历的成员。维护这三个相互独立的应用对我们来说是一件成本极高的事情。

墨刀在18年开始了 To B 的更进一步转变-墨刀企业版的开发。新的版本中由于全新的产品架构,应用自然而然地也要经历大规模的改变。同时,在新版中,我们开始更近一步地使用了我们自己的设计系统,而新的设计语言涵盖了用户在各平台的使用场景,这是一套体验、界面一致的设计规范。

因此,重新开发,统一墨刀的移动端应用,移动端网站成为了一件自然而然的想法。于是我们开始了对这一想法的实践。

找到一个可行的方案

为了满足我们同时支持的三个平台愿景,一番搜索后这几个框架进入了我们的视野:

如雷贯耳的 React Native 和如日中天的 Flutter 就不再介绍了,我们重点介绍下 ReactXP。ReactXP 是微软的 Skype 团队研发的框架,它的官方介绍其似乎是一种究极的跨平台解决方案,在兼容 iOS、Android 和 web 的同时甚至还兼容了 Windows 桌面应用开发。相较于 React Native 配合 React Native for Web 的那种需要在构建过程做些定制化才能实现的写一次,部署到各个平台的方式,ReactXP 则更为彻底,开发者几乎不需要做什么的配置就达到目的。这是一个很吸引人的点。而 Flutter 对 web 的支持目前未实现。所以在跨平台这一特性上,ReactXP 引起了我们的注意。

为了刚进一步地了解 ReactXP,我们通读了 ReactXP 的源码。ReactXP 的源码其实不多,而且文件结构清晰,很容易了解。我们发现 ReactXP 在移动端其实只是一个抽象层,使用 TypeScript 开发。它在 web 上使用 React,Native 上使用 React Native,自己实现一套类似于 React Native 风格的 API。而功能上基本实现了 React Native 的各种组件及 API。构建方案在 Native 端用的就是 React Native 自带的打包工具 Metro,而在 web 端是 webpack。在最终的产出时,在 native 平台则会打包出 .app 和 .apk;在 web 平台则是前端开发最熟悉的 SPA。同时,ReactXP 采用插件的形式,官方实现了一些跨平台的组件以满足更进阶的使用需求。而前面介绍到,墨刀团队在 React Native 上已经做过一个完整功能的原生应用,需求已被证明可以被满足,该踩的坑我们都已经填过,因此采用这个方案我们也能更有自信。

于是,我们便使用 ReactXP 开始对整个应用的重新编写。

过程比较流畅,但并非一帆风顺

因为有过之前的 React Native 使用经验,同时应用的主要功能没有发生变化,所以开发起来相对容易一些,但是我们也遇到了大大小小的问题,在这里分享一些令我们印象较深的以及我们的解决办法。

第三方的模块大多不是跨平台的

这个是我们最先遇到的问题。在引用了 react-native-wechat 来完成微信登录需求时,在 web 端首先就遇到了构建失败的问题,这也是跨平台开发中会经常碰到的问题,因为大多数的模块设计之初也没有考虑到这种跨平台的使用场景。

前面提到过 ReactXP 在 web 端使用的是 webpack 作为构建工具,于是我们想起来了 webpack 的 alias 特性。简而言之就是给模块一个别名,比如

# webpack.config.js
const WEB_MODULE_ALIAS_PATH = path.join(__dirname, ‘..‘, ‘..‘, ‘web‘, ‘alias‘)

module.exports = {
  resolve: {
    alias: {
      ‘react-native-wechat$‘: path.resolve(WEB_MODULE_ALIAS_PATH, ‘react-native-wechat.ts‘),
    },
  },
}

有了这样的配置后,webpack 就会在引用 react-native-wechat 的地方转而引用 /web/alias/react-native-wechat.ts。这样就允许我们在这个单独的文件中为 web 端 patch 掉 react-native-wechat

而有些时候采用这种方式向着一方 patch 接口是件很难实现的事。比如为了达到更好的用户体验和开发效率,我们为 native 选用了 React Navigation 而在 web 上使用 React Router。但是他们的 API 几乎没有一样的地方,于是我们采用了分文件的写法,如 router.tsx 和 router.web.tsx,同样采用 alias 的方法。二者都暴露出一个接口一致的组件,这样就能够满足跨平台的要求。

ReactXP 有对应用很多限制

在列表组件中,ReactXP 为了达到跨平台的目的而禁用了 RefreshControl 这个基本组件的使用,但这个是不能满足我们的下拉更新的需求。通过阅读源码我们发现 ReactXP 在调用 React Native 的 FlatList 组件时屏蔽掉了 RefreshControl 这个 Props,于是我们直接在 native 平台使用 React Native 的 FlatList 模块。

这类问题也发生在了样式中。在使用百分比形式的长度时,比如 width: ‘80%‘,TS 的类型检查就会报出不支持的类型错误。搜索后发现这是 ReactXP 因为性能原因而有意为之。但在实现一些设计时百分比是一个绕不开的话题,如果运行时手动用 js 计算又显得有些繁琐。同样阅读源码我们发现这种禁用只是在类型中,实际 ReactXP 在调用底层框架时依旧是将百分比的值传了下去。因此我们便能够自信地在不可避免的地方采用百分比的值还原设计。

React Native 的样式在一些地方不符合 CSS 的标准

在带阴影的圆角矩形的实现上,我们发现在 overflow: ‘hidden‘ 的时候 box-shadow 在 native 平台是不生效的。其实这个问题和 ReactXP 无关,而是 React Native 遵循了 iOS 的渲染方式才出现了这个与 CSS 规范不相符的表现。但在编写跨平台的组件时,这个问题就变得非常明显。其实解决办法也很简单,就是再加一层 wrapper,在它身上应用 shadow 和设置 overflow 为 visible,而在自身节点控制圆角。

IconWrapper: RX.Styles.createViewStyle({
  shadowOffset: {
    width: 0,
    height: 3,
  },
  shadowRadius: 8,
  shadowColor: ‘rgb(0, 0, 0)‘,
  shadowOpacity: 0.1,
  overflow: ‘visible‘,
}),
Icon: RX.Styles.createViewStyle({
  elevation: 5,
  borderRadius: 9,
}),

带来的收获

虽然经历了种种的坑,但一个个填平后,ReactXP 为我们指引的这条路还是挺宽敞明亮的。我们共计两位开发,其中一名是之前没有移动开发经验的同事,在经历满打满算的5个月后,使用一套代码开发出了横跨3个平台的移动端应用并顺利发布。同时也保持着良好的用户体验。而这其中的在解决技术难题的时间其实只占了不到 30% 的时间。重要的是我们今后只用维护这一份代码,这是我们梦寐以求的。



跨平台应用虽然问题多多,但是并不是一条走不通的路。我们之所以能够成功使用 ReactXP 来完成我们的目标,很大原因是因为 ReactXP 并没有重造轮子,而是站在 React 和 React Native 这个两个巨人的肩上,使得我们在遇到问题时很容易地在适当的地方找到解决办法,而不是去花更多的时间去学习一个全新的体系。这也帮助我们降低了重新编写而带来的风险。

如果你也对跨平台抱有希望,那么尝试一下 ReactXP 吧,或许它也能让你从维护多平台的困境中解脱出来。

嘿,这儿是墨刀技术团队的官方网站,你会在这里发现墨刀背后的技术故事。

在 GitHub 上关注我们

原文地址:https://www.cnblogs.com/productcompass/p/10777103.html

时间: 2024-08-30 06:10:24

跨平台技术实践案例: 用 reactxp 重写墨刀的移动端的相关文章

【新书推荐】《微软开源跨平台移动开发实践》带你走近微软开源开源跨平台技术

上周收到本书作者李争送的一本12月份的新书<微软开源跨平台移动开发实践——利用ASP.NET Core 1.0 .Apache Cordova.Xamarin和Azure快速构建移动应用解决方案>.这本书的名字超长.这本书也是超薄,只有220页,一个周末时间就读完了,但是这本书的内容确是超丰富,浓缩了微软这三年向开源和跨平台领域的转变,微软在开源和跨平台领域构建出来的一套技术体系.从服务端的NET Core.ASP.NET 和 Web APi ,到Web端的 Typescript脚本语言,再到

【新书推荐】《微软开源跨平台移动开发实践》--带你走近微软开源开源跨平台技术

上周收到本书作者李争送的一本12月份的新书<微软开源跨平台移动开发实践——利用ASP.NET Core 1.0 .Apache Cordova.Xamarin和Azure快速构建移动应用解决方案>.这本书的名字超长.这本书也是超薄,只有220页,一个周末时间就读完了,但是这本书的内容确是超丰富,浓缩了微软这三年向开源和跨平台领域的转变,微软在开源和跨平台领域构建出来的一套技术体系.从服务端的NET Core.ASP.NET 和 Web APi ,到Web端的 Typescript脚本语言,再到

《SaltStack技术入门与实践》—— 实践案例 &lt;中小型Web架构&gt;3 Memcached配置管理

实践案例 <中小型Web架构>3 Memcached配置管理 本章节参考<SaltStack技术入门与实践>,感谢该书作者: 刘继伟.沈灿.赵舜东 Memcached介绍 Memcached是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态数据库驱动网站的访问速度.Memcached基于一个存储键/值对的hashmap.其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通

王晶:华为云OCR文字识别服务技术实践、底层框架及应用场景 | AI ProCon 2019【华为云技术分享】

演讲嘉宾 | 王晶(华为云人工智能高级算法工程师王晶) 出品 | AI科技大本营(ID:rgznai100) 近期,由 CSDN 主办的 2019 中国AI 开发者大会(AI ProCon 2019)在北京举办.在计算机视觉技术专题,华为云OCR人工智能高级算法工程师王晶分享了“文字识别服务的技术实践.底层框架及应用场景”的主题演讲. 演讲的第一部分,他分享了文字检测和识别的基础知识以及难点和最新进展.第二部分是华为云文字识别服务关键能力.关键技术,以及落地过程中遇到的“坑”,这对其他人工智能产

ASP.NET跨平台最佳实践

前言 八年的坚持敌不过领导的固执,最终还是不得不阔别已经成为我第二语言的C#,转战Java阵营.有过短暂的失落和迷茫,但技术转型真的没有想象中那么难.回头审视,其实单从语言本身来看,C#确实比Java更优秀(并非C#天生丽质,而是它站在了巨人的肩膀上). 本文并非为.NET正名而来,而仅仅是分享作者近几年在ASP.NET跨平台方面的研究与实践经验,算是对八年的.NET之路作一个阶段性的总结. .NET技术自诞生以来,便一直因其跨平台能力差而广受诟病.这里面有微软有意为之,也有别有用心之人在混淆视

移动端跨平台技术总结

概述 曾经大家以为在手机上可以像桌面那样通过 Web 技术来实现跨平台开发,却因为性能或其他问题而放弃,不得不针对不同平台开发多个版本.这也违背了跨平台开发的初衷.而React Native让跨平台移动端开发在次回到人们的视野中,其成功的原因除了他"一次编写处处运行",还因为它相比h5等前端技术,有了更接近原生的体验. 为了方便理解,笔者将跨平台技术分为4大流派: Web 流:也被称为 Hybrid 技术,它基于 Web 相关技术来实现界面及功能 代码转换流:将某个语言转成 Objec

Druid 在小米公司部分技术实践

引言:Druid作为一款开源的实时大数据分析软件,自诞生以来,凭借自己优秀的特质,不仅逐渐在技术圈收获了越来越多的知名度与口碑,并且陆续成为了很多技术团队解决方案中的关键一环,从而真正在很多公司的技术栈中赢得了一席之地. 本文通过对小米公司技术团队对Druid 的实践案例与经验的介绍,让大家对Druid有更加全面和深入的了解,希望能够帮助你事半功倍地学习Druid 这项年轻的技术. 本文选自<Druid实时大数据分析原理与实践>. 小米公司正式成立于2010 年4 月,是一家专注于高端智能手机

探寻百度AI3.0背后的技术实践

2018年7月28日,安卓绿色联盟携手百度联盟和华为终端开放实验室共同举办的<探寻百度AI3.0背后的技术实践>主题技术沙龙在北京西二旗华为大厦圆满落幕.来自百度简单搜索.百度安全.百度AIG.百度地图.百度云的五位资深技术专家围绕AI这个主题进行了精彩的技术分享,吸引了近200名开发者现场参与. 1.简单搜索中的技术架构和人工智能落地 百度资深安卓研发工程师高扬从事多年安卓和移动端的开发工作,目前主要专注于简单搜索的Android端架构以及人工智能的技术落地. 高扬表示,现阶段人工智能相关的

腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践

本文来自腾讯前端开发工程师" wendygogogo"的技术分享,作者自评:"在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦." 1.GIF格式的历史 GIF ( Graphics Interchange Format )原义是"图像互换格式",是 CompuServe 公司在1987年开发出的图像文件格式,可以说是互联网界的老古董了. GIF 格式可以存储多幅彩色图像,如果将这些图像((https://www.q