前言
若你已经有RN商业项目经验及桥接原生功能给RN端使用经验,对下文的理解会比较流畅,否则理解起来可能稍微有些吃力,但也可以试试,万一跟他有缘呢。
本篇的内容都是自己刷官网及结合项目得出的当下对expo的认识,可能会存在一些错误或以偏概全,我会随着自己认识的加深不断的修改,也欢迎大家提问题共同探讨
一、生态介绍
-
expo
RN开发分为两部分,其一:React代码开发,其二:Native代码开发。以前开发者需要同时维护这两套代码,expo期望使用自研的expo SDK帮你维护Native代码(包括包的构建及发布),做到让RN开发者对Native代码无感,即使需要对Native做改动,也会尽量的做成配置项让你配置。总之通过各种方式来减少你直接修改Native代码的可能。expo对web的兼容做的也比较好,目前还没有碰到啥值得记录的事情,因此没有放太多篇幅
-
ExpoKit
ExpoKit是一个Objective-C和Java库,基于它可以生成expo项目对应的iOS、Android代码expo SDK 38 版本之后ExpoKit被标记为过期,具体原因下面会分析
-
eas
expo-cli中提供有从构建到发布一条龙服务,但只限于使用expo-cli创建的RN项目,facebook为了统一各种RN项目的构建发布服务,单独的做了一个eas-cli,直接让所有的RN开发者可以忽略掉Native上各种构建发布相关的配置,比如: Android端的签名管理及iOS端的证书管理,这对没有原生开发经验的朋友来说简直是天大的福音 -
snack
基于该平台,你可以将现有的expo项目快速的共享或演示,比如:- 将代码上传到该平台后,在该平台的网页中便可以直接查看效果,无需设置各种环境
- 将代码上传该平台后,会生成一个链接,在expo Go App上可访问链接查看真机效果
- 你自己封装的组件库,在docs中想快速预览,可将snack嵌入到docs中实现
其他的暂时想不起来了,想到再补充吧,总之,react-native-cli正在慢慢的被淘汰,expo将会成为主力军,并且生态也在渐渐完善
二、添加自定义Native代码
expo SDK的生态目前来说对国外更加友好,因为expo SDK内置了国外常用的三方服务平台(google SDK、firbase SDK等),而对国内的常用三方服务(微信 SDK、神策 SDK等)却没有支持,其次随着项目的迭代,避免不了需要自行桥接API.
基于如上场景,接下来介绍两种修改Native代码的方式,分别是:eject、prebuild
-
eject
执行expo eject会借助expokit生成Native工程。官方列举了如下几个副作用:- 无法使用expo build构建应用。
但可以使用eas呀
- 需要管理Native代码。
其他两种也需要改动
- 升级react-native版本将会比较繁琐。
这种版本升级的概率会较小
- 无法使用expo的推送服务。
国内本身也不会用国外的推送SDK
- 在expo社区无法解决Native的问题。
其他社区有就行
分析上诉问题后,发现其实这些限制目前而言都不是大问题,那么官方为什么会不再推荐呢(同时expokit被标记过时),关键在于他不支持config-plugins
- 无法使用expo build构建应用。
-
prebuild
由上面的介绍可以感觉到,eject后的项目会越来越脱离expo的管理,而prebuild后的项目没有eject的那些限制,本身还都是在expo的完整生态下,显然后者是更加符合expo的理念,因此我觉得prebuild其实就是eject的重构版本。接下来我通过对比两者生成Native代码的机制来对两者深入了解一下首先结果都是生成了Native工程,但两者的内容有一定的差异,eject出来的Native项目模板是固定的,而perbuild会基于如下四个配置来个性化的生成Native项目:
- Expo 配置文件 (app.json, app.config.js)
- 执行prebuild时后续带的参数
- 指定的模板文件
- 自动link package中的Native代码(eject不会自定link)
如果仅仅基于以上四点,直接在eject脚本上做些修改即可,没必要再搞一个prebuild。他和eject的核心差异在于对于对config-plugins的支持。
config-plugins这个东西在上面反复被提到,接下来我介绍下他有何神奇之处
我们在日常开发中,若使用到有native代码的package,无论是eject还是prebuild都可通过link的方式将Native代码加到Native工程中,若我们需要修改android的build.gradle、AndroidManifest、。。。和iOS的AppDeletegate、Info.plist、。。。文件时,eject只能去native工程中修改,而prebuild可以基于插件修改,不需要去动Native项目。这对没有Native开发经验的人来说是…好事么?之所以是疑问句,是因为插件的学习门槛对于熟悉native的开发人员来说并不低,若还不熟悉native,学习成本就更高了。
到这里是否有些灰心了,下面我介绍三个东西来帮助大家在建立一下信心。
-
插件的学习方式
在看插件文档之前,强烈推荐首先去了解你要改动文件的作用及基本结构,否则你较大概率会陷入双重懵逼状态 -
如何快速上手
- 如果我们的插件不依赖于任何的package,将插件放在项目下即可,若该插件是配合package,建议将插件放在package目录下
- 官方提供有现成插件列表,文档看完后建议去瞅瞅,帮助你熟悉一下插件的基本目录结构及开发模式
-
我碰到的一些坑
- 官方的插件部分是在package中,而且在项目中也不需要在app.json或app.config.json中引入,估计expo自行做了,但我们自定义的插件需要手动引入
- 因为基于插件修改native代码是用node实现的,node又不支持ts,因此插件需要生成js文件
- 插件的开发基于两个库
@expo/config
和expo-module-scripts
,建议插件在哪里我们就在哪里引入这两个库 - 插件使用
createRunOncePlugin
包装,还没有弄明白为啥 - 这是目前我的一些经验教训,其他碰到在回来记录吧,若有问题欢迎探讨
我们改动Native代码之前,开发一直用的是Expo Go App,但我们改动了Native代码,就需要一个即包含Expo Go App的Native模块,也包含我们自定义代码的定制化Expo Go,development builds解决的就是这个问题,这个就去看官方文档吧,我目前没啥可说的
三、从构建到发布
已经了解到目前官方推荐使用eas做构建发布,在此我不想做官方的翻译,我主要是将我自己的落地过程及碰到的问题给记录一下,方便以后其他项目的快速集成。
-
eas的基本原理是什么
-
构建过程
-
发布过程
-
热更新过程
-
上传元数据