爱收集资源网

冯地木:适配小程序的神奇方案

网络整理 2023-10-02 03:03

作者简介

#8:5:c:7:9:f:a:6:a:6:d:1:a:d:3:b:c:5:0:1:a:9:0:a:1:2:a:1:8:5:4:5#

冯地木

去哪里网后端技术经理

08年开始从事后端工作,曾就职于人人网、新浪微博、爱奇艺等,12年加入去哪里网,主导多次后端技术构架升级,深化Node前后端分离,React,RN等技术构架在业务上的落地应用,擅长各类后端性能优化和工程化实践,目前负责推动Qunar的多端统一化升级方案。

#2:b:f:d:2:6:e:9:7:f:2:0:1:e:6:9:4:d:0:a:6:7:a:4:c:c:6:f:4:e:7:1#

孟晨

2019年加入去哪里网,擅长多种前后端语言,主要负责Node工程化,规范化工作,现阶段工作重心为多端统一框架的开发与推广。

#4:3:f:1:2:7:c:0:4:7:6:a:f:f:6:5:2:1:6:d:0:6:8:9:e:6:f:9:6:a:2:6#

王佳峰

2019年加入去哪里网,主要负责公共产品业务向RN技术栈迁移以及主流程RN工程向三端工程迁移。主要涉及React-Native、Touch、小程序业务开发和多端融合框架等基础构架的研制。

1序言

qrn-remax-unir是由去哪里网后端技术团队实现的一套将RN适配到小程序端的跨端组件,通过该组件库可快速便捷的将RN源代码直接运行到小程序端。方案参考了react-native-web的适配方案,使用remax框架来实现适配组件库并达到适配多小程序的目的。和react-native-web一样,它对RN源代码侵入度低,但是调试和替换组件相当便捷。

方案来自于社区,我们只是合理的应用拿来解决我们遇见的业务问题,最终开发了这套组件库,也希望开源下来跟你们分享和共同阐述多端开发之路。

下边我们简单介绍下RN到小程序的适配方案和适配组件库的点滴。

2多端方案回顾

qrn-remax-unir组件库是整个去哪里网跨端方案的一个部份,通过整套方案可实现将RN代码直接运行到H5和小程序,达到跨IOS,ADR,H5,小程序的目标。整体多端方案的思路是:

使用react-native-web将RN代码适配到H5上运行,这也是RN官方推荐和集成的形式。

在remax组件的基础上实现一套RN的组件库,借用remax来适配到多端(qrn-remax-unir)。

利用webpack的特点来实现针对不同平台的打包。

#3:5:b:c:e:4:b:3:7:7:1:d:5:a:d:2:4:5:a:9:e:a:0:c:6:2:6:a:b:c:2:2#

3RN相关多端方案3.1对alita的督查

在最初的督查中我们注意到alita可以实现将ReactNative转换到陌陌小程序运行,也对方案进行了详尽的督查:

alita会在编译阶段将JSX句型根据代码块编译成陌陌wxml的碎片,之后用templete包裹;

内部实现了一个mini-react来对接适配react和小程序的生命周期。

详尽原理可参考:

于是跑了些demo对方案进行使用认为还是跟我们的期望有些差别:

尽管期望是对RN代码无入侵,但还是会对RN源码有限制的,部份特点不能用,动漫之类的要求用alita提供的自定义动漫库;

内部使用了自定义的mini-react来对接react和小程序的生命周期,考虑后期对react新特点的适配进度风险;

专注于RN到陌陌小程序的转换,对其他小程序不支持。

基于以上缘由我们最终没有直接使用该方案,督查过程觉得她们对jsx模板的处理思路还是很新颖的,是挺好的借鉴。

3.2remax简单原理

remax可实现在小程序中用真正的react进行开发。remax将自己实现成了一个react的渲染器,搜集寄主UI变更指令生成页面VNode树,之后在小程序渲染层渲染这个树。

详尽原理可参考:

因为基于运行时适配的方案,有以下异同点:

适配在react虚拟dom之上,对react的技术栈无任何限制,redux,mobx,hooks等都可自由使用;

模板的动态处理在渲染的时侯可能效率低下,须要针对性解决;

因为没有编译处理,运行时都是平台源代码,查问题更便捷;

基于react组件,可以挺好的对小程序原生组件进行支持;

并没有提供对各个小程序的跨端组件,只对部份基础组件进行了封装和适配。

4我们的适配方案

remax其实支持remax的句型,而且他是基于自定义组件提供的句型DSL,提供的组件和RN也没有任何关系。但她们对react句型适配到小程序的方案还是很大胆实用的,也启发我们可以根据类似的适配方案来实现RN组件到小程序的适配,这样就可以将RN运行到小程序了。

4.1ReactNative到remax组件

