Skip to content

React Native & Expo

下面如无特别说明,环境均指 Expo SDK 53。

Android 构建依赖

iOS 构建依赖

  • node v23.x
  • Expo SDK 53
  • macOS 15.5
  • Xcode 16.4

Terms

注:在中国大陆访问 Expo 相关服务需要使用全局模式代理。

EAS

2023-7,EAS 免费套餐构建 HelloWorld iOS 应用约耗时 9 分钟,IPA 打包约 8MB 。

RN 基本元素是视图组件(View),所有组件基于视图组件实现; 编译时,View 会替换为 iOS/Android 对应原生组件(Native Components); RN 自带部分开箱即用的核心组件(Core Component)

2023-9,Android Studio Giraffe 2022.3.1 Patch 1, Java 20.x, 打开 ProGuard 和 split 特性,构建 API level 29 (Android 10), arm64-v8a APK 包约 8MB 。

Hello world

HelloWorld iOS

  • 付费订阅 Apple Developer Program
  • 安装 XCode、Command Line Tools 和 iOS 模拟器
  • 安装 HomeBrew
  • 安装开发环境依赖包
    • node.js brew install node
    • watchman brew install watchman
    • Ruby brew install ruby
    • CocoaPods iOS 依赖管理 gem install cocoapods

使用 react-native 脚手架工具包创建名为 app 项目 npx react-native@latest init app --verbose

启动一个终端,启动 Metro 服务

sh
# 它类似网页开发编译打包工具 Webpack,将 JavaScript 业务代码和相关依赖打包(Bundling)为一个单独文件。
# 注:两者有差异,和 Webpack 统一编译所有代码不一样,Metro 仅编译(compiled) 部分 JavaScript 代码以提升启动性能和跨平台兼容性。
cd app
yarn start

另启动一个新终端,启动应用

sh
yarn ios

