了解如何在本地构建环境中直接使用 EAS Update。
在本分步指南中,你将创建一个新的 Expo 应用,在本地开发环境中运行它,发布更新,并显示应用在重新启动时下载并运行更新。它还详细介绍了 EAS 更新中使用的一些应用配置属性及其功能。
¥In this step-by-step guide, you'll create a new Expo app, run it in your local development environment, publish an update, and show that the app downloads and runs the update when restarted. It also details some of the app config properties used in EAS Update and their functions.
1
¥Install the latest EAS CLI
EAS CLI 是命令行应用,你将使用它从终端与 EAS 服务进行交互。要安装它,请运行命令:
¥EAS CLI is the command-line app that you will use to interact with EAS services from your terminal. To install it, run the command:
-
npm install --global eas-cli
你还可以使用上述命令检查是否有新版本的 EAS CLI 可用。我们鼓励你始终保持最新版本。
¥You can also use the above command to check if a new version of EAS CLI is available. We encourage you to always stay up to date with the latest version.
我们建议使用
npm
而不是yarn
进行全局包安装。你也可以使用npx eas-cli@latest
。请记住,只要文档中需要它,就使用它而不是eas
。¥We recommend using
npm
instead ofyarn
for global package installations. You may alternatively usenpx eas-cli@latest
. Remember to use that instead ofeas
whenever it's called for in the documentation.
2
3
¥Configure your project
要配置你的项目,请按指定顺序运行以下命令:
¥To configure your project, run the following commands in the order they are specified:
# Install the latest `expo-updates` library
-
npx expo install expo-updates
# Initialize the app in EAS
-
eas init
# Initialize your project with EAS Update
-
eas update:configure
在应用配置中,进行更改以使用具有固定值的 runtimeVersion
属性,并添加应用在从 EAS 下载更新时用于指定通道的请求标头。
¥Inside the app config, make changes to use runtimeVersion
property with a fixed value and to add a request header that the app will use to specify a channel when downloading updates from EAS.
"expo": {
%%placeholder-start%%... %%placeholder-end%%
"updates": {
%%placeholder-start%%... %%placeholder-end%%
"requestHeaders": {
"expo-channel-name": "main"
}
%%placeholder-start%%... %%placeholder-end%%
}
"runtimeVersion": "1.0.0",
%%placeholder-start%%... %%placeholder-end%%
}
在 开始使用 指南中,通道名称由 EAS Build 设置,并且对于不同的构建配置文件是不同的,并在服务器上自动同步。由于这是本地构建,因此需要在应用配置中明确设置请求标头,如上所示,然后在服务器上手动创建通道。
¥In the Get started guide, the channel name is set by EAS Build and is different for various build profiles and automatically synchronized on the server. Since this is a local build, it is necessary to set the request header explicitly in the app config, as shown above, and then manually create channel on the server.
# Create the `main` channel on EAS (which points it to the main EAS Update branch by default)
-
eas channel:create main
4
¥Run prebuild
执行 npx expo run:android
或 npx expo run:ios
时,预构建会自动运行。但是,我们希望在本指南中单独调用此步骤。从 SDK 48 及更高版本开始,此步骤将我们所需的请求标头添加到 Android 和 iOS 版本中的 AndroidManifest.xml 和 Expo.plist 中。
¥Prebuild runs automatically when executing npx expo run:android
or npx expo run:ios
. However, we want to call this step out separately in this guide. From SDK 48 and above, this step adds our desired request headers to AndroidManifest.xml and Expo.plist in the Android and iOS builds.
# Run prebuild to install and configure the android and ios directories, and install CocoaPods for iOS.
-
npx expo prebuild
运行上述命令后,检查 android/app/src/main/AndroidManifest.xml 和 iOS/<你的项目名称>/Supporting/Expo.plist 以查看添加的更改。
¥After running the above, inspect android/app/src/main/AndroidManifest.xml and iOS/<your project name>/Supporting/Expo.plist to see the added changes.
%%placeholder-start%%... Existing configuration %%placeholder-end%%
<key>EXUpdatesRequestHeaders</key>
<dict>
<key>expo-channel-name</key>
<string>main</string>
</dict>
%%placeholder-start%%... Existing configuration %%placeholder-end%%
%%placeholder-start%%... Existing configuration %%placeholder-end%%
<meta-data android:name="expo.modules.updates.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY" android:value="{"expo-channel-name":"main"}"/>
%%placeholder-start%%... Existing configuration %%placeholder-end%%
在 SDK 48 及更高版本中,应用配置中的
requestHeaders
属性用于自动将这些行添加到原生文件中。¥In SDK 48 and later, the
requestHeaders
property from the app config is used to automatically add these lines to the native files.
5
¥Build the project
运行以下命令以使应用在 Android 或 iOS 上运行。
¥Run the following commands to get the app running on Android or iOS.
# Android: Build and run the app on a local Android Emulator
-
npx expo run:android --variant release
# iOS: Build and run the app on a local iOS Simulator.
-
npx expo run:ios --configuration Release
我们构建应用的发布版本,而不是调试版本。默认情况下,调试版本期望连接到本地 React Native 打包程序以加载应用包,并且不会连接到 EAS 更新服务。
¥We build the release version of the app, not the debug version. By default, a debug build expects to connect to a local React Native packager to load the application bundle and will not connect to the EAS Update service.
可以创建一个原生调试版本,该版本将连接到 EAS 更新服务并允许调试原生代码。请参阅 使用调试版本测试更新 部分了解所需的更改。
¥It is possible to create a native debug build that will connect to the EAS Update service and allow debugging of native code. See Testing updates with a debug build section for the required changes.
6
对 App.js 进行以下修改,以便应用使用 Updates
API 来显示它是否已下载并运行更新。
¥Make the modifications below to App.js so that the app uses the Updates
API to show if it has downloaded and run an update.
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import * as Updates from 'expo-updates';
export default function App() {
const runTypeMessage = Updates.isEmbeddedLaunch
? 'This app is running from built-in code'
: 'This app is running an update';
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
<Text>{runTypeMessage}</Text>
<StatusBar style="auto" />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
然后再次构建并运行应用:
¥Then build and run the app again:
# Android: Build and run the app on a local Android Emulator
-
npx expo run:android --variant release
# iOS: Build and run the app on a local iOS Simulator.
-
npx expo run:ios --configuration Release
该应用应如下面的屏幕截图所示。
¥The app should appear as in the screenshot below.
7
¥Publish an update
现在我们准备发布包含我们的更改的更新。
¥Now we're ready to publish an update that will include our changes.
根据需要对 App.js 进行其他更改后,使用以下命令发布更新:
¥After optionally making additional changes to App.js, publish an update with the following command:
-
eas update
运行命令会提示如下:
¥Running the command will prompt the following:
用于发布的分支。选择默认分支:main
。这是上面默认链接到 main
通道的分支。
¥For the branch to publish on. Select the default branch: main
. This is the branch that the main
channel was linked to by default above.
用于输入更新消息。选择默认的 Initial commit
消息或输入自定义消息。
¥For entering an update message. Select the default Initial commit
message or type in a custom message.
构建更新并将其上传到 EAS 并且命令完成后,强制关闭并重新打开你的应用最多两次以下载和查看更新。
¥Once the update is built and uploaded to EAS and the command completes, force close and reopen your app up to two times to download and view the update.
该应用现在应该如下图所示:
¥The app should now appear as shown in the screenshot below:
¥Testing updates with a debug build of your app
创建一个调试版本,该版本将从 EAS 加载更新,而不是从 React Native 打包器加载 是可能的。
¥It is possible to create a debug build that will load updates from EAS instead of loading from a React Native packager.
要对上述应用执行此操作,请修改上面的步骤 4,如下所示:
¥To do this for the above app, modify step 4 above as follows:
# Set the environment variable needed for native debug builds
-
export EX_UPDATES_NATIVE_DEBUG=1
# Run prebuild to install and configure the android and ios directories, and install CocoaPods for iOS.
-
npx expo prebuild
# iOS: Modify the application project so that the application JavaScript
# is bundled into the app for both debug and release builds.
-
sed -i '' 's/SKIP_BUNDLING/FORCE_BUNDLING/g;' ios/<project name>.xcodeproj/project.pbxproj
# iOS: Build and run the app on a local iOS Simulator.
-
npx expo run:ios --configuration Debug
# Android: Build and run the app on a local Android Emulator
-
npx expo run:android --variant debug
生成的应用将可以使用 Xcode 或 Android Studio 进行完全调试,但将像发布版本一样使用 EAS 更新服务,并且不会连接到本地打包程序。
¥The resulting app will be fully debuggable with Xcode or Android Studio, but will work with the EAS Update service the same way as a release build, and will not connect to a local packager.