资讯动态

用Expo创建React Native项目:从零到上线的完整实战指南

发布时间:2026/9/11 5:10:26 来源:尧图企业网站定制
前阵子帮朋友搭一个新的跨端项目对方开口就是“用expo创建react-native”我愣了一下——这个说法虽然有点绕但确实点出了当下 React Native 开发最主流的一条路直接用 Expo 这套工具链来初始化、开发、调试和打包 RN 应用。我用 Expo 创建 React Native 项目已经踩过不少坑从一开始的“这东西是不是玩具”到后来发现它在中小型项目里是真的省事。这篇文章就把我从零到一把项目跑起来的完整过程、关键决策、常见坑位一次讲清楚内容偏向实操适合刚接触 RN 生态的开发者也适合那些在裸 RN 和 Expo 之间反复纠结的人。1. 整体设计与思路拆解1.1 为什么选择 Expo 而不是裸 React Native先说一个很多人都有的误区以为 Expo 是 React Native 之外的另一套框架。其实不是Expo 是构建在 React Native 之上的一整套工具和服务它的核心目标是让你不用碰 Android Studio 和 Xcode也能完成 RN 应用的开发、调试和上架。我自己最早用 RN 是纯手动搭建环境那体验怎么说呢光是处理 Gradle 版本冲突和 CocoaPods 依赖就能耗掉一整个下午。后来切到 Expo最直观的感受是“原来 React Native 也可以这么好上手”。你不需要先装 JDK、SDK、模拟器只要装了 Node用 npx create-expo-app 创建项目再用手机装一个 Expo Go扫码就能在真机上看到界面。那是不是所有项目都该用 Expo也不是。如果你要做的是对原生代码高度定制的事比如需要集成某个第三方 SDK 且 Expo 没有对应模块或者你们团队本身就在维护一套原生代码库那这时候裸 RN 可能更合适。但如果你的目标是快速验证产品、开发业务逻辑密集的跨端应用、或者团队里没有专职原生开发人员Expo 绝对是目前性价比最高的选择。给个我常用的判断标准可以直接抄作业判断项选 Expo选裸 RN团队原生开发能力没有或很弱有专职原生开发需要自定义原生代码很少或不需要经常需要项目交付周期短要快速出结果长不急于上线是否需要 Expo 云服务需要或多设备联调频繁不需要已有原生项目需要集成否是1.2 创建 Expo 项目背后的核心流程拆解其实整个流程拆开来看就几个核心环节环境准备、初始化项目、选择模板、启动开发服务、真机联调、UI 组件选型、构建发布。每个环节单独看都不复杂但串起来的时候如果对底层机制不清楚很容易在某个点卡住。比如有个朋友在 Windows 上跑 Expo每次启动开发服务器都报错后来发现是防火墙把 8081 端口给拦了。还有人在创建项目时死活用不了模板参数最后才发现是 npx 缓存了旧版 create-expo-app。这些问题都不是什么高深技术但因为很少写进官方文档你只能一个个踩过去。所以我这篇文章不只是教你怎么敲命令更想帮你在脑子里建立一张完整的“Expo 项目创建全景图”。你知道了每一层在干什么之后遇到报错才会知道去哪里排查而不是搜到一条命令就盲目复制。2. 核心细节解析与实操要点2.1 环境准备Node、npm 和 Git 的基本要求先说环境这是整个流程里最不应该出错却最多人出错的地方。Expo 官方要求 Node LTS 版本我建议直接用 Node 18 或 20 的 LTS 版本。版本太老会导致 CLI 命令报语法错误版本太新又可能出现某些原生模块编译不兼容的问题。npm 一般会随着 Node 一起装上这没问题。Git 也建议装好因为 create-expo-app 初始化的项目默认就带 Git 仓库如果你机器上没装 Git项目创建后会有警告后面的版本管理也会受影响。我实际测试下来最容易忽略的是 Watchman。macOS 用户建议装上它用来监听文件变化。如果不装Metro Bundler 的文件监听机制可能因为系统文件描述符限制而失灵典型症状是你保存了代码但模拟器里界面半天不刷新或者刷新后直接红屏报错。Windows 用户则是另一个常见痛点cmd 和 PowerShell 执行 npx 时如果有权限问题可以先试试以管理员身份打开终端。实测下来 Windows 下用 Git Bash 跑 Expo 命令比 PowerShell 稳。再来检查一下环境node -v npm -v git --version三条命令正常输出版本号就说明基础环境没问题。2.2 创建项目的三种方式和模板选择创建 Expo 项目现在统一用 create-expo-app 这个脚手架命令很简洁npx create-expo-applatest默认会在当前目录下创建一个叫 app 的新目录名称可以这样指定npx create-expo-app my-expo-app如果想直接用 TypeScript 模板可以用npx create-expo-app my-expo-app --template blank-typescript用 npx 的好处在于每次都拉取最新版本避免本机缓存了旧版导致创建出来的结构过时。我第一次用的时候没加 latest结果拿到的是很老的模板里面连 expo-router 都没有排查了挺久才明白是缓存问题。Expo 官方模板其实分好几种我列几个常用的blank最干净的 JavaScript 模板适合想自己搭结构的老手blank-typescript同上但内置 TypeScript 配置现在新项目我基本都用这个tabs自带底部导航和 expo-router 文件路由的模板适合起步就要多页面的项目bare-minimum这个要留意它会生成一个裸 RN 工程而不是纯 Expo 托管工作流新手我建议直接用 blank-typescript别选 tabs。底下的导航结构虽然方便但如果你对 expo-router 的路由机制还不熟悉改起来反而绕。blank-typescript 给你的是一块干净的地基后续加什么都很顺手。提示创建项目时如果网络不稳定容易卡在 “Downloading and extracting project files.” 这一步。建议在终端里配置好 npm 的淘宝镜像再跑速度会快很多命令是npm config set registry https://registry.npmmirror.com。2.3 启动项目与 Expo Go 联调项目创建完成后进入目录启动开发服务cd my-expo-app npx expo start运行之后终端会显示一个二维码同时提供几个快捷键a 是打开 Android 模拟器i 是打开 iOS 模拟器w 是在浏览器里打开。如果没有配置模拟器也没关系直接用手机上的 Expo Go 扫码就能跑。这里插一句 Expo Go 的问题。很多新手下载 Expo Go 时会困惑为什么应用商店里搜出来一堆第三方工具因为 Expo Go 是 Expo 官方发布的预览客户端iOS 在 App Store 里搜 “Expo Go”Android 在应用市场或官网下载 APK。它本身不是一个完整开发环境而是用来连接你电脑上 Metro Bundler 的“预览窗口”。用 Expo Go 联调时手机和电脑必须在同一个局域网内。有两个细节值得注意第一如果手机扫码后一直显示 “Connection refused” 或者长时间卡在加载界面大概率是电脑防火墙拦了 8081 端口。Windows 用户记得在防火墙设置里放行 Node.jsmacOS 用户检查一下网络是否开启了“允许入站连接”的拦截。第二如果你在公司网络或某些公共 WiFi 下局域网隔离会把设备之间的通信掐掉。遇到这种情况可以试试用 Expo 的 tunnel 模式启动npx expo start --tunnel这个命令会通过 Expo 的云端服务建立一条隧道手机和电脑不在同一网络也能连。不过隧道模式依赖网络质量稍有延迟但应急时很管用。3. 实操过程与核心环节实现3.1 目录结构的逐层解读项目创建好之后结构比裸 RN 要简洁很多这是 Expo 托管工作流的一大优点。我先把核心文件逐一拆开讲不然新手很容易对着目录发懵。my-expo-app/ ├── .expo/ ├── assets/ ├── node_modules/ ├── app/ │ └── index.tsx ├── app.json ├── package.json ├── tsconfig.json └── ...app.json是 Expo 项目最重要的配置文件它替代了裸 RN 里很多原生配置。应用名称、图标、启动屏、权限声明等都在这里管理。我实际改过的一个示例如下{ expo: { name: My Expo App, slug: my-expo-app, version: 1.0.0, orientation: portrait, icon: ./assets/icon.png, userInterfaceStyle: light, splash: { image: ./assets/splash.png, resizeMode: contain, backgroundColor: #ffffff }, ios: { supportsTablet: true, bundleIdentifier: com.example.myapp }, android: { package: com.example.myapp, adaptiveIcon: { foregroundImage: ./assets/adaptive-icon.png, backgroundColor: #ffffff } }, web: { favicon: ./assets/favicon.png } } }新版本的 Expo 默认使用目录即路由也就是说app/目录下的文件结构就是应用的页面路由结构。app/index.tsx对应首页你再加一个app/about.tsx就自动有了/about这个路由页面。这是 expo-router 的规则理解这一点后面做多页面会在心智上轻松很多。assets/目录放静态资源图标、启动屏、字体文件都放这里。注意这里的图标引用路径写在 app.json 里所以资源的文件名不能随意改改了就要同步更新配置。3.2 配色、基础组件与导航的快速实现项目创建好之后第一件事就是把默认页面改掉。这里我建议先把基础设计规范定下来即颜色、间距、字体大小我一般直接在入口文件里建立一个主题对象。打开app/index.tsx可以看到默认模板的核心代码逻辑。我自己习惯先改成这样一套布局import { StatusBar } from expo-status-bar; import { StyleSheet, Text, View } from react-native; export default function App() { return ( View style{styles.container} Text style{styles.title}欢迎来到 Expo 开发/Text Text style{styles.subtitle}这是一个由 Expo 创建的项目/Text StatusBar styleauto / /View ); } const styles StyleSheet.create({ container: { flex: 1, backgroundColor: #f5f5f5, alignItems: center, justifyContent: center, }, title: { fontSize: 24, fontWeight: 600, color: #333, }, subtitle: { fontSize: 16, color: #666, marginTop: 8, }, });保存文件Metro 会自动热更新模拟器里的界面立刻变化。这套开发体验就是 Expo 最大的价值所在改代码像写网页一样即时反馈不用重新编译原生工程。需要说明的是StyleSheet.create 在 Expo 里和裸 RN 完全一致都是 React Native 的样式系统。flex 布局是默认布局方式flex: 1表示占满父容器剩余空间alignItems 和 justifyContent 控制水平垂直居中。如果对 flex 不熟建议先去补一下基本概念因为后面所有页面布局都离不开它。3.3 网络请求与数据展示的完整案例开发一个实际应用不可能只停留在静态页面。我找一个最常见的业务场景——从远程接口拿数据并渲染列表来演示 Expo 项目下的完整数据流。先安装一个轻量的 HTTP 客户端Expo 支持 axiosnpm install axios然后封装一个简单请求// services/api.ts import axios from axios; const api axios.create({ baseURL: https://api.example.com, timeout: 10000, }); export async function fetchPosts() { const response await api.get(/posts); return response.data; }在页面组件中使用 useEffect 拉取数据同时用 useState 管理加载状态和错误状态import { useEffect, useState } from react; import { FlatList, Text, View, ActivityIndicator } from react-native; interface Post { id: number; title: string; body: string; } export default function HomeScreen() { const [posts, setPosts] useStatePost[]([]); const [loading, setLoading] useState(true); const [error, setError] useState(); useEffect(() { fetchPosts() .then((data) setPosts(data)) .catch((err) setError(err.message)) .finally(() setLoading(false)); }, []); if (loading) { return ActivityIndicator sizelarge color#333 /; } if (error) { return Text加载失败{error}/Text; } return ( FlatList data{posts} keyExtractor{(item) item.id.toString()} renderItem{({ item }) ( View style{{ padding: 16, borderBottomWidth: 1 }} Text style{{ fontSize: 18, fontWeight: 600 }}{item.title}/Text Text style{{ fontSize: 14, color: #666, marginTop: 4 }}{item.body}/Text /View )} / ); }这就是一个标准的 RN 应用页面骨架。FlatList 是长列表渲染的核心组件它的存在解决了上万条数据渲染卡顿的问题内部做了窗口化只渲染可见区域附近的项。这是 RN 开发里一个非常重要的概念写列表页时别用 ScrollView 加 map性能差距会非常明显。3.4 配置自定义字体、图标和基础 UI 库当项目从“跑起来”进入“像样”的阶段就该考虑 UI 了。这里正好回应一下热搜词里的 “expo ui库”。很多新手以为 Expo 内置了一堆现成的 UI 组件其实它没有。Expo 提供的更多是原生能力模块比如相机、定位、文件系统而不是像 Bootstrap 那样的现成组件库。所以你还需要在 npm 生态里选一个 UI 组件库。我按自己用过的经验做一个对比组件库风格适合场景备注React Native PaperMaterial Design快速做后台管理类、表单类上手快社区活跃NativeBase通用型中小型业务项目3.x 版本改版后配置略重Tamagui高性能跨平台想要统一样式系统的团队适合重定制场景学习成本高UI KittenEva Design System追求视觉一致性的应用内置主题系统适合中后台风格我自己在 Expo 项目中最常用的是 React Native Paper因为它安装简单、对 Expo 支持好而且 Material 风格的组件在 iOS 和 Android 上都有不错的表现。一般的业务系统包括登录、列表、表单、数据统计页面这个库都能覆盖。安装命令如下npm install react-native-paper然后在入口文件用 Provider 包裹import { PaperProvider } from react-native-paper; export default function RootLayout() { return ( PaperProvider HomeScreen / /PaperProvider ); }之后就能在页面里直接使用 Paper 的组件例如Button、TextInput、Card它们已经内置了规范化的颜色和间距设计省去大量重复写样式的时间。除了 UI 库图标也值得说一句。Expo 官方自带expo/vector-icons里面封装了超过 20 个图标集包括 Ionicons、MaterialIcons、FontAwesome 等几万个图标随心用不需要手动配置。使用方式也很简单import { Ionicons } from expo/vector-icons; Ionicons namehome size{24} colorblack /这个组件库是 Expo 项目默认集成的你几乎不需要额外配置对图标名不确定的可以查看官网的图标列表页面或者直接在代码里试。4. 常见问题与排查技巧实录4.1 视频读取错误 0xc00d36b4 的真实排查过程最近热搜词里有一条看起来很奇怪它是一条 Windows 系统报错windowsvideomedia error 0xc00d36b4 while reading d:\dx\dxkxq_dataoutput\expo。很多人把它和 Expo 开发环境联想到一起我一开始也被误导了实际查了一圈才发现这个错误码 0xc00d36b4 是 Windows Media Foundation 的视频读取错误常见原因是文件损坏或视频编码格式不被当前播放器支持。具体到这条报错报错里出现 expo 是因为某类自动化脚本把视频文件输出到了与 expo 相关的目录。那是业务流程的问题不是 Expo 框架的问题。但这件事也给了我们一个提示在 Windows 上做 Expo 开发副作用可能来自各种你想不到的地方。我的排查思路是分三步的第一步确认报错来源。凡是看到 0xc00d36b4 这种 Windows 多媒体错误码先判断是否与自家项目代码有关系。建议直接在项目目录下搜索报错中的文件路径如果 d:\dx... 这个目录不是你的 Expo 项目目录那基本可以断定是其他软件在读取视频文件而不是 Expo 本身出错。第二步检查视频文件本身。用系统自带的“电影和电视”打开确认是否能正常播放。如果打不开用格式工厂或 FFmpeg 重新转码为 H.264 AAC 的标准 MP4 格式这个组合兼容性最好。Expo 官方文档对视频模块要求的编码格式也推荐使用 H.264 视频编码和 AAC 音频编码。第三步清理系统环境。如果你确认报错发生在开发过程中且文件路径指向项目目录可以尝试删除 node_modules 和 .expo 目录后重新安装rm -rf node_modules .expo npm install npx expo start -c-c参数会清空 Metro 缓存很多莫名其妙的资源加载问题就能解决。我之前遇到过几次启动项目后白屏就是 Metro 缓存文件损坏导致的清缓存永远是第一优先级的排障动作。4.2 Expo Go 无法连接与扫码失效问题Expo Go 连接不上开发服务器算是出现频次最高的一个问题我把它单拎出来讲因为排障思路很有代表性。如果你点击二维码没反应、扫码又说找不到服务器按从简到繁的顺序排查先确认手机和电脑在同一个 WiFi 网络。这一步看着简单实际中很常见手机自动连了 5G 频段电脑连的是 2.4G 频段或者两台设备在不同 VLAN 下都会导致相互发现不了。然后确认终端里的地址。运行npx expo start后终端会显示类似exp://192.168.1.5:8081的地址你的手机必须能够访问到这个 IP把地址复制到手机浏览器里测试一下如果能访问说明网络通不能访问就查防火墙。Windows 下最常见的是防火墙拦截 Node.js。解决办法是控制面板进入“允许应用通过防火墙”把 Node.js 的专用和公用都勾上或者干脆在首次出现防火墙提示时点“允许访问”。如果以上都没问题就用隧道模式兜底npx expo start --tunnel它会通过远程服务器建立连接绕开局域网限制代价是传输速度略慢但在咖啡厅、酒店这种网络环境复杂的场景下隧道模式就是我最后的保命手段。4.3 其它高频问题备忘按我自己的经验把常见问题做成一个速查表遇到直接对号入座现象可能的根因解决方案npx create-expo-app卡住不动网络问题或 npx 缓存了旧版本设置镜像源后重试或用npx create-expo-applatest启动后白屏控制台无报错Metro 缓存损坏npx expo start -c修改代码后页面不刷新Watchman 未安装或文件监听失效macOS 安装 WatchmanWindows 改用 Git Bashnpm install时权限报错全局依赖权限问题用 npx 替代全局安装避免 sudo应用启动时找不到 expo 模块node_modules 损坏删除 node_modules 后重新 npm install图片资源 setTimeout 后不显示地址引用错误或缓存清理 .expo 目录并重启TypeScript 报找不到模块路径别名未配置在 tsconfig.json 里配置 paths4.4 几个值得记住的调试技巧有些技巧是官方文档里不起眼的角落但对开发效率提升非常显著。第一个是 Expo 开发菜单。在 Expo Go 里摇一摇手机或者按m键模拟器可以打开开发者菜单里面有强制刷新、打开 React DevTools、查看组件布局等入口。这个菜单是日常调试的核心入口很多新手不知道遇到问题只能干瞪眼。第二个是 React DevTools。它可以在开发者菜单里直接启动弹出的独立窗口能查看组件树、props、state 的变化。这比单纯看日志定位问题要快得多尤其是处理列表组件的重复渲染问题时。第三个是日志输出。Expo 支持在终端里直接看到应用内的 console.log 输出还可以按层级过滤。开发时在该加日志的地方不要吝啬线上问题难查大多是因为当时没留足排查线索本地联调时多打几行日志不会错。注意如果你在 Windows 上使用 Expo需要特别注意项目路径中不要包含中文、空格或特殊字符。比如D:\开发项目\my-expo-app这种路径会在 Metro 打包时出现各种奇怪报错。统一用全英文、无空格的路径可以省去一多半的路径相关问题。5. 从创建到构建发布的完整工作流5.1 什么时候该用 EAS Build用 Expo 开发到一定程度你需要把应用打包成正式的安装包。这里必须讲清楚一个概念Expo Go 只是一个预览工具它不能用于最终发布。想要生成独立的 APK 或 IPA需要走构建流程。当前 Expo 推荐的构建服务是 EAS Build全称 Expo Application Services。它是云端的构建服务你本地提交代码配置它在远程服务器上完成原生编译最后返回安装包。好处是不用自己配原生环境坏处是免费额度有限而且云端构建需要排队等待。安装 EAS CLI 并登录npm install -g eas-cli eas login在项目目录下初始化配置eas build:configure这个命令会生成eas.json配置文件里面定义了 development、preview、production 三种构建档位。你需要根据平台执行构建命令eas build -p android --profile preview eas build -p ios --profile previewiOS 需要 Apple Developer 账号和对应的证书Android 则相对简单生成的 AAB 文件可以直接上传到应用商店。这个流程第一次跑会有点懵但跑通一次后后续和 CI/CD 接起来就顺了。5.2 和现有团队项目的迁移方案最后聊一个很多人实际会遇到的场景团队里已经有一套老的 RN 项目代码写得乱糟糟想借 Expo 重新梳理一遍。这时候不建议直接迁移所有组件风险太大。我自己的做法是“渐进式迁移”第一步先新建一个 Expo 空白项目把全局配置、路由结构、设计规范搭好。第二步把老项目里最核心的页面迁移过来优先处理业务逻辑暂不管样式细节。第三步写一个简单的兼容层将老项目的自定义组件转换成 Expo 生态下对应的 UI 组件。第四步确认核心页面表现稳定后再逐个迁移剩余页面。这个过程不需要一步到位exp 老项目共存的过渡期也可以用 Expo 的web支持来快速验证页面效果。等到后续迭代稳定了再考虑彻底弃用老工程。说实话我很少见到有团队能一次把老 RN 项目完整迁移到 Expo大多数情况都是拿 Expo 起新项目、新模块或者用在新业务的快速验证上。如果你是维护老项目的先别急着推倒重来把 Expo 引入到新功能模块上跑通之后大家自然就有信心了。6. 最后的几点实操体会写到这里整条“Expo 创建 React Native 项目”的链路已经完整走了一遍。结合我自己的实践最后再分享几个真实体会。模板一定要用 TypeScript。我第一次用 Expo 时选的默认 JavaScript 模板后来项目规模上去了类型问题开始成为隐性负担在 IDE 里面跳转定义、重构变量都需要额外的心智成本。换成 TypeScript 模板之后代码的可维护性提升不是一点点而且 Expo 对 TypeScript 的支持已经很成熟不需要你额外做太多配置。UI 库和设计系统越早定越好。项目前期为了省时间东用一个组件、西用一个原生组件等界面多了风格会越看越不统一。后面再想统一就要付出额外成倍的修改成本。建议项目第一天就选定 UI 库定好主色、辅色、间距规范后续所有页面都遵守这套规则。调试能力的优先级被很多人低估。很多新手拿到项目就开始写业务遇到问题只会用 console.log 硬调。实际上 Expo 的调试体系已经很完善开发菜单里那些工具用熟了定位问题的速度会快很多。花半天时间把这些工具摸透后期至少能省下几十个小时的埋头痛查时间。最后保持项目目录的干净。这个建议听着琐碎但确实是我踩过坑之后的教训。之前有个项目因为路径里带了中文目录名Metro 打包时反复报错排查了将近两个小时才找到原因。之后所有项目我都统一用英文小写加短横线命名这比任何技巧都可靠。如果你正打算用 Expo 创建自己的 React Native 项目照着这篇文章的流程走一遍应该能很顺利地把第一个应用跑起来。后面的路——新页面、新组件、新业务模块——就是在扎实的基础上不断叠加的过程了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价