督查remax的适配方案,尽管方案原理说上去很简单,而且真正要做如此一套东西评估了下还是十分历时耗力的。

重新评估出来,发觉remax虽然早已可以做到react到小程序的适配,且提供了基础的几个跨端组件可供使用。我们直接用remax组件来实现RN的组件则可以快速的适配到小程序端,尽管可能带来部份性能耗损。

看个将RN的Text组件适配到remax组件的事例:

#a:4:1:c:d:0:c:a:8:d:1:9:7:5:1:8:9:c:f:d:6:7:3:c:3:c:d:7:7:f:5:3#

4.2ReactNativeAPI的适配

对与API的实现要更为简单直接一些,这儿请容许我将react-native的组件分为两类:

其二是纯函数的api,简单理解就是你调用了一个由框架提供的函数,得到了你想要的数据写入或返回,例如Dimensions,这一类普通api,qrn-remax-unir的处理方案就是能否通过封装调用小程序提供的api并存在两个平台磨平参数差别可能的即可完美适配。对未能通过调用小程序api来实现同样疗效的或小程序场景逻辑上就不存在的,qrn-remax-unir常常通过空实现并对开发者加以告知。

其一是调用一个有框架提供的方式,在页面上进行呈现,我们暂且叫它api组件(react-native中是api、但在小程序平台更像是组件),比如:Alert、ToastAndroid、ActionSheetIOS等,这一类api的实现方案是构造展示的模板组件,曝露出方式才能间接更改组件的状态,比如alert就是通过获取调用方式传入的内容进行填充,当获取用户操作后更改为隐藏不显示的状态并反弹组件的反弹技巧。

4.3复杂组件和API的适配

复杂组件和第三方组件虽然都是对基础元素组件的组合使用,我们从最底层的基础组件(ViewText等)完成适配,这样大部份复杂组件都可以直接适配到小程序端。如右图只要qrn-remax-unir的基础组件适配得足够完整就可以保证对下层RN业务和组件的完整适配。

#b:3:2:c:8:9:0:3:e:4:1:4:9:a:d:8:7:f:3:1:f:0:8:a:7:6:f:c:4:5:9:4#

5开发过程

尽管开发思路大体清晰了,但在开发过程中还是遇见了一些比较棘手的问题。

5.1款式处理

对于将RN的款式转换成小程序端能用的款式,我们一开始确定了两个方向:

编译时提取并转换

运行时动态生成

编译时提取并转换

这个方法虽然是我们一开始经过讨论认为可行的方案,具体方法就是通过编撰Webpack以及Babel插件,实现在编译阶段对款式相关对RN代码进行抽取并生成最终的WXSS文件。

这个方案的用处就是:

静态编译出的文件可以更好的进行管理,对于式样转化出的问题可以直观的进行更改,相当于有一个可见的原生产物去进行调试,对于开发者变得更友好,更直观。

实现的疗效理想中是这样的。

对于源代码:

#5:4:e:0:3:a:8:b:e:2:b:d:4:6:8:3:d:e:0:2:d:b:f:4:f:a:c:7:4:f:5:f#

处理后生成的styles.wxss文件中:

#b:7:a:2:f:a:a:1:b:3:f:3:1:f:f:a:6:6:3:7:0:b:5:4:f:3:0:f:2:9:5:6#

但是在尝试开发好了相关babelloader以及webpack插件之后,面对真实的复杂项目时,却发觉代码的书写复杂情况很难穷举解决。

由于RN代码的式样并不总是规矩的写成:

#c:e:5:5:7:0:c:7:5:b:a:b:4:8:8:b:4:c:b:7:5:6:1:4:3:4:4:a:8:4:f:0#

在项目中因为一些款式的值,比如屏幕宽高等,须要在运行时获取,于是会有一些不规则的形参方式:

#c:6:4:5:e:7:c:c:b:6:f:e:f:0:f:a:6:0:6:5:f:6:0:3:8:d:3:1:1:5:7:e#

当出现这些动态获取运行时值的情况时,我们的这个策略就难以处理了,于是这个方案只能姑且定夺。

运行时动态生成

这些方案的基本实现方法虽然是借鉴了React-native-web的做法,其实Twitter也尝试过编译时去生成CSS文件转换到web的方案,最后遭拒,才使用的运行时提取RN款式成class并形参到DOM元素上的方案。其实,通过剖析了react-native-web的源码库,我们做了一定程度的改动以适配到陌陌小程序的情况。具体做法如下:

以最基础组件View为例:

#6:a:8:1:6:e:c:9:8:5:e:4:2:0:d:c:3:f:5:c:8:f:4:f:4:f:6:f:f:d:5:9#

