Taro框架剥离指南:从跨端迁移到原生React Native

Viewed 0

序言

在项目初期选择技术栈时,由于计划支持多平台发布,我们采用了Taro跨端框架来开发APP,以便后续跨平台迁移。然而,项目上线一段时间后,使用Taro框架开发React Native应用的问题逐渐显现:一是升级Taro版本必须同步更新React Native,带来较大风险;二是Taro Router深度耦合封装了react-navigation等组件,当与其他使用类似组件的库共存时,版本冲突可能导致崩溃。因此,对项目进行框架改造已刻不容缓。

计划

在确认项目基本不会发布到多平台后,我们开始考虑剥离Taro框架,避免技术栈与打包工具深度耦合导致后期维护困难。为最小化剥离过程对项目稳定性的影响,我们制定了三步走计划:

  1. 运行时剥离:将代码中使用的Taro方法统一迁移到项目中,解除代码与框架的运行时依赖;
  2. 编译时剥离:移除Taro的预编译代码,实现技术栈与打包工具的完全解耦;
  3. 编译器剥离:彻底移除Taro框架,改用Metro启动React Native,并移除Taro CLI等相关工具。

一、运行时剥离

运行时剥离的核心是将原本由Taro框架提供的方法和组件迁移到项目内部,从而解除运行时与框架的耦合。需要注意的是,此步骤仅处理运行时引用,对于Taro的预编译代码,我们暂时保留原有引用,留待后续步骤处理。

我们在src目录下创建了tarojs文件夹,并在其中实现了项目中所用到的各类组件,例如View、Image、Text等,同时将Taro的API如getSystemInfoSync、showToast、showLoading等也迁移至此。随后,我们对import语句进行了批量修改,将指向@tarojs/components的引用改为指向@/tarojs/components。在实际修改过程中,我们发现并非所有组件都能直接替换为React Native原生组件。例如,View组件针对TextNode等节点类型额外使用Text进行包裹,否则React Native编译会失败。因此,最终我们选择迁移Taro源码并稍加修改,以确保代码行为的一致性。

二、编译时剥离

像Taro、Umi这类技术栈与编译器一体的框架,通常会在编译时进行预处理。例如,Taro框架的Router和Model等公共方法,为适配小程序语法,会在项目编译过程中注入额外代码。第二步的目标是将技术栈与Taro彻底剥离,移除项目中与生命周期和路由等相关的耦合代码。

首先,以showToast为例,其底层基于react-native-root-siblings实现,这需要向App层注入RootSiblingParent组件。因此,我们改造了App.jsx,确保原有逻辑得以保留。其次,最复杂的部分在于剥离路由和生命周期这些深度绑定的代码。由于Taro源于小程序,其写法基于小程序的路由配置和生命周期,我们需要逐步进行适配。

我们移除了原有的children结构,直接使用@react-navigation实现路由功能,通过NavigationContainer和createNativeStackNavigator来定义页面栈。为了模拟Taro的getCurrentPages能力,我们使用createRef获取导航实例,从而获取当前路由信息。此外,我们利用react-navigation的useFocusEffect和React Native的AppState事件,重新实现了useDidShow等生命周期钩子,确保组件在页面显示或应用切换到前台时能正确触发回调。

三、编译器剥离

完成前两步后,项目基本移除了对@tarojs代码的依赖,仅剩命令行、编译和启动等部分需要处理。首先,我们替换了原有的taro-cli命令行,通过自定义脚本或工具(如Fastlane)来执行构建命令。其次,在样式处理上,由于项目使用Less而React Native不支持,我们继续沿用taro-css-to-react-native插件,将Less转换为StyleSheet。最后,我们移除了metro.config.js中的@tarojs/rn-supporter,并自行实现了样式转换等必要能力,确保项目能通过Metro正常启动和构建。

最后

经过上述步骤,我们成功将项目从Taro框架剥离,并迁移到原生React Native环境,应用运行稳定,达到了预期效果。

0 Answers