Hello world!
Contents
新建项目
Expo官方网站给出两条路:
- 1. 用expo.new自动设置
- 2. 快速开始文档
第一种方式,expo.new
(expo的新花样,链接)会导引你进入一个Expo精心设计的网站,通过你的github账号联动,选择你要创建的项目类型,在网页界面中一步步指引你以EAS工具建立自己的项目,它在你完成 npx eas-cli@latest init:onboarding
命令后自动建立与你GitHub repo的连接。
没错,这是一个云服务,想法很酷,也比较新,但不知现在有多少程序员喜欢用这种方式进入学习和开发呢?本书写作的时候,作者还未发现有人强烈推荐,本人也没有尝试过,还是静观其变吧。我们先走第二条路。
[!NOTE] 接下来的操作过程记录,都是基于作者自己的开发环境。 如果我们的开发环境相似,那真是太好了! 如果遇到因环境差别产生的障碍,希望你通过摸索和网上询问,掌握相应的变通技巧!👍
运行下面这行命令,可用create-expo-app工具建立一个最新版本的Expo App项目。
npx create-expo-app@latest
这句命令默认引入了一个模版(template),包括用Expo Router库建立的多屏幕架构。当然,我们可以选择不同的模版,只要在命令中加入--template
参数即可,比如接下来的例子我们会用blank
模版,建立一个最小库依赖的不包括导航配置的项目。
npx create-expo-app@latest --template blank
安装过程中,会有一个问题:What is your app name?
我们给本课程的项目取名叫expo-lesson-blank,之后再无交互。
很快安装就结束了,毕竟是个很“空”的项目。
运行程序
安装命令的结尾处贴心地把运行操作打印出来,让我们赶快run一下,这其实也是对我们前期各种准备工作和安装环境是否正常的检查机会。
[!NOTE] 如果下面的过程不顺利,请移步前面章节检查自己的环境配置情况。
我们进入刚才建立的项目目录:cd expo-lesson-blank
;
执行npm run ios
(安卓也行,根据你的偏好来,但本书不讳言各方面内容比较偏向iOS开发);
很快我们的iOS模拟器(Simulator)就自己启动了,并且用Expo Go打开了我们第一个app的界面。如果你是第一次运行,可能在命令行中会提示一下要在模拟器安装Expo Go这个应用,回答Yes就可以。
[!TIP] Expo Go的下载地址:Google Play(Android), App Store(iOS),请在自己的手机上装一下,后面的课程会用到。
我们在启动过程的提示中可以看到,刚才实际上是直接调用了expo cli工具,执行了expo start --ios
这条命令,未来的大多数时间,我们都要习惯以expo命令来启动自己写的app了。
我们退出现在的执行命令(Ctrl + C),然后再执行expo。 oops,报错了!
原因是我们从头到尾都没有安装过expo cli,当然没法直接调用它。
现在我们有两个选择,第一当然是安装expo cli,但个人更倾向于永远不去安装它,我们用万能的npx搞定一切,执行npx expo
即可,这样带来的好处包括但不限于不用再担心包管理和新版本升级等烦心事。(对npx没有印象的同学,请移步[[前面章节]]。)
expo命令跳出的这些内容包含哪些重要信息呢?我们来解读一下。
[!NOTE] 当然你也可以跳过这段以后再来看,现在只要知道按i打开iOS模拟器,按b去安卓运行就可以了。
› Metro waiting on exp://192.168.1.2:8081
› Scan the QR code above with Expo Go (Android) or the Camera app (iOS)
› Using Expo Go
› Press s │ switch to development build
› Press a │ open Android
› Press i │ open iOS simulator
› Press w │ open web
› Press j │ open debugger
› Press r │ reload app
› Press m │ toggle menu
› Press o │ open project code in your editor
› Press ? │ show all commands
从上到下逐句解读:
Metro waiting on exp://192.168.1.2:8081
: 说明expo启动了一个叫Metro的服务,它在ip地址192.168.1.2(我家wifi路由器给开发电脑分配的地址)的8081端口等待前端(模拟器或真机)的访问,如果你同时在这台开发主机启动了其他Metro服务,它们就会开启其他端口,以8082,8083的顺序建立下去。Scan the QR code above with Expo Go (Android) or the Camera app (iOS)
: 可以用你的手机扫描装置扫描上面的二维码访问Metro服务,当然现在你要安装Expo Go这个应用才行,而且你的手机要和开发主机在一个局域网段内并且互相可访问。国内的同学别看到二维码就想起微信,iPhone的话用手机操作系统自带的那个相机工具就可以,安卓的话Expo Go里的扫码工具更好。- 这两句告诉我们expo cli现在采用Expo Go模式,而且它还可以支持
development build
模式,你按一下s就可以了。
› Using Expo Go
› Press s │ switch to development build
当然现在你按下 s 就会得到一个报错,告诉你还没有生成开发包呢,赶快再按s切回来。
- 剩下的内容就很直白了:
› Press a │ open Android
› Press i │ open iOS simulator
› Press w │ open web
› Press j │ open debugger
› Press r │ reload app
› Press m │ toggle menu
› Press o │ open project code in your editor
a 打开安卓模拟器;
i 打开iOS模拟器;
w web页面(没错expo还支持web开发,似乎想和next.js硬钢,但我们的课程不会再提。);
j 打开debugger调试器,不建议;
r 重启app,其实和按下a, i, 或者在前端调出菜单reload的效果一样;
m 切换菜单,不常用;
- 最后一行
Press ? │ show all commands
是说随时按下问号你都可以回到这里,相当于调出帮助信息。
[!NOTE] 值得注意的是,这些快捷键在整个命令期间,也就是app运行调试期间都是生效的。虽然很快终端面板就会被各种log日志信息刷屏了,但我们依然可以随时按下这些单个字母快捷键启动相关功能。
打开项目
为了了解这个最新项目的结构,我们可以执行ls或者用之前安装好的vscode直观查看。
假设我们还在终端程序里并位于项目根目录下,执行code .
,没错这样就可以用vscode打开项目了。
我们发现,这个blank的模版果然很空、很纯粹,呈现了一个expo项目的基础核心内容。
所有的代码都在这个App.js文件中(没错,它甚至没用到Type Script)。
剩下的文件,虽然做过前端的同学都不陌生,但复习一遍对巩固知识是有好处的:
babel.config.js
是一个JavaScript配置文件,用于告诉 Babel 编译器如何处理代码。简单来说,它的作用包括:
选择预设:定义要使用的预设,比如转换ES6+代码到旧版浏览器兼容的代码。
添加插件:添加额外的插件来支持特定的语言特性。
环境配置:根据不同的运行环境(如开发或生产环境)调整编译选项。
忽略文件:指定 Babel 忽略某些文件或文件夹,不进行转换。
源码映射:生成源码映射,方便调试。
它使得你的代码能够兼容更多环境,同时保持代码的现代性和简洁性。
package.json
一个非常重要的文件,它在 Node.js 项目中扮演着核心角色。以下是它的一些基本要点:
项目信息:包含项目的名称、版本、描述、作者、许可证等元数据。
依赖管理:列出项目所需的所有依赖包和它们各自的版本号,确保项目可以正确安装和运行。
脚本:定义可以执行的脚本命令,比如 npm start 或 npm test,方便自动化任务。
配置:包含项目的配置选项,比如 Babel 编译器的配置或测试工具的配置。
入口点:指定项目的主文件或模块,通常是 main 字段。
版本范围:使用语义化版本控制(SemVer)来管理依赖的版本,确保兼容性。
package.json
文件通常位于项目的根目录,是项目依赖和配置的中心。通过 npm install
命令,可以基于这个文件自动安装所有依赖。
app.json
React Native 和 Expo 都使用 app.json
文件来配置应用,但它们的配置重点有所不同:
React Native:
- 主要配置应用基本信息,如名称、版本、描述。
- 可以指定应用的入口文件和资产。
Expo:
- 除了基本配置,还包括 Expo 特有的配置,如预览选项和平台特定功能。
- 支持通过 Expo 平台进行 OTA 更新。
简而言之,Expo 的 app.json
提供了更多与 Expo 平台相关的配置选项,使得开发和发布流程更加简化。而 React Native 的 app.json
更专注于应用本身的基本配置。
assets目录
放项目共享的静态文件,如图标,splash画面等;
.expo文件夹
我们全文翻译一下它的README文档:
- 为什么我的项目中有一个名为 ".expo" 的文件夹?
当使用 "expo start" 命令启动 Expo 项目时,会创建 ".expo"文件夹。- 这些文件包含什么内容?
- "devices.json":包含最近打开此项目的一些设备信息。这用于填充开发构建中的 "Development sessions" 列表。
- "settings.json":包含用于提供应用程序清单的服务器配置。
- 我应该提交 ".expo" 文件夹吗? 不,你不应该共享 ".expo" 文件夹。它不包含对项目上其他开发者有用的任何信息,它是特定于你的机器的。 在项目创建时,".expo" 文件夹已经被添加到你的 ".gitignore" 文件中。
[!NOTE] 总之,别动它。
node_modules
文件夹
是 Node.js 项目中用来存放所有安装的第三方库和模块的地方。它的主要作用包括:
存储依赖:存放项目所需的所有外部库。
自动解析:Node.js 通过这个文件夹来查找和加载所需的模块。
避免冲突:确保不同项目可以使用不同版本的库,互不干扰。
提高效率:通常不提交到版本控制,通过 npm install
重新生成,避免重复下载。
.gitignore
文件
用于列出 Git 应该忽略不跟踪的文件和目录。它的主要作用是:
排除无关文件:防止编译文件、日志、临时文件等被加入版本控制。
保持仓库整洁:避免仓库因包含不必要的文件而变得杂乱。
保护隐私:防止敏感信息被提交。
它通常位于项目根目录,可以通过编辑或使用模板来创建。简单来说,.gitignore
帮助开发者维护一个干净、高效的 Git 仓库。
[!IMPORTANT] 强烈建议你的项目用GitHub来进行版本管理。
基本文件分析
package.json
首先看看基本依赖:
// 2024年6月12日创建的@latest的blank expo项目
"dependencies": {
"expo": "~51.0.13",
"expo-status-bar": "~1.12.1",
"react": "18.2.0",
"react-native": "0.74.2"
},
"devDependencies": {
"@babel/core": "^7.20.0"
},
这里可以看到expo, react, react-native三个核心组件的版本情况,还加入了一个expo-status-bar组件以实现状态栏的正常显示。
在 package.json 文件中,devDependencies(开发依赖)部分用于列出只在开发过程中需要的包,而不是在生产环境中运行时需要的包。这里的极简模版只包含一个"@babel/core"
,是 Babel 编译器的核心包,用于将现代 JavaScript 代码转换为向后兼容的代码,表示Expo项目开发依赖 Babel 编译器的核心功能。
[!NOTE] 大部分情况下,我们不会去手动修改以上这些内容,而是通过组件安装命令等方式进行新增、删除和更新依赖。
scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web"
}
在 Expo 项目的 package.json
文件中,"scripts"
字段定义了可以通过 npm
或 yarn
运行的脚本命令。以下是对您提供的配置的解释:
-
"start": "expo start"
:这个命令用于启动 Expo 项目。当你运行npm start
或yarn start
时,Expo 会启动一个开发服务器,并打开 Expo 客户端应用程序,你可以在其中预览你的 React Native 应用。 -
"android": "expo start --android"
:这个命令用于直接启动 Expo 项目在 Android 设备或模拟器上运行。如果你连接了 Android 设备,或者配置了 Android 模拟器,运行npm run android
或yarn android
将会在该设备上启动应用。 -
"ios": "expo start --ios"
:这个命令用于直接启动 Expo 项目在 iOS 设备或模拟器上运行。如果你有访问 iOS 设备或者模拟器,运行npm run ios
或yarn ios
将会在 iOS 设备上启动应用。 -
"web": "expo start --web"
:这个命令用于启动 Expo 项目在 Web 浏览器上运行。运行npm run web
或yarn web
将会打开一个新标签页,你可以在其中查看你的应用的 Web 版本。
![NOTE] 根据个人经验和大多数文档,我们一般直接用expo命令来启动服务或运行项目,比如
expo start
,expo run
等。
app.json
这个blank
模版配置的内容,和真实世界项目(特别是EAS管理的项目)比确实够简单,但也算五脏俱全,有一定代表性。
{
"expo": {
"name": "expo-lesson-blank",
"slug": "expo-lesson-blank",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/icon.png",
"userInterfaceStyle": "light",
"splash": {
"image": "./assets/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/favicon.png"
}
}
}
以下是对配置项的逐项解读:
-
"expo"
:这是 Expo 配置的根对象。 -
"name"
:应用的名称,通常在应用商店和项目中显示。 -
"slug"
:应用的 URL 友好名称,用于 Expo 服务的链接。 -
"version"
:应用的版本号,遵循语义化版本控制。
版本号其实不是个简单话题。 这个配置项代表你的应用版本号。除了这个字段外,您还会使用
ios.buildNumber
和android.versionCode
—— 您可以在此处阅读更多关于如何为您的应用版本命名的信息。在 iOS 上,这对应于CFBundleShortVersionString
,在 Android 上,这对应于versionName
。所需的格式可以在此处找到。 裸机工作流情况下(传统React Native),要更改您的应用版本号,请在 Xcode 中编辑 'Version' 字段,以及在android/app/build.gradle
中编辑versionName
字符串。
"orientation"
:应用支持的屏幕方向,这里设置为"portrait"
表示仅支持竖屏。
将您的应用锁定为特定的方向,可以是竖屏或横屏。默认情况下不锁定。有效值:default(默认)、portrait(竖屏)、landscape(横屏)。
-
"icon"
:应用的图标文件路径,相对于app.json
文件的路径。 -
"userInterfaceStyle"
:应用的主题风格,这里设置为"light"
表示浅色主题。
配置用于强制应用始终使用浅色或深色用户界面外观,例如“深色模式”,或者让它自动适应系统偏好设置。如果未提供,将默认为浅色。在 Android 上工作需要在项目中安装
expo-system-ui
。
-
"splash"
:启动画面的配置对象,包含以下属性:"image"
:启动画面的图片文件路径。"resizeMode"
:图片的缩放模式,这里使用"contain"
表示图片应保持其宽高比并填充屏幕。"backgroundColor"
:启动画面的背景颜色。
-
"ios"
:iOS 平台特定的配置对象,这里设置"supportsTablet"
为true
表示应用支持在 iPad 上运行。 -
"android"
:Android 平台特定的配置对象,这里定义了"adaptiveIcon"
:"foregroundImage"
:自适应图标的前景图片文件路径。"backgroundColor"
:自适应图标的背景颜色。
-
"web"
:Web 平台特定的配置对象,这里设置"favicon"
为应用在 Web 上的图标文件路径。
简而言之,这个 app.json
配置文件定义了 Expo 应用的基本信息、图标、启动画面、屏幕方向、主题风格以及一些特定于平台的配置,如 iOS 的平板支持和 Android 的自适应图标。这些配置帮助确保应用在不同平台上的一致性和用户体验。
[!NOTE] 再配合Expo打造的EAS工具和服务,统一管理多平台应用的过程就更加舒适了。
babel.config.js
目前只有一段值得注意的配置:
presets: ['babel-preset-expo']
presets 数组定义了一组预设(preset),这些预设包含了 Babel 插件和配置的集合。
'babel-preset-expo'
是一个专门为 Expo 项目配置的预设,它包括了转换 JSX、ES6+ 语法以及 Expo 特定功能的插件。
开发调试
接下来我们尝试修改调试一下本项目,也就是开始写代码了。
写点代码
首先在vscode中,确保自己在项目根目录下,运行:
npx expo start
// 或者仅 npx expo 也行
按 i 键,启动mac电脑上之前用xcode配置好的iPhone Simulator, 我常用模拟设备是iPhone 15。
等到应用画面出现后,在vscode中修改App.js,再保存一下修改内容,我们发现模拟器界面立刻有了反应。 太棒了!我们已经具备了所见即所得的开发能力。
接下来,在代码中增加一个按钮:
...
<Text>Hello World!</Text>
<Button title='Press' onPress={() => console.log("---> pressed.")} />
<StatusBar style="auto" />
...
没错我们要通过按下按钮,输出一个终端控制台文本,结果它长这样... vscode的terminal窗口中输出了日志,似乎和想象中不太一样,我希望日志输出到调试面板中,也就是旁边的DEBUG CONSOLE,毕竟TERMINAL输出复杂对象时不算优美易读,而且终端面板也不是专业 搞调试的。
找遍互联网,我们只发现了一个Expo官方的调试工具Expo Tools,你可以在vscode的插件页中搜索并安装它。 然后在你的mac电脑上按下Shift+Command+P,命令面板跳出来,选择第一行“Expo: Debug Expo app on a device or simulator, using Hermes”。 然后切换到Debug console操作一下App界面,可以看到我们的调试日志信息似乎以更优雅/美观的形式显示出来了。 当然,Expo官方为vscode制作这个号称“Tools”的组件,不仅仅提供了一个调试工具而已,它包含很多其他功能,可以查看它的GitHub Repo,其中提到,这个插件会为你带来以下强大支持:
Expo 配置智能建议和文档:Expo Tools 为所有 Expo 配置文件提供智能建议和文档支持。
智能感知示例:提供配置文件的自动完成和文档,如:
eas.json
:EAS 构建、提交、更新配置。store.config.json
:EAS 元数据。app.json
:Expo 清单。expo-module.config.json
:Expo 模块配置。
调试 Expo 应用:内置的 Expo 调试器允许直接在编辑器中调试应用,连接模拟器或手机, 提供应用行为的完整洞察。
- 使用单个命令
Expo: Debug ...
开始调试。 - 通过
.vscode/launch.json
完全配置 Expo 调试器。
原生文件的实时预览:在保存应用清单时,实时预览 npx expo prebuild
生成的原生文件,不影响现有文件。
支持的 Android 文件预览:包括 AndroidManifest.xml
、gradle.properties
、colors.xml
、strings.xml
、styles.xml
等。
支持的 iOS 文件预览:包括 Info.plist
、[name].entitlements
、Expo.plist
、Podfile.properties.json
等。
清单预览:预览应用生成的清单,包括:
prebuild
:运行npx expo prebuild
时的本地应用清单。introspect
:运行npx expo prebuild
时评估的应用清单结果。public
:使用 Expo 更新时的托管清单。
简而言之,Expo Tools 旨在提高开发 Expo 应用的效率和体验。
[!NOTE] 个人感受,这个插件有用但不算惊艳,有时还会抽风...,官方出品是它的最大优势。
试试Android模拟器
即使在前面的命令未关闭,也就是项目服务端未关闭的情况下,我们也可以直接在终端点击a,顺利的话,你之前在Android Studio中配置的模拟器Emulator就可以启动了。
如果是第一次,expo会问你要不要在这个模拟器安装Expo Go?
如果你的电脑很快(CPU是Apple Silicon的),那这个过程会比较顺滑。
[!Tip] 在正式开发时,我们一般不会同时打开多个模拟器,更不用说iOS和Android同步调试,一方面防止电脑被拖慢,一方面好集中精力避免被一堆窗口干扰。 对了你有没有注意Xcode的模拟器叫Simulator,而Android Studio的叫做Emulator。
试试真机
我们现在的项目还是纯粹的Expo Go项目,真机调试很简单,扫码就可以,请参考[[前面的内容]]。