进行完转换的className以及style,会陪同一些默认补全款式,传递到Remax的View组件中对于一个普调的View组件,我们根据RN正常书写习惯,对style形参。我们适配层做的核心处理,就是将这种styles解析,而且转换和处理Class以及字段格式的款式,生成classList以及style变量。

#0:d:a:3:b:8:f:6:3:c:3:2:f:e:f:e:e:0:f:d:0:2:8:a:4:b:d:8:d:2:f:1#

进行完转换的className以及style,会陪同一些默认补全款式,传递到Remax的View组件中。

#c:5:0:d:1:b:f:2:b:1:6:d:c:5:6:2:8:2:6:3:a:5:e:2:c:4:4:7:5:9:c:5#

至此在运行时的Dom渲染,都会得到相应的class名以及行内style的值。

#8:7:5:e:f:b:1:4:7:2:7:e:b:8:f:3:f:5:2:5:c:5:6:b:e:7:3:0:f:8:5:0#

所以,对于编译时碰到的,那个DeviceInfo这类形参,也会在运行时得到最终的值并添加到组件的style属性里,进而解决了编译时难以控制的事情。

式样小结与思索

对于式样的处理,有好多细节须要注意,比如对于不同端的单位转换问题,对于不同端一些默认式样的补全的设置等。此处重在方案的选择过程介绍,并未列举具体款式差别,还须要更多的人来贡献力量,持续投入,跟进react-native的版本以及remax的版本。并且对于StyleSheet的细节处理,感兴趣的朋友也可以去查看react-native-web的源码,还是值得对跨端开发感兴趣的朋友深入研究学习的。关于方案,我们也在思索是否可以更进一步提高,例如将编译和运行时结合,进而降低行内款式,目前这样直接写入行内款式还是会造成我们的dom元素上属性值过长,不可读,不利于开发调试。另一方面,这些过长的属性也使小程序端的性能表现遭到了一定的影响。

5.2对动漫的处理

qrn-remax-unir在实现动漫方案上,采取了尽量不引入新的写法,与react-native起初写法尽量保持一致的思路,对RN代码做到零入侵。

这儿打算了一个demo,代码中的动漫写法和react-native官方文档的写法是一致的,先看一下疗效。

在定义react-native的单一动漫是这样写的:

#2:3:9:5:6:7:c:1:1:0:6:5:d:7:d:0:8:c:9:f:9:f:4:f:b:8:f:2:0:9:e:4#

qrn-remax-unir将前面的代码转换成类似下边的才能在小程序运行的代码,1-5的动漫关键信息通过框架层处理成一一对应,过渡时间就是react-native的动漫时间即duration,opacity就是react-native的Animated组件的动漫款式key即opacity、linear就是react-native中的形参API即Easing(有一些复杂曲线无法适配会在小程序端做相应的降级处理,例如使用linear),初始值和目标值直接传递过去就可以了再借助配准器将原始单位正则解析下来放如动漫属性值中,产物就是这样的transition:3000msopacitycubic-bezier(0.42,0,1,1);

组合动漫、平行动漫和次序延后动漫都是由Animated.timing组成动漫序列,由react-native的Animated本身的处理机制处理多个动漫触发和销毁。

6组件库的使用

组件库地址:

组件demo地址:

组件文档地址:#/./

想要了解具体怎么使用我们的组件库,可以下载我们的示例工程进行开发学习:传送门()

这个工程内集成了RN,web,陌陌小程序三端的编译开发能力,而且启动非常简单,你可以基于这个项目进行跨端项目的整修。此项目开发时疗效如右图(自左至右:RN->Web→微信小程序):

#1:a:0:e:8:0:3:6:7:0:4:b:c:e:6:1:2:3:0:e:9:8:2:5:2:2:f:9:4:4:6:4#

项目启动过程很简单,步入到项目根目录下:

1、安装依赖

#d:e:d:6:c:f:4:0:1:3:3:5:e:5:3:a:7:2:2:c:2:5:7:2:8:b:8:9:0:4:4:7#

2、运行dev环境

#f:1:7:e:0:5:1:b:3:2:8:2:f:b:8:b:1:8:4:e:4:d:5:e:b:7:1:b:0:e:7:6#

此时更改代码就可以实时热更新每一端的代码,是不是很便捷!赶紧开启你的跨端开发之旅吧!

假如你想了解具体搭建过程,也可以参考我们github网站上的介绍:传送门(#/./),尝试自己去动手改建出这样一个跨端项目。

END

#5:8:4:1:a:c:8:7:f:0:1:8:e:1:b:8:e:d:8:8:9:a:0:6:1:0:2:9:5:6:0:5#

#b:a:d:7:8:8:e:d:7:7:2:7:4:4:9:d:6:c:d:5:8:3:4:3:d:a:f:a:a:b:c:1#

微信小程序组件传值
上一篇:清洗咖啡机,让咖啡更美味 下一篇:没有了