XCode 打开 ios/*.xcworkspace ,设置签名证书,编译指定目标启动模拟器或者真机设备即可预览。

断点调试

启动终端 npx expo start

构建二进制包并在虚拟机中以 debug 模式启动应用 npx expo run:android

设置调试:

  • 在终端中按 j 打开 React Native DevTools
  • 点击右上角齿轮图标设置按钮,打开 Settings 面板,Ignore List 中去掉勾选 Enable ignore listing 选项
  • 点击右上角 X 按钮关闭 Settings 面板
  • 点击 Sources 标签页 ,依次展开 127.0.0.1:8081/[metro-project]/app/path/to/you-file.tsx
  • 选中目标行添加 breakpoint 即可,触发逻辑运行到目标行即可

参考 https://docs.expo.dev/debugging/tools/

构建 Android 原生应用

构建步骤,以 Android Studio 为例

  • 安装 Android SDK
  • 设置 Gradle
    • 在 Settings - Build, Execution, Deployment - Build Tools - Gradle
      • Gradle user Home: $HOME/.gradle or %UserProfile%/.gradle
      • Distribution: Wrapper
      • Gradle JDK: check your local JDK 17

参考 https://docs.expo.dev/guides/local-app-development/#local-app-compilation

更新静态资源

如 app logo ,需 commit 变更后,在跟目录执行 npx expo prebuild

虚拟机上运行

启动终端 npx expo start

a. 安装并更新 Android SDK 到最新版本 b. 更新 macOS 系统、XCode 到最新正式版本

构建二进制包并在虚拟机中启动应用

  • npx expo run:android
  • npx expo run:ios

默认输出目录 ./android/app/build/outputs/apk/debug/app-debug.apk

真机上运行

TBD.

加载 dotenv 环境变量

  • 本地/开使用文件名 .env.local
  • git 忽略名单文件 .gitignore 加上 .env*.local
  • 生产使用文件名 .env

参考 https://docs.expo.dev/guides/environment-variables/

本地化

https://docs.expo.dev/guides/localization/

常用类库

常见问题

升级 Expo SDK:

shell
npx expo install expo@latest
npx expo install --fix

Android Studio 无法构建 apk

提示错误 Could not start 'node' / node command cannot be found

修改项目设置 Android SDK 路径:

  • Settings - Build, Execution, Deployment - Build Tools - Gradle
    • Gradle Projects - Gradle JDK,设置为合适的值,如 /Library/Java/JavaVirtualMachines/openjdk-17.jdk/Contents/Home

参考 https://github.com/expo/expo/issues/28309

RN 无法启动 iOS 模拟器 ERROR: No bundle URL present

关闭宿主机代理,重新构建后启动应用。

Expo SDK 53 requires XCode 16

Error Value of type "some View" has no member "onGeometryChange"

see also https://github.com/expo/expo/issues/36830

添加出口合规性密钥流程

  • navigate to Info.plist
  • add a key named ITSAppUsesNonExemptEncryption, value is NO

SafeAreaView

规则

  1. 如果是 Stack.Screen <Stack.Screen name="xxx" options={headerShown: true} /> , header 会自动计算高度,无需计算 safe area,如果是 headerShown=false ,则需要手动计算 safe area 。
  2. 如果想完整自定义 header ,可以使用 SafeAreaView 包裹。<SafeAreaView>{yourChildren}<SafeAreaView />,yourChildren 会被自动设置 paddingTop 为 headerHight 。

CFBundleVersion is empty but must be composed of one to three period-separated integers

Fix: '1234.05.06' => '1234.5.6'

https://stackoverflow.com/questions/25418798/cfbundleversion-must-be-a-period-separated-list-of-at-most-three-non-negative-in

8081 already used on macOS

shell
lsof -nP -i4TCP:8081 | grep LISTEN
kill node by specified port

XCode 不断奔溃

断开真机设备后重试

无法找到 App Store 登录 sandbox 测试帐号入口

同下

iOS Receipt Validation Returns Status 21002 校验票据值为 21002

  • 更新 iOS、react-native、pod 依赖到最新
  • XCode schema - run - 勾选 StoreKit Configuration,重新构建 app
  • 在真机上,退出当前 Apple ID
  • 在真机上触发内购,使用 sandbox 测试帐号登录购买
  • XCode schema - run - 勾选和 sandbox 帐号、真机一致的地区 region 和语言 language,运行 app

https://github.com/dooboolab-community/react-native-iap/issues/1968

Sandbox: bash deny(1) file-write-create /path/to/app.app/ip.txt Operation not permitted

solution: set ENABLE_USER_SCRIPT_SANDBOXING to NO

https://stackoverflow.com/questions/76792138/sandbox-bash72986-deny1-file-write-data-users-xxx-ios-pods-resources-to-co

iOS 设置 Text 圆角(borderRadius) 需要包裹一层 View

iOS 混合使用 react-native native-base View Text 布局,可能导致 Web 平台正常,iOS 上错乱

iOS enable HTTP connection

https://stackoverflow.com/a/50760593/913751

adr 真机调试 android

  • install android sdk and android sdk platform
  • enable USB debug on device
" 列出设备
adb devices
adb -s <device name> reverse tcp:8081 tcp:8081
adb -s b476cd5 reverse tcp:8081 tcp:8081
adb devices

yarn start
" 按 a 启动或 yarn android --mode debug

修改 android 代码后,需要在真机上终止 app 进程,重新在 yarn start + a 编译后安装启动。

adr Error: error:0308010C:digital envelope routines::unsupported

node:internal/crypto/hash:71
  this[kHandle] = new _Hash(algorithm, xofLen);
Error: error:0308010C:digital envelope routines::unsupported
set NODE_OPTIONS=--openssl-legacy-provider
npx expo start --web

https://github.com/expo/expo-cli/issues/4575#issuecomment-1293202536

adr Doesn't say anything about org.gradle.plugin.api-version (required '7.5')

android studio - settings build, execution, deployment - build tools gradle - gradle JDK: Oracle JDK 1.8 改为 embedded JDK

https://stackoverflow.com/questions/73160326/could-not-resolve-all-files-for-configuration-classpath-could-not-resolve-io

adr unsupported class file major version 64

android studio 打开项目提示升级 gradle 后重新构建。

adr Could not connect to development server

重启 yarn start

adr 真机调试安装包提示错误 INSTALL_FAILED_USER_RESTRICTED

提示

Error running 'MainActivity'
The application could not be installed: INSTALL_FAILED_USER_RESTRICTED

红米 Note 7

  • 设置 - 更多设置 - 开发者选项 - 取消启用 MIUI 优化
  • 启用 USB 调试

adr Win11 android 虚拟机设置硬件加速时键盘花屏

模拟器设置图形加速 为 软件加速 代替 硬件加速

Released under the CC-BY-NC-4.0