@sigmayun/react-native-template-typescript
@sigmayun/react-native-template-typescript是基于 react-native-community/react-native-template-typescript 二次开发的模板脚手架。本文的架构方案融进了该模板。你甚至不需要阅读本文的内容即可使用本文中的最佳实践!!!
全局变量
既然都引入 TypeScript 了,就不用再担心给全局对象添加属性不小心污染它了,但是需要我们进行一些配置。
1、在项目根目录新建 types
,并新建 global.d.ts
文件名,添加一下内容:
1 | declare const global: { |
2、为了防止和 @types/node
的 Global
声明冲突,需要把 tsconfig.json
中的 skipLibCheck
的值设置为 true
该部分示例代码涉及
global.ts
、types/global.d.ts
、tsconfig.json
,请到 https://github.com/sigmayun/react-native-template-typescript 查看。
编码规范
- @sishuguojixuefu/eslint-config:大而全的 ESlint 配置,支持 vue、jsx、js、ts、tsx、html 的 ESLint 配置插件,基于 airbnb,支持Prettier
- husky + lint-staged: 禁止
commit
不符合规范的代码
该部分示例代码:https://bre.is/3GD7cHKn
Npm Scripts
善用 NPM Scripts 能帮助改善工作流程!!!
1 | { |
该部分示例代码:https://bre.is/LC6uu8kc
网络编程
- axios: Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
- qs: A querystring parsing and stringifying library with some added security.
- clean-deep: 从对象中递归删除空对象、空数组、空字符串、
null
和value
值。不改变原始数据。
该部分示例代码:https://bre.is/39khhJtn
路由管理
- React Navigation: 这个模块是官方推荐的导航组件,升级到5之后不仅支持了
hooks
,更是支持了动态路由。
该部分示例代码:https://bre.is/pzA7JArY
状态管理
mobx
+mobx-react
: 相对于 redux 来说更简单易用,还在犹豫的同学,可以读一下有赞的一篇文章 我为什么从Redux迁移到了Mobx
本地存储
- react-native-simple-storage: AsyncStorage 的一个简单包装器
- rxdb: JavaScript 即时数据库,如果有复杂的缓存业务可以考虑使用
- watermelonDB: 一个专为 React、React Native 服务的响应式数据库框架
启动屏
启动屏的配置涉及到不少原生知识,请阅读 https://bre.is/CRC2SkqP 进行配置。
热更新
- react-native-pushy: ReactNative中文网推出的代码热更新服务,免费,但是限制多,不推荐使用
- react-native-code-push + AppCenter:完全免费,国内速度可能慢,适合个人开发者【推荐】
- react-native-code-push + code-push-server:适合公司自建热更新服务器
新版热更新部分我还没写好博客,可以先参考我之前写的: http://techblog.sishuxuefu.com/atricle.html?5beaa7e59f5454007039e01c,我会在看完新文档之后把这部分配置也内置到脚手架中,毕竟这个服务也是 React Native 的标配。
UI框架
- @ant-design/react-native: Ant Design 出品的一个基于 React Native 的 UI 组件库
- beeshell: 美团 React Native 组件库
- react-native-elements: 跨平台React Native UI工具包
- react-native-ui-lib: 没有体验过,看起来很强大
其他组件收藏请查看:https://bre.is/jWUGvPrK
列表
- mobx+react-native-largelist 实现分页功能: 推荐使用 react-native-largelist-v3,支持下拉刷新、上拉加载更多、分组列表、表格和瀑布流
- 自行封装
FlatList
、SectionList
: 并不复杂,建议还是要回手写的,react-native-largelist-v3 不一定能满足所有场景
图标
- react-native-iconfont-cli: 【推荐】用纯JS把图标转换成RN组件,不依赖字体,支持多色彩,支持热更新
- @ant-design/icons-react-native: Ant Design Icons for React Native
- react-native-vector-icons: Perfect for buttons, logos and nav/tab bars. Easy to extend, style and integrate into your project.
字体
- react-native-fonts: 在React Native项目中开箱即用的可用字体,这个库只是统计了一下 React Native 中可用的字体而已
- React Native 配置自定义字体
- React Native Custom Fonts
- react-native-responsive-fontSize: 响应式fontSize基于React Native中设备的屏幕尺寸
- React Native 配置字体大小不随字体设置变化
- React Native字体问题解决方案指北
- react-native-responsive-fontsize
工具
- react-native-shadow-generator: 在线生成 React Native 阴影代码
- visualize-bundle:
npx visualize-bundle
允许你一键检查你的 React Native bundle 包 并且找到大的依赖 - 图标工厂: 一键生成所有尺寸的应用图标/启动图
React Hooks
这个新语法是2019年的明星,React Navigation、Mobx这些常用库都内置支持了,还没有学习的同学快去补课吧!!!
推荐阅读
建议先读官方文档!!!
如何兼容类组件
考虑到对于不适应 Hooks 的但是业务又很紧急的场景,我们可以在类组件之上封装一层来支持 React Navigation 的 Hooks 组件,之所以这么做,起因是因为 React Navigation 5 中我们只能通过 useHeaderHeight()
方法获取标题栏高度。
1 | class Albums extends React.Component { |
Metro
第三放服务
这里尽量为大家推荐了免费的服务,当然选择自行搭建服务也是一个很棒的选择!!
Sentry
Sentry 胜在可以把服务搭建到自己的服务器上,并且官方提供了sentry-react-native插件来帮助 React Native 工程师快速集成。如果有条件,选择 Sentry 恐怕是目前行业的最佳选择。
Sentry提供自托管和基于云的错误监控,可帮助所有软件团队实时发现分类和确定错误的优先级。已经有超过五万家公司的100万名开发人员使用,Sentry可以更快地提供更好的软件。你不加入他们吗?
腾讯 Bugly
腾讯Bugly,为移动开发者提供专业的异常上报和运营统计,帮助开发者快速发现并解决异常,同时掌握产品运营动态,及时跟进用户反馈。免费提供异常上报、运营统计、应用升级
推送
信鸽 | 腾讯移动推送
为开发者提供免费、快速、简单的推送服务。QQ登录即可快速注册,为APP接入SDK后马上获得无限量应用推送能力,
有效提升用户留存率、活跃度,开发者的不二选择!
小米消息推送服务
- MIUI上系统级通道
- iOS/Android全平台支持
- 免费 稳定 安全 高效
极光推送
极光推送服务,可以免费使用,但限制较多。官方SDK, React Native 集成容易
U-Push
和极光属于一类,限制级免费,友盟的产品胜在生态,公司产品考虑,后期用户上来之后方便扩展。
社会化分享
ShareSDK
为开发者提供40+主流平台的分享与授权等社会化功能,效果稳定,完整清晰统计分享数据
- 一键分享
- 第三方登录
- 闭环分享
- 短链转换
- 数据统计
- 新浪微博独家LinkCard
jshare
- 一键分享
- 第三放登录
- 社会化统计
- 官方 React Native SDK 集成方便
U-Share
- 全面覆盖国内外社交平台
- 集成成本低、速度快
- 自由定制分享界面
- 权威、实时的大数据分析
其他
- react-native-wechat: 🚀 WeChat login, share, favorite and payment for React-Native on iOS and Android platforms
- @0x5e/react-native-alipay: Alipay SDK for React Native. Support mobile webpage url payment. Support RN >= 0.47.
测试
这部分作者的理解仅限于 Jest,有大佬可以联系我补充!!!
- Jest: Jest是一个令人愉快的 JavaScript 测试框架,专注于简洁明快。React Native 已经集成好了,直接使用即可。
自动化运维
这部分作者接触不深,只知道 Jekens + GitLab 的方案
shell 文件的坑
为了安全性 shell 文件默认都是不可执行的,当然也包括 android/gradlew
这个用来打包的脚本文件,这会给持续集成带来麻烦:运维同学默认是执行不了我们的打包命令的。解决办法很简单:
1 | git update-index --add --chmod=+x android/gradlew |
动态设置 package.json 的版本
set-version.sh:
1 |
|
package.json:
1 | { |
官方组件缺陷处理
- React Native 解决Image 圆角在安卓上面没效果
- React Native 处理Android系统上文字偏下的问题
- React Native 自定义 TextInput 高度的问题
- [Android] Using TextInput inside ViewPagerAndroid causes context menu (copy/paste) in some cases to not display
VsCode 插件推荐
- React Native TypeScript Snippets: 本人开发,主要服务于本文的架构,帮助开发者快速搭建页面和组件,凡是重复的工作都可以靠工具来解决,一个不够,就来俩!!!
- ES7 React/Redux/GraphQL/React-Native Snippets
性能优化
自动 remove console 语句
准确地说,是在正式环境下删除 console
语句,配置方式请参考 自动 remove console 语句
推荐阅读
应用内测
安卓必知必会
配置应用名
很简单,我们直接打开 android/app/src/main/res/values/strings.xml
,即可看到配置中的 app_name
,修改为你想要的即可。
你可以在初始化项目的时候指定应用的名字,像这样:
npx react-native init MyApp --title 掘金
配置图标
1、使用图标工厂、react-native-svg-app-icon 或者让设计师给图片
2、在 android\app\src\main\res\mipmap-xxxxxx
中直接覆盖图标就可以,注意图标的大小。
打包 APK
1、在项目根目录执行 keytool -genkeypair -v -keystore release.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
生成密钥文件 release.keystore
2、把 release.keystore
文件放到你工程中的 android/app
文件夹下。
3、配置 android/app/build.gradle
1 | android{ |
打包优化
去除无用的语言资源
通过配置 android/defaultConfig/resConfigs
可以选择只打包哪几种语言,进而去掉各种 aar
包中全世界的语言,尤其是 support
包中的。
选择保留什么语言要根据产品的用户和市场来定,如果只选择默认英语和中文语言,配置如下:
1 | defaultConfig { |
配置 PackagingOptions
打开 android/app/build.gradle
文件,添加如下配置:
1 | packagingOptions { |
pickFirsts
: 当出现重复文件,会使用第一个匹配的文件打包进入 apkmerges
: 当出现重复文件,合并重复的文件打入 apkexcludes
: 打包的时候排除匹配的文件
配置 splits
查看手机 CPU 信息:
adb shell
->cd /proc
->cat cpuinfo
默认情况下,生成的 APK
会同时包含针对于 x86
和 ARMv7a
两种 CPU
架构的原生代码。这样可以让我们更方便的向其他人分享这个 APK
,因为它几乎可以运行在所有的 Android 设备上。但是,这会导致所有设备上都有一些根本不会运行的代码,白白占据了空间。目前安卓设备绝大多数是 ARM
架构,因此对于大部分应用来说可以考虑去掉 x86
架构的支持。
你可以在 android/app/build.gradle
中修改如下代码:
1 | - include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" |
gradle 编译速度优化配置
在 android\gradle.properties
中加入以下配置:
1 | # 让gradle使用单独的守护进程 |
BuildConfig
在 react-native 中,我们可以借助 react-native-config-reader 来方便地读取这些属性
BuildConfig
是程序编译后,根据 buildType
生成在 app\build\generated\source\buildConfig\debug(release)\
包名下的一个 java 文件。默认有一下属性:
DEBUG
:是否是调试版本APPLICATION_ID
:当前应用的包名FLAVOR
:产品(渠道包的名称)BUILD_TYPE
:当前的编译类型(release
/debug
)VERSION_CODE
:版本号(数字)VERSION_NAME
:版本号
自定义 BuildConfig
1 | defaultConfig { |
在子模块中取主项目的 BuildConfig
1 | ... |
解决在 Android P 上的提醒弹窗 (Detected problems with API compatibility(visit g.co/dev/appcompat for more info)
在 MainActivity.java
中添加 closeAndroidPDialog 方法并在 onCreate
方法中调用
1 | import android.os.Bundle; |
自定义安卓打包的后缀
配置 android/app/build.gradle
:
1 | ... |
常见报错及解决办法
Failed to read PNG signature: file does not start with PNG signature
有时从网上下载的 Demo 资源文件不规范,会出现直接将 jpg 文件改为 png 后缀名的情况,gradle 打包检查时报错编译通不过的。我们通过 aaptOptions.cruncherEnabled=false
来禁止 Gradle 检查 png 的合法性:
1 | android { |
com.android.build.api.transform.TransformException
在 android\gradle.properties
中加入以下配置:
1 | dexOptions.javaMaxHeapSize = 2g |
The number of method references in a .dex file cannot exceed 64K.
随着 Android 平台的持续成长,Android 应用的大小也在增加。当您的应用及其引用的库达到特定大小时,您会遇到构建错误,指明您的应用已达到 Android 应用构建架构的极限。
解决办法是配置您的应用进行 Dalvik
可执行文件分包,在 android/app/build.gradle
中做下面的配置:
1 | defaultConfig { |
ios必知必会
这部分目前作者接触不深,有大佬可以联系我补充!!!
镜像
pod install
会从 GitHub 拉代码,所以在国内会很慢。年轻人要爱国,自觉不翻墙!!!
配置应用名
- 选中工程名称
- 找到右侧菜单
Info
选项 - 添加
Bundle display name
并把value
设置成 “应用名称” - 最后重新再
Run
一次,即可看到最新的效果
你可以在初始化项目的时候指定应用的名字,像这样:
npx react-native init MyApp --title 掘金
配置图标
1、使用图标工厂、react-native-svg-app-icon 或者让设计师给图片
2、把准备好的图标拖到图中箭头指向的位置:
获取BUILD_TYPE
在 Info.plist
中添加 BUILD_TYPE
,取值为 $(CONFIGURATION)
获取构建时间
在 Info.plist
中添加 BUILD_TIME
,取值为空,并通过脚本在每次编译的时候对其更新,脚本添加步骤 Target
-> Build Phases
-> +
-> New Run Script Phase
, Shell 代码如下:
1 | !/bin/bash |
权限申请
Privacy - Camera Usage Description
Privacy - Photo Library Usage Description
Privacy - Microphone Usage Description
Lean Core
COMPONENT | DEPRECATED? | NEW HOME |
---|---|---|
AsyncStorage | 0.59 | @react-native-community/react-native-async-storage |
ImageStore | 0.59 | expo-file-system or react-native-fs |
MaskedViewIOS | 0.59 | @react-native-community/react-native-masked-view |
NetInfo | 0.59 | @react-native-community/react-native-netinfo |
Slider | 0.59 | @react-native-community/react-native-slider |
ViewPagerAndroid | 0.59 | @react-native-community/react-native-viewpager |
WebView | 0.60 | react-native-webview |
NetInfo | 0.60 | @react-native-community/netinfo |
Geolocation | 0.60 | @react-native-community/geolocation |
Apple TV Support | 0.62 | react-native-community/react-native-tvos |
联系作者
作者微信 | 知识星球 | 赞赏作者 |
---|---|---|