【实战复盘】基于 Cursor + Expo 的跨平台 App 开发:从零到打包的全流程踩坑记录
一、前言与背景
本文记录了一次无前端/移动端经验的新手,完全依托 AI 工具与跨平台框架(React Native + Expo)从零构建移动端 App 的过程。文章按实际开发时间线,拆解每一步的具体操作与遇到的问题(Pitfalls),并提供工程化的解决方案(Solutions)。由于篇幅限制,本文主要探讨技术实现与工具链的配置,不涉及具体业务逻辑。
阅读建议:如果你也是第一次接触移动端开发,建议按章节顺序阅读,每一步的坑都是后一步的前置条件。
二、开发环境与工具链
| 用途 | 工具 | 说明 |
|---|---|---|
| 主要代码生成 | Cursor | 直接修改本地文件 |
| 技术攻坚与诊断 | DeepSeek | 解析长堆栈错误、梳理架构逻辑 |
| 终端与打包工具 | Windows PowerShell、EAS(Expo Application Services) | 本地命令执行与云端构建 |
| 核心框架 | React Native(Expo SDK 57)、Zustand | 跨平台 UI 与状态管理 |
| 运行环境 | Node.js LTS(建议 20.x 及以上)、手机端 Expo Go | 本地运行时与真机预览,Expo Go 版本需与本地 SDK 对齐 |
三、开发全流程拆解与问题排查
本章按实际开发顺序拆解七个步骤,每一步都依赖前一步的环境基础,建议按顺序阅读:
- 步骤一(环境搭建):打通 Node.js 与 PowerShell,是一切命令执行的前提。
- 步骤二(项目初始化与联调):创建项目并让手机端成功连上本地开发服务器。
- 步骤三(依赖与框架修正):解决导航库版本不兼容导致的红屏。
- 步骤四(隐性语法错误诊断):排查 AI 写入文件时引入的编码与转义问题。
- 步骤五(状态管理排查):让数据真正写入全局状态并正确订阅。
- 步骤六(环境变量与外部 API):安全存放密钥并正确读取配置。
- 步骤七(云端打包):通过 EAS 产出可安装的 APK。
步骤一:本地基础环境搭建
【执行操作】:前往 Node.js 官网下载 LTS 版本并完成安装,打开 PowerShell 准备执行包管理命令。
【遇到问题】:执行 npm -v 时报错 无法将“npm”项识别为 cmdlet...。配置好路径后,执行命令提示 因为在此系统上禁止运行脚本。
【排查与解决】:
- 问题 1 是因为 Windows 系统变量未同步。手动进入环境变量,在
Path中新增C:\Program Files\nodejs\,重启终端生效。 - 问题 2 是 Windows 默认的安全执行策略限制。执行以下命令将策略放宽:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
步骤二:项目初始化与跨端联调(局域网连接破局)
【执行操作】:使用 npx create-expo-app 创建项目,运行 npx expo start 生成二维码,使用手机端 Expo Go 扫码预览。
【遇到问题】:终端提示要下载 expo@58.0.19(导致版本冲突)。手机扫码后无法连接,一直处于白屏转圈或报错。
【排查与解决】:
- 问题 1 是因为终端停留在系统根目录,系统误判为新建项目。需先
cd进入项目文件夹。 - 问题 2 的排查过程较曲折:首先确保手机与电脑连接在同一个 Wi-Fi(局域网)下。发现直接扫码经常因为网络隔离或路由器设置而连接失败。最终有效的解决方式是:放弃扫码,直接在终端找到
exp://192.168.x.x:8081这样的本地局域网地址,然后在手机端 Expo Go 首页选择“Enter URL manually(手动输入 URL)”,将地址准确输入,最终成功连接。
注:还需确保手机端 Expo Go 版本与本地 SDK 版本严格对齐。
步骤三:依赖冲突与底层框架修正
【执行操作】:让 Cursor 生成页面的路由跳转与导航栏代码。
【遇到问题】:手机端直接红屏报错 As of SDK 56, expo-router is no longer compatible with react-navigation。
【排查与解决】:AI 模型使用了旧版的 @react-navigation/* 依赖。需指导 Cursor 按官方规范,将所有导航相关的导入重写为 expo-router 的最新语法。
步骤四:AI 生成的“隐性语法错误”与深度诊断
【执行操作】:让 Cursor 批量修改配置文件(如 package.json)。
【遇到问题】:项目突然无法启动,终端报 JSON5: invalid character 或 Unexpected token。
【排查与解决】:肉眼检查代码无语法错误。最终定位到 AI 在写入文件时,将换行符硬编码为了字符串(如 \n),或写入了不可见的 UTF-8 BOM 头。
【引入 DeepSeek】:当 Cursor 陷入“自己改错自己看”的盲区时,我将终端冗长的报错信息复制给 DeepSeek。DeepSeek 精准定位了问题不在代码逻辑,而是字符编码问题,并给出了排查思路:确认文件是否带有 BOM 头、检查配置文件中的换行符是否被转义。按此思路处理后,项目恢复正常启动。
步骤五:状态管理与数据流向排查
【执行操作】:让 Cursor 实现表单提交与数据保存功能。
【遇到问题】:界面点击无反应,或者数据保存后刷新即丢失,终端无报错。
【排查与解决】:AI 有时只完成 UI 渲染和点击事件,未将数据写入全局状态库(Zustand)。
【引入 DeepSeek】:我将 store.ts 和相关页面的核心代码发给 DeepSeek。DeepSeek 指出,页面组件未通过 Selector 正确订阅 Store 的状态更新。通过其提供的 Zustand 最佳实践代码重构后,数据实现了无缝同步。
下面是一个最小可用的 Zustand Store 示例,页面组件按字段订阅即可避免整库订阅带来的重渲染:
import { create } from 'zustand';
interface FormState {
value: string;
setValue: (value: string) => void;
}
export const useFormStore = create<FormState>((set) => ({
value: '',
setValue: (value) => set({ value }),
}));
// 页面组件中按字段订阅,避免整库订阅导致的不必要重渲染
// const value = useFormStore((state) => state.value);
// const setValue = useFormStore((state) => state.setValue);
步骤六:环境变量(.env)配置与外部 API 接入
【执行操作】:创建 .env 文件存放 API Key,并编写网络请求代码。
【知识点补充:什么是 .env?】:在开发中,调用外部 API(如大模型)需要用到敏感密钥(API Key)。如果把 Key 直接写在代码里,不仅容易泄露,后期切换测试/正式环境也极不方便。.env 文件就是一个“安全保险箱”,把密钥和配置写在这里,代码中通过 process.env.XXX 读取,既安全又灵活。
【遇到问题】:在终端使用 curl 测试接口时,请求被服务端直接封禁。在代码中修改了 .env 里的 Key,但 App 里用 process.env.XXX 读取时,始终为 undefined。
【排查与解决】:
- 问题 1:部分第三方 API 服务商会拦截
curl的请求头。放弃终端测试,直接在 App 代码中用fetch发起请求。 - 问题 2(新手极容易踩的坑):Expo(以及绝大多数 Node.js 框架)仅在项目冷启动的那一刻读取环境变量。 如果你在项目正在运行的过程中新建或修改了
.env文件,运行中的 App 是感知不到的。必须按Ctrl+C停止当前服务,然后带上清除缓存的参数重启:
npx expo start -c
重启后,App 才能成功读取到最新的环境变量。
步骤七:云端打包(EAS)与构建报错
【执行操作】:使用 EAS 执行 eas build -p android --profile preview 生成 APK。
【遇到问题】:云端排队编译数分钟后,提示 Gradle build failed。
【排查与解决】:由于云端报错信息非常长且夹杂复杂的 Gradle 堆栈,我将完整的构建日志丢给了 DeepSeek。DeepSeek 像剥洋葱一样,从冗长的日志中排查出底层依然是配置文件格式错误导致了构建中断。修复后,在执行命令时加入跳过指纹检查的环境变量,成功绕过缓存问题:
$env:EAS_SKIP_AUTO_FINGERPRINT=1; eas build -p android --profile preview
四、实战经验总结(非技术向坑位)
在最终的线下路演(Live Demo)环节,由于使用了临时借用的不熟悉设备(Mac),导致操作卡顿,演示节奏被打乱。
工程建议:
- 设备锁定:任何 Live Demo 必须使用自己最熟悉的开发机,提前关闭弹窗通知。
- Plan B 预案:针对现场网络波动、环境异常等不确定因素,建议提前录制一份高质量的完整操作视频,作为意外发生时的替代方案。
五、给新手的 AI 编程建议
- 多模型协作(Multi-Model Workflow):不要把所有的任务压给同一个 AI。建议使用 Cursor 负责主干代码的编写和文件修改,同时使用 DeepSeek 等具备强大逻辑分析能力的模型作为“外脑”,用来解答长报错、审查底层逻辑和提供架构建议,双管齐下能解决 99% 的问题。
- 物理备份优先:AI 具备很强的破坏力,一次指令误操作可能崩溃整个项目。在每次核心功能跑通且无 Bug 时,直接复制整个项目文件夹作为快照(v1、v2……),这是新手最稳妥的回滚方案。
- 控制 Prompt 颗粒度:避免一次性提出多页面、多交互的复合需求。拆解为原子级任务(如:先改 UI → 测试 → 再加数据逻辑),逐步验证。
六、常见问题速查表
下表把前文七个步骤中的典型坑位压缩成一张对照表,方便遇到问题时快速定位到对应章节。
| 阶段 | 典型报错或现象 | 核心原因 | 解决方案 |
|---|---|---|---|
| 步骤一 | 无法将“npm”项识别为 cmdlet | Windows 系统变量未同步 | 在 Path 中新增 Node.js 安装目录并重启终端 |
| 步骤一 | 因为在此系统上禁止运行脚本 | PowerShell 默认执行策略限制 | 执行 Set-ExecutionPolicy -Scope CurrentUser RemoteSigned |
| 步骤二 | 终端提示下载 expo@58.0.19 | 终端停留在系统根目录,误判为新建项目 | 先 cd 进入项目文件夹再执行命令 |
| 步骤二 | 手机扫码白屏、无法连接 | 局域网隔离或路由器设置导致扫码地址不可达 | 手动输入 exp://192.168.x.x:8081,并保证 Expo Go 与 SDK 版本对齐 |
| 步骤三 | expo-router is no longer compatible with react-navigation | AI 生成了旧版 @react-navigation/* 依赖 | 按官方规范把导航导入重写为 expo-router 语法 |
| 步骤四 | JSON5: invalid character 或 Unexpected token | 换行符被硬编码为字符串,或文件带 UTF-8 BOM 头 | 借助 DeepSeek 定位编码问题,检查 BOM 与转义字符 |
| 步骤五 | 点击无反应、刷新后数据丢失 | 数据未写入 Zustand,或组件未正确订阅状态 | 用 Selector 按字段订阅 Store,补齐写入逻辑 |
| 步骤六 | process.env.XXX 读取为 undefined | 运行中的进程不会重新读取 .env | 按 Ctrl+C 停止服务后执行 npx expo start -c 重启 |
| 步骤七 | Gradle build failed | 配置文件格式错误导致构建中断,或缓存指纹异常 | 修复配置后加 EAS_SKIP_AUTO_FINGERPRINT=1 重新构建 |
更多推荐

所有评论(0)