本节摘要:创建 React Native 项目有 Expo 与社区脚手架两条主流路线。Expo 上手快、零配置、可在真机即时预览,适合初学者与快速迭代;社区脚手架更贴近原生工程,适合需要深度定制原生能力的项目。本节讲清两条路线的创建、运行与项目结构,帮你跑起第一个应用。核心认知是"双层架构"——JS 层开发、原生层底座、桥负责通信。
阅读完本节,你应当能够:
在 React Native 的世界里,第一道选择题不是"写什么代码",而是"用哪条路创建项目"。两条路各走一边:Expo 走的是"省事"路线,开箱即用、无需配置原生工程、扫码就能在真机上预览;社区脚手架走的是"原生"路线,生成完整的 android 与 ios 原生工程,能深度定制原生能力,但配置成本高。
怎么选?给两个判断标准:如果你刚入门、想最快看到应用跑起来,用 Expo;如果你的项目明确需要自定义原生模块、要接入复杂的原生 SDK,用社区脚手架。很多人最后会从 Expo 起步、再转社区脚手架,这是合理的成长路径——先用低门槛跑通,再追求完整控制。
这里有个容易被忽略的事实:两条路线产出的项目,写的组件代码几乎完全一样。View、Text、样式、状态管理这些核心语法不受创建方式影响。区别只在于工程形态与原生能力的深度。所以你不必把选路线当成"选错了就回不了头"的大事——代码层面是可以迁移的,真正锁死的只是工程形态。这个认知能让你放心地从简单的那条路开始。
Expo 的本质是"托管式"工作流。它把原生工程的复杂度藏起来,提供一套标准化的构建与开发工具。你写的代码运行在 Expo 提供的运行时里,原生能力通过 Expo SDK 提供。好处是零配置、迭代快、真机预览方便;代价是你对原生层的控制力变弱,某些自定义原生功能需要"弹出"到社区工程才能做。
社区脚手架的实质是生成完整的原生工程骨架。你能直接看到并修改 android 与 ios 两个原生目录,可以随意接入自定义原生模块。好处是完整控制力;代价是首次配置、升级维护的成本明显更高。
Expo 的创建命令也是脚手架式,但流程多一步"选模板":
npx create-expo-app MyExpoApp
创建时会提示选择模板:空白项目(blank)、带 TypeScript 的空白项目、带导航栏的示例项目(tabs)等。对初学者,空白模板最干净——没有多余代码干扰理解。
Expo 最吸引人的是真机预览。装好 Expo Go 应用(手机应用商店里就能找到),手机和电脑连同一 Wi-Fi,扫码即可在真机上打开应用,无需构建、无需数据线。这个体验对"想快速看看效果"的场景非常友好。Expo 也保留了 Web 支持,浏览器里也能预览。
什么时候需要"弹出"。当你的项目需要自定义原生模块、修改原生配置文件,而 Expo 的托管式工作流无法满足时,需要把工程"弹出"成社区工程。这是一条单行道,弹出后通常无法回到托管模式,所以决策要慎重。多数学习阶段的 App 用不到弹出,先把托管模式玩熟再说。
以社区脚手架路线为例(这是理解原生工程最直接的方式),创建命令:
npx react-native init AwesomeProject
npx 是 npm 自带的小工具,会在不全局安装的情况下运行指定命令。命令执行后生成名为 AwesomeProject 的项目目录,包含完整的原生工程骨架。初始化可能需要几分钟,耐心等待。
关于 react-native init 的现状。社区脚手架的命令形式几经变化,早期是全局安装 react-native-cli,现在是 npx 直接调用。有些新版本可能提示命令弃用或要求特定参数,遇到时以命令输出里的提示为准。核心不变:它生成一个带 android 与 ios 原生工程的项目骨架。
前面章节讲过 React Native 是"JS 层做开发、原生层做底座"的双层结构,创建完项目后这个结构就具象化了:

