@fht360/fht-react-native
v1.0.59
Published
烽火台移动端react-native项目
Downloads
59
Keywords
Readme
以下内容都是以 iOS 平台的角度来说的,相应的第三方库, Android 需要按照官网进行与 Android 原生的集成。 使用 npm 安装包
react-native 项目说明
- react-native 官网
- react-native 中文网
- react-native github
- react-native guide
- react-native awesome
- typescript 中文网
- storybook 官网
- react 中文官网
- redux 官网
- code-push 官网
原生端(iOS、Android)需要集成的第三方库
- React
- react-native-gesture-handler
- code-push
- react-natvie-linear-gradient
- react-native-charts-wrapper
- react-native-reanimated
react-native 集成到 iOS 项目中
中文网上给的文档是以 react-native 项目为主目录,把 iOS、Android 项目为子目录。我这里的做法是把 iOS、Android、react-native 分别作为独立的项目,iOS、Android 项目通过 npm 包的方式依赖 react-native 项目。
建立 fht-react-native 文件夹,以后所有的 react-native 相关文件都放在其中
进入 fht-react-native 目录,执行以下命令,创建 package.json 文件,暂时不需要修改内容都使用默认值
npm init -y
使用 npm 安装 react-native
npm install react-native
根据上一步给出的警告信息,添加对应版本的 react
npm install react@version
这个 react-native 的项目最终是作为一个 npm 包供 iOS、Android 使用的,我们使用 Github Actions 来自动化这个过程,每次 push 后,都会自动发布一个新版本的 npm 包
进入到 iOS 项目目录 fht-iOS 下,在 Podfile 文件中加入 react-native 依赖库,并安装
pod install
(首先要安装上一步产生的 npm 包,可以查看 iOS 项目中的 README )我们项目使用 typescript,所以按照官网配置一下
在 iOS 中需要接入 react-native 的 viewController 中加入以下代码,注意 moduleName 与 react-native 中导出的模块名称要一致
NSURL *bundleUrl = [NSURL URLWithString:@"http://ip:8081/index.bundle?platform=ios"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:bundleUrl moduleName:@"FHTTrafficStatistics" initialProperties:@{} launchOptions:@{}]; rootView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:rootView]; // 需要设置rootView的上下左右约束
创建以.ts/.tsx 为后缀的文件,编写业务代码
创建 index.js 入口文件,并加入以下代码
import {AppRegistry} from 'react-native'; import TrafficStatisticsContainer from './TrafficStatistics/Container'; AppRegistry.registerComponent("FHTTrafficStatistics", () => TrafficStatisticsContainer);
开启 node 服务
npm start
运行 iOS 项目,进入到加入了 react-native 项目的页面,可以看到运行的效果。
对项目目录的解释
- api.ts:所有的 api,由 swagger_gen.sh 脚本生成
- src:项目代码
- dist:生成的 bundle 包和资源
- index.js:react-native 项目入口文件
- swagger_gen.sh:生成 api.ts 的脚本
- tsconfig.json:typescripe 配置文件
对 FHTNativeModules.ts 文件的解释
是模块的声明文件,模块是指原生(iOS/android)项目暴露给 react-native 项目的模块。
先看一下 iOS 端写的要导出的模块有哪些:
- FHTRNEventEmitManager:负责发送事件到 react-native
- FHTRNEventHandleManager:负责处理 react-native 的事件,比如点击
- FHTRNMethodManager:负责导出方法供 react-native 使用
- FHTRNConstManager:负责导出常量供 react-native 使用
以 FHTRNConstManager 为例进行解释
下图红色字体表示的为 iOS 端导出的常量名称
不创建 FHTNativeModules.ts 时的使用方式
使用过程中是完全没有提示的
创建 FHTNativeModules.ts 后的使用方式
先看看 FHTNativeModules.ts 的内容
使用过程中会有提示
需要注意的是,每当原生端有新的模块导出,都要在 FHTNativeModules.ts 中增加对应的声明
对 Color.ts 的解释
文件在./Const/Color.ts
导出的一个字符串枚举,枚举内容为 16 进制颜色字符串,这么做的目的是可以方便有提示的使用颜色。对前端理解不深,不知道正常应该如何处理,这是我自己的想法
Color.ts 文件的内容
没有 Color.ts 使用颜色时,且没有提示
...
backgroundColor: '#FC3A0D',
...
有 Color.ts 使用颜色时,且有提示
import Color from './Color'
...
backgroundColor: Color.cf03ad,
...
对 NetworkTool.ts 的解释
包装一下请求,对每个请求加入我们自己的 headers,比如 Authorization 等等
NetworkTool.ts 文件的内容
使用方法
import NetworkTool from './NetworkTool'
import \* as Api from './api'
...
getMobileProductVisitDetail = async () => {
const api = await NetworkTool.restfulApi(Api.StatisticsApiApi);
const result = await api.statisticsApiMobileProductVisitStatistics({timeRange: 'Today', size: 50});
}
...
chart 的选择
在 github 上找了几个跨平台的画图的库
- react-native-chart
- victory-native
- react-native-charts-wrapper
- react-native-svg-charts
- react-native-pathjs-charts
简单的使用过以后,综合考虑易用性、库本身是否维护、文档等,最终选择了react-native-charts-wrapper
做为我们项目中使用的库。
热更新服务
热更新服务简单点说就是一个云服务器,用于存放 reactnative 代码打包后的 bundle 包,供原生端去下载。
目前比较常用的热更新服务
我首先尝试了中文网提供的热更新服务,按照其github上的教程集成时(因为我们是在原有项目基础上集成,所以只能手动链接),结果失败了;后来通过自己创建 RCTHotUpdate.podspec 文件才算集成成功,使用后发现并不是那么好用,所以最终选择了微软提供的热更新服务。
微软热更新 code-push
android/app/build.gradle 文件不要删除,不要修改,为了 android 可以正常打包发布到 appcenter(热更新)
先明白几个概念
- operatingSystem: 操作系统,比如 iOS、Android
- platform: 运行平台,比如 React-Naitve、Cordova
- app: 一个应用
- deployment: 可以理解为 app 的不同环境
- release: 可以理解为 deployment 的不同版本
创建 app 时要指定 operatingSystem 和 platform,而一个 app 可以包含多个 deployment,一个 deployment 可以包含多个 release,bundle 包可以理解为 release。
- 我们把.ipa(iOS)、.apk(Android)称为二进制文件,这个二进制文件是有版本的,把 react-native 打包后的 js 称为 bundle 包,这个 bundle 包也是有版本的,热更新就是在不修改二进制文件版本的情况下修改 bundle 包的版本。
- 实现的原理就是在二进制文件中埋入指定代码,也就是 code-push 提供的 sdk,这个 sdk 会检查当前二进制文件有没有更新的 bundle 包,如果有就会把 bundle 包下载下来,这样 bundle 包就更新了,内容也就更新了。
- 这样就决定了,发布 bundle 包时要指定其有效的二进制文件的版本,具体为什么要这样做,可以查看版本说明,不过指定的二进制版本可以是一个范围表达式,只要在这个范围的二进制都会检测到新的 bundle 包。
发布
"update-ios-debug": " appcenter codepush release-react --target-binary-version '*' --entry-file ./index.js --deployment-name Debug --app fht360.com/fht-ios --development true",
"update-ios-staging": " appcenter codepush release-react --target-binary-version '*' --entry-file ./index.js --deployment-name Staging --app fht360.com/fht-ios",
"update-ios-release": " appcenter codepush release-react --target-binary-version '*' --entry-file ./index.js --deployment-name Production --app fht360.com/fht-ios",
"update-android-debug": " appcenter codepush release-react --target-binary-version '*' --entry-file ./index.js --deployment-name Debug --app fht360.com/fht-android --development true",
"update-android-staging": "appcenter codepush release-react --target-binary-version '*' --entry-file ./index.js --deployment-name Staging --app fht360.com/fht-android",
"update-android-release": "appcenter codepush release-react --target-binary-version '*' --entry-file ./index.js --deployment-name Production --app fht360.com/fht-android",
Android 引入 node_modules 中库时需注意的点
1、使用时需在项目根目录 setting.gradle 中配置引入的 module 名称,例如: include ':app',':react-native-code-push' project(':react-native-code-push').projectDir = new File(rootProject.projectDir, FHT_REACT_NODE_MODULE_PATH + 'react-native-code-push/android/app')
(1)第一行 include 表示 app 下 build.gradle 中引入该 module 的别名,implementation project(':react-native-code-push') (2)第二行表示引入的 module 的名称及其 android 项目路径,所选择路径为 src 文件夹的上一级路径;
2、fht 项目 buildType 有三种,所以引入 module 时需检查该 module 的 build.gradle 是否也配置了,如果未配置,则需手动添加 buildTypes { release {} dev {} debug {} }
备注: 方式(1):使用 fht/fix_react_native_lib_build_gradle.js 配置 node_modules 下的相关库【该方式已废弃,建议使用方式(2)】 方式(2):使用 fht-react-native/fix_module_lib_build_gradle.js 配置 nodules 下的相关库
3、由于项目已迁移至 Androidx,fht-react-native 中引入的库 react-native-gesture-handler、react-native-charts-wrapper、 react-native-code-push 以及 react-native-linear-gradient 中的部分文件中 android.support.xxxx 的引用需要修改至 androidx 引用,这个每次 node_modules 重新生成的时候需要检查下文件是否正确(目前 node_modules 生成后运行项目可能会因这个问题报错) // TODO nodejs 脚本检测库引用中 android.support.xxx 的引用并替换为 androidx 功能
4、node_modules 下的库引用时,大部分 module 都会从根目录中获取 compileSdkVersion 等信息,项目配置时最好能在根目录 的 build.gradle 中配置全局变量: ext { compileSdkVersion = 28 buildToolsVersion = "28.0.3" minSdkVersion = 19 targetSdkVersion = 28 }
4、【重要】每次重新 npm install or yarn install 后需重新检查 setting.gradle 中引入的 node_modules 下的对应的 module 的 build.gradle 是否仍然是添加注意点 2 中的 buildType...
5、【重要】
1、@zhangmenglai windows上 目前只能使用node 10运行react(index_android_bundle包也需要使用node 10),node 12及以上暂时用不了,调试及打包时
需要注意node版本切换;
2、@zhangmenglai windows上不要使用cnpm install安装包,会出现打包失败情况,错误很奇葩,使用npm install;
3、
## 注意事项
- react-native项目是独立存在的,Android、iOS项目对react-native的引用是通过npm包的方式实现的,我们通过github action的方式进行自动npm包的发布,每次push后都会自动往npm上publish