React Native + Expo 开发指南:编译、调试、构建全解析
日期 : 2025-01-07
项目: AI 玩具管家 (React Native + Expo)
📋 目录
背景与项目介绍
项目背景
本项目是一个 AI 玩具配网应用,旨在将微信小程序的 BLE(蓝牙低功耗)配网功能移植到 React Native 平台。目标设备是通过蓝牙接收 WiFi 凭据的智能玩具。
技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| React Native | 0.74.x | 跨平台移动开发框架 |
| Expo | SDK 52 | React Native 开发工具链 |
| react-native-ble-plx | v3.0.0 | 蓝牙低功耗库 |
| TypeScript | 5.x | 类型安全的 JavaScript |
为什么选择 Expo?
Expo 是一个强大的 React Native 开发工具链,提供了:
- 快速启动: 一键启动开发服务器
- 热重载: 代码修改即时反映到设备
- 原生构建: 支持构建独立安装包
- 权限管理: 简化 Android/iOS 权限配置
- 无需 Xcode/Android Studio: 基础开发无需完整安装 IDE
核心概念澄清
开发阶段划分
一个典型的移动应用开发流程分为以下几个阶段:
┌────────────────────────────────────────────────────────────────────────────┐
│ 应用开发生命周期 │
├────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 编码 │ ─→ │ 编译 │ ─→ │ 调试 │ ─→ │ 测试 │ ─→ │ 发布 │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │ │ │
│ ↓ ↓ ↓ ↓ ↓ │
│ 源码文件 Expo/Gradle Metro 服务器 同一阶段 APK/AAB │
│ (.ts/.tsx) 原生代码 实时打包 继续迭代 正式安装包 │
│ │
│ ══════════════════════════════════════════════════════════════════════ │
│ 开发阶段(频繁迭代) 发布阶段(稳定版本) │
│ ══════════════════════════════════════════════════════════════════════ │
│ │
└────────────────────────────────────────────────────────────────────────────┘
什么是"编译"?
编译(Compile) 是将人类可读的源代码转换为机器可执行代码的过程。
在 React Native 中,编译分为两层:
-
JavaScript 编译(打包/Bundling)
- 将分散的
.ts/.tsx文件合并为一个或几个大文件 - 代码转换(如 TypeScript → JavaScript)
- 优化和压缩
- 工具: Metro Bundler
- 将分散的
-
原生编译(Native Build)
- 将 JavaScript 代码与原生组件结合
- 生成可执行的 APK/AAB (Android) 或 IPA (iOS) 文件
- 工具: Gradle (Android) / Xcode (iOS)
什么是"调试"?
调试(Debug) 是在开发过程中排查和修复问题的过程。
React Native 调试的特点:
- 实时日志 : 通过 Metro 控制台查看
console.log - 热重载: 修改代码后无需重新安装应用
- 远程调试: 可使用 Chrome DevTools 调试 JavaScript
- React DevTools: 检查组件树和状态
什么是"构建"?
构建(Build) 是创建可分发安装包的过程。
| 构建类型 | 用途 | 特点 |
|---|---|---|
| Debug 构建 | 开发测试 | 包含完整日志,体积大,未优化 |
| Release 构建 | 生产发布 | 移除日志,代码优化,体积小 |
Expo 命令详解
npx expo start
作用: 启动 Metro 开发服务器
bash
npx expo start
# 或指定端口
npx expo start --port 8082
# 或清理缓存启动
npx expo start --clear
详细行为:
1. 启动 Metro Bundler(代码打包服务器)
├── 监听指定端口(默认 8081)
├── 读取项目配置 (app.json/app.config.ts)
└── 初始化开发工具链
2. 等待设备连接
├── USB 连接:自动检测
├── 局域网:扫描同一 WiFi 的设备
└── 扫码连接:通过浏览器隧道
3. 输出二维码(局域网/远程调试)
输出示例:
Starting project at C:\project\device_app
Starting Metro Bundler
▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
▌ Expo Go ▐
▌ scan the QR code above or enter the code below ▐
▌ ▐
▌ TUNNEL https://exp.host/@username/project-name ▐
▌ LOCAL http://localhost:8081 ▐
▌ ▌
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
Logs for your project will appear below.
何时使用:
- 只需查看日志时
- 手机已安装好 app 后
- 需要扫码让其他人测试时(隧道模式)
- Metro 崩溃但不需要重新编译原生代码时
注意事项:
- 不会编译原生代码
- 不会安装 app 到设备
- 仅启动打包服务器
npx expo run:android
作用: 启动开发服务器 + 编译原生代码 + 安装到设备
bash
npx expo run:android
# 带指定设备
npx expo run:android --device "vivo V2338A"
# 清理原生代码后构建
npx expo run:android --no-bundler
详细行为:
┌─────────────────────────────────────────────────────────────────┐
│ npx expo run:android 执行流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 步骤 1: 检查环境 │
│ ├── 检测 Android SDK │
│ ├── 检测 Gradle 版本 │
│ └── 检查 USB 调试模式 │
│ │
│ 步骤 2: 启动 Metro(如未运行) │
│ ├── 读取 JavaScript 源码 │
│ ├── 打包为 bundle (.android.bundle) │
│ └── 发送到设备 │
│ │
│ 步骤 3: 原生编译 │
│ ├── 执行 ./gradlew assembleDebug │
│ ├── 合并 JavaScript bundle 和原生资源 │
│ └── 生成 APK 文件 │
│ │
│ 步骤 4: 安装到设备 │
│ ├── 通过 ADB 安装 APK │
│ ├── 启动应用 │
│ └── 建立开发服务器连接 │
│ │
└─────────────────────────────────────────────────────────────────┘
首次执行 vs 后续执行:
| 执行次数 | 耗时 | 原因 |
|---|---|---|
| 首次执行 | 2-5 分钟 | 需要生成所有原生代码和资源 |
| 后续执行 | 30 秒-1 分钟 | 只需增量编译 JavaScript |
何时使用:
- 日常开发调试(最常用的命令)
- 修改了 JavaScript/TypeScript 代码后
- 修改了 React Native 组件后
重要特性: 热重载
修改代码后:
- 保存文件
- Metro 自动重新打包
- 设备自动刷新(或手动摇晃手机触发)
npx expo prebuild
作用: 生成本地原生项目(Expo 管理的 Android/iOS 项目)
bash
# 清理并重新生成
npx expo prebuild --platform android --clean
# 仅生成 iOS
npx expo prebuild --platform ios
# 不清理直接生成
npx expo prebuild --platform android
详细行为:
┌─────────────────────────────────────────────────────────────────┐
│ npx expo prebuild 执行流程 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 步骤 1: 读取配置 │
│ ├── 读取 app.json / app.config.ts │
│ ├── 读取 expo.plugins (如 react-native-ble-plx) │
│ └── 解析权限、版本号、图标等配置 │
│ │
│ 步骤 2: 生成原生项目 │
│ ├── android/ 目录(如果不存在) │
│ │ ├── AndroidManifest.xml │
│ │ ├── build.gradle │
│ │ ├── settings.gradle │
│ │ └── 入口 Activity/Application │
│ └── ios/ 目录(如果不存在) │
│ ├── AppDelegate.mm │
│ ├── Info.plist │
│ └── Podfile │
│ │
│ 步骤 3: 应用配置 │
│ ├── 写入权限声明 │
│ ├── 配置插件(如蓝牙权限) │
│ └── 设置版本号和构建号 │
│ │
└─────────────────────────────────────────────────────────────────┘
何时使用:
- 首次添加需要原生配置的第三方库后(如 react-native-ble-plx)
- 修改了
app.json中的原生配置后 - 需要在 Android Studio/Xcode 中进行原生开发时
- 构建 Release APK 前
注意事项:
- 会修改
android/和ios/目录 - 这些文件应该加入
.gitignore(因为可从 config 重新生成) - 如果原生项目已存在,使用
--clean会删除后重新生成
npx expo doctor
作用: 检查项目配置和环境问题
bash
npx expo doctor
输出示例:
✔ Check package.json for common issues
✔ Check that native modules use Expo support
✔ Check for issues with build configuration
✗ Check JavaScript dependencies for known issues
Found 1 issue:
• Some dependencies are incompatible with Expo SDK 52
何时使用:
- 项目有问题但不确定原因时
- 安装新依赖后出现错误时
- 环境配置异常时
构建命令详解
Gradle 命令
Gradle 是 Android 的构建工具,Expo 底层使用 Gradle 进行原生编译。
Debug 构建
bash
cd android
./gradlew assembleDebug
作用: 构建 Debug 版 APK
输出位置 : android/app/build/outputs/apk/debug/
特点:
- 包含完整日志(方便调试)
- 未进行代码优化
- 体积较大
- 可以通过
adb logcat查看实时日志
Release 构建
bash
cd android
./gradlew assembleRelease
作用: 构建 Release 版 APK(正式发布版本)
输出位置 : android/app/build/outputs/apk/release/
特点:
- 移除所有
console.log日志 - 代码混淆和优化
- 体积更小
- 性能更好
- 无法直接调试,需要特殊工具
构建 Debug APK
bash
cd android
./gradlew assembleDebug
生成:android/app/build/outputs/apk/debug/app-debug.apk
构建 Release APK
bash
cd android
./gradlew assembleRelease
生成:android/app/build/outputs/apk/release/app-release.apk
构建 App Bundle (Google Play 推荐格式)
bash
cd android
./gradlew bundleRelease
生成:android/app/build/outputs/apk/release/app-release.aab
App Bundle vs APK:
| 格式 | 用途 | 优点 |
|---|---|---|
| APK | 直接安装 | 可分享给他人 |
| AAB | Google Play | 按设备架构生成最优 APK,体积更小 |
安装 APK 到设备
bash
# 安装 Debug 版
adb install android/app/build/outputs/apk/debug/app-debug.apk
# 安装 Release 版
adb install android/app/build/outputs/apk/release/app-release.apk
# 覆盖安装(保留数据)
adb install -r android/app/build/outputs/apk/release/app-release.apk
清理构建缓存
bash
# 清理所有构建产物
cd android
./gradlew clean
# 清理并重新构建
cd android
./gradlew clean assembleDebug
何时使用:
- 构建出现奇怪问题时
- 升级 Gradle 或依赖版本后
- 原生代码出现编译错误时
开发流程图解
日常开发流程
┌─────────────────────────────────────────────────────────────────────────┐
│ 日常开发工作流 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. 连接设备(USB 调试开启) │
│ │ │
│ ↓ │
│ 2. 执行开发命令 │
│ │ │
│ ├─→ 修改代码后测试 │
│ │ npx expo run:android │
│ │ │
│ ├──→ 仅查看日志 │
│ │ npx expo start │
│ │ # 手机摇晃 → Enable Fast Refresh │
│ │ │
│ └──→ 添加/修改原生配置 │
│ npx expo prebuild --platform android --clean │
│ npx expo run:android │
│ │
│ 3. 测试验证 │
│ ├── 蓝牙功能测试 │
│ ├── 界面渲染测试 │
│ └── 异常场景测试 │
│ │
│ 4. 修复问题 → 返回步骤 2 │
│ │
└─────────────────────────────────────────────────────────────────────────┘
完整发布流程
┌─────────────────────────────────────────────────────────────────────────┐
│ 完整发布流程 │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 阶段 1: 开发调试 │
│ ├── 代码开发 │
│ ├── 单元测试 │
│ └── 使用 npx expo run:android 本地调试 │
│ │
│ 阶段 2: 预发布检查 │
│ ├── 执行 npx expo doctor 检查配置 │
│ ├── 修复所有警告 │
│ └── 使用 ./gradlew assembleDebug 构建 Debug 版 │
│ │
│ 阶段 3: 回归测试 │
│ ├── 安装 Debug APK 到测试设备 │
│ ├── 完整功能测试 │
│ └── 蓝牙兼容性测试(多设备) │
│ │
│ 阶段 4: 构建 Release │
│ ├── npx expo prebuild --platform android --clean │
│ ├── ./gradlew assembleRelease │
│ └── 验证 app-release.apk 可正常安装和运行 │
│ │
│ 阶段 5: 发布 │
│ ├── 上传到 Google Play │
│ ├── 或通过 adb install 分发 │
│ └── 更新版本号(app.json → versionCode/versionName) │
│ │
└─────────────────────────────────────────────────────────────────────────┘
命令关系图
┌─────────────────────┐
│ 源代码 (.ts) │
└──────────┬──────────┘
│
┌───────────────┼───────────────┐
│ │ │
↓ ↓ ↓
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ expo start │ │expo run:android│ │ expo prebuild│
│ (仅打包) │ │ (打包+编译+安装)│ │ (生成原生项目)│
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
↓ ↓ ↓
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Metro Server │ │ Debug APK │ │ android/ │
│ (8081端口) │ │ (开发测试) │ │ 目录 │
└──────────────┘ └──────┬───────┘ └──────┬───────┘
│ │
↓ │
┌──────────────┐ │
│ gradlew │←───────────┘
│ assembleDebug│
└──────┬───────┘
│
↓
┌──────────────┐
│ gradlew │
│ assembleRelease│
└──────┬───────┘
│
↓
┌──────────────┐
│ Release APK │
│ (正式发布) │
└──────────────┘
常见问题与解决方案
问题 1: Port 8081 被占用
错误信息:
Port 8081 is already being used by another process.
Input is required, but 'npx expo' is not interactive.
解决方案:
bash
# 方案 1: 使用其他端口
npx expo start --port 8082
# 方案 2: 查找占用端口的进程(Windows)
netstat -ano | findstr :8081
# 然后结束进程
taskkill /PID <PID> /F
# 方案 3: 结束所有 Node 进程后重试
taskkill /F /IM node.exe
npx expo start
问题 2: SDK 位置未配置
错误信息:
Can't find SDK
解决方案:
创建 android/local.properties 文件:
properties
sdk.dir=C:\\Users\\你的用户名\\AppData\\Local\\Android\\Sdk
问题 3: Gradle 构建失败
错误信息:
FAILURE: Build failed with an exception.
解决方案:
bash
# 方案 1: 清理缓存后重试
cd android
./gradlew clean
./gradlew assembleDebug
# 方案 2: 删除 node_modules 后重新安装
cd device_app
rm -rf node_modules
npm install
# 方案 3: 重新生成原生项目
cd device_app
npx expo prebuild --platform android --clean
npx expo run:android
问题 4: 手机无法连接 Metro
症状: 手机提示 "Unable to load JavaScript"
解决方案:
bash
# 方案 1: 检查防火墙设置
# 确保 Windows 防火墙允许 Node.js 通过
# 方案 2: 使用局域网 IP
npx expo start --lan
# 方案 3: 使用隧道模式(外网访问)
npx expo start --tunnel
问题 5: 热重载不生效
解决方案:
bash
# 方案 1: 手动触发
# 手机摇晃 → 选择 "Enable Fast Refresh"
# 方案 2: 清理 Metro 缓存
npx expo start --clear
# 方案 3: 重启 Metro
# 在 Metro 终端按 Ctrl+C 停止,然后重新运行
命令速查表
日常开发
| 命令 | 用途 | 耗时 |
|---|---|---|
npx expo run:android |
启动开发环境 | 首次 3-5 分钟,后续 30 秒 |
npx expo start |
仅启动 Metro | 10-20 秒 |
npx expo start --clear |
清理缓存后启动 | 20-30 秒 |
npx expo start --port 8082 |
指定端口启动 | 10-20 秒 |
原生项目
| 命令 | 用途 | 耗时 |
|---|---|---|
npx expo prebuild --platform android --clean |
重新生成原生项目 | 1-2 分钟 |
npx expo doctor |
检查配置问题 | 30 秒 |
构建 APK
| 命令 | 用途 | 输出位置 |
|---|---|---|
./gradlew assembleDebug |
Debug 构建 | apk/debug/ |
./gradlew assembleRelease |
Release 构建 | apk/release/ |
./gradlew bundleRelease |
App Bundle | apk/release/ |
./gradlew clean |
清理构建缓存 | - |
安装和日志
| 命令 | 用途 |
|---|---|
adb install path/to/app.apk |
安装 APK |
adb install -r app.apk |
覆盖安装 |
adb uninstall com.package.name |
卸载应用 |
| `adb logcat | grep "BLE"` |
adb logcat --pid=$(adb shell pidof com.package.name) |
查看应用日志 |
总结
开发阶段 vs 命令选择
| 阶段 | 目标 | 推荐命令 |
|---|---|---|
| 编码 | 写代码 | 任意编辑器 |
| 调试运行 | 测试修改 | npx expo run:android |
| 仅看日志 | 排查问题 | npx expo start |
| 原生配置修改 | 添加蓝牙等 | npx expo prebuild |
| 构建 Debug | 测试完整包 | ./gradlew assembleDebug |
| 构建 Release | 发布应用 | ./gradlew assembleRelease |
黄金法则
- 日常开发 :
npx expo run:android一把梭 - 有问题先清理 :
npx expo start --clear或./gradlew clean - 发布前必做 :
./gradlew assembleRelease测试 - 遇到奇怪问题 :
npx expo doctor检查配置
最后更新: 2025-01-07
相关文档:
- Build-and-Deploy.md - 构建部署指南
- BLE-Implementation-Guide.md - BLE 配网实现
- Device-Compatibility-Analysis.md - 设备兼容性分析