记住这张图的层次关系:你平时写的是 JS 层,需要平台能力时下探原生层,桥负责两层通信。理解了它,就理解了整个 React Native 工程的骨架。
对初学者,几个关键文件值得花几分钟逐一打开看看:
index.js 是应用入口,它的核心工作是注册根组件。你通常不需要改它,但要知道它存在——它负责告诉系统"启动时加载哪个组件"。
App.js 是你的主战场。默认的 App.js 展示欢迎界面,你可以在这里改出第一个属于自己的页面。第 3 章开始,你会频繁进出这个文件。
package.json 是依赖与脚本的清单。新增第三方库时,包名要加进 dependencies 段;跑各种命令用的脚本定义在 scripts 段里。它是 JS 生态的"配置文件之王",值得熟悉。
android 与 ios 目录是原生工程。默认情况下你不需要碰它们,但要认识它们——它们是"双层结构"的底座。第 6 章讲原生模块时,我们才真正动这两块。
在项目根目录下执行:
cd AwesomeProject npx react-native run-android
首次运行会下载 Gradle 依赖并编译原生工程,耗时较长,耐心等待。Android 模拟器或连接的设备会被自动识别。macOS 上可用类似命令跑 iOS 模拟器。
Metro 打包器是什么。运行命令背后有一个隐藏角色:Metro。它是 React Native 的 JavaScript 打包器,负责把项目里的 JS 代码打包、交给设备执行。你在终端看到的"启动 Metro"或"打包中"的日志,就是它在工作。很多"代码改了没反应"的问题,源头都是 Metro 缓存或连接问题,而不是代码本身。认识它,排错就有了方向。
| 维度 | Expo | 社区脚手架 |
|---|---|---|
| 上手速度 | 快,零配置 | 慢,需配置原生工程 |
| 原生工程可见 | 隐藏,默认不可见 | 完整可见可改 |
| 原生定制能力 | 弱,需弹出工程 | 强,直接改原生代码 |
| 真机预览 | 扫码即用(Expo Go) | 需构建安装 |
| 适合场景 | 初学者、快速迭代 | 深度原生集成项目 |
读这张表时注意"适合场景"这一行的潜台词:Expo 不是"玩具",社区脚手架也不是"正统"。两者对应的是不同阶段与不同需求。很多产品上线初期用 Expo 快速验证,业务稳定后才考虑弹出或重建为社区工程。用"成长路径"而非"二选一"的眼光看这两条路线,心态会轻松很多。
"Metro 无法连接"。Metro 是 RN 的 JS 打包器。跑项目前先在项目目录启动它,或在 VS Code 集成终端里保持打包进程运行。端口被占用也会导致此报错,换端口即可。
"无法连接到开发服务器"。模拟器与电脑的开发服务器失联。检查 Metro 是否在运行、网络是否通畅,重启模拟器与打包器通常能解决。
"SDK location not found"。项目找不到 Android SDK。配置 ANDROID_HOME 环境变量,或在项目的 local.properties 文件里写入 SDK 路径。
"Gradle 下载依赖失败"。网络原因。配置 Gradle 与 Maven 的国内镜像,或重试。
⚠️ 常见坑:改了代码但模拟器没变化。多半是 Metro 缓存或热刷新连接断了。清缓存重启打包器,或检查是否误用了"仅构建不加载"的命令。
💡 关键直觉:RN 项目"跑不起来"时,先问一句"Metro 在不在"。这条命令几乎能定位一半以上的启动类问题。
项目跑起来、看到默认界面后,第一件事是改 App.js 里的内容,保存,观察热刷新生效。这会建立"我改代码、界面立刻变"的正反馈。然后再翻一翻项目结构,把 2.3 节那张图与实际目录对上号。这样你对 React Native 的工程就有了体感,而不仅仅是概念。
问:Expo 项目以后能转成社区脚手架吗? 可以,通过"弹出"操作。但弹出是不可逆的(托管模式回不去),且弹出后要自己维护原生工程。建议只有确认需要自定义原生能力时才弹出,别图新鲜。
问:为什么我的首次构建特别慢? 首次构建要下载 Gradle 与 Maven 依赖、编译原生代码,慢是正常的,几分钟到十几分钟都可能。后续构建会用缓存,明显加快。如果反复失败,多半是网络问题,配好镜像再试。
问:改了 App.js 但界面没变化? 先确认 Metro 是否在运行、热刷新是否开启。常见原因是打包进程断开或缓存陈旧,重启 Metro 并清缓存。这条占了这类问题的大头。
问:社区脚手架是不是比 Expo 更"正统"? 不存在正统一说。两者都官方支持,是同一框架的两种工作流。选型看需求:追求开发体验与速度选 Expo,需要原生深度定制选社区脚手架。官方文档对两种方式都有完整支持,没有高低之分。
React Native 项目里加第三方库不是简单地执行安装命令,还涉及"原生依赖链接"。0.60 版本之前需要手动链接(react-native link),之后新架构支持自动链接,多数库开箱即用。但仍有少数库要求额外配置(修改原生工程或添加配置项),这类库的文档会明确写出"额外步骤"。判断依据很简单:装完库后如果运行报"模块不存在"或原生编译错误,多半是链接或配置没做完。装库前扫一眼它的安装说明,能省下不少排查时间。这也是为什么"先读文档再装库"值得成为习惯。
第一个 React Native 应用跑起来了,接下来看 Flutter 侧的同款流程——创建项目、认识结构、跑起第一个应用。