配置更新


本文档于2022年8月归档,不会再有任何更新。请改用EAS Update。了解更多

Expo 提供了多种设置,用于配置你的应用如何接收更新。更新允许你发布应用 JavaScript 和资源的新版本,而无需构建应用的新版本并重新提交到应用商店。(了解更多关于限制的信息)。

🌐 Expo provides various settings to configure how your app receives updates. Updates allow you to publish a new version of your app JavaScript and assets without building a new version of your app and re-submitting it to app stores. (Read more about the limitations).

要创建应用更新,请运行 expo publish。如果你使用发布通道,请使用 --release-channel <channel-name> 选项指定一个。注意,如果你希望更新应用的 SDK 版本,或进行这些更改中的任何一项,你需要使用 eas build 重新构建应用并将二进制文件上传到相应的应用商店(请参阅此处文档)。

🌐 To create an update of your app, run expo publish. If you're using release channels, specify one with --release-channel <channel-name> option. Note that if you wish to update the SDK version of your app, or make any of these changes, you'll need to rebuild your app with eas build and upload the binary file to the appropriate app store (see the docs here).

更新由 app.json 中的 updates 设置控制,该设置处理应用的初始加载;以及 Updates SDK 模块,该模块允许你从 JS 异步获取更新。

🌐 Updates are controlled by the updates settings in app.json, which handle the initial app load, and the Updates SDK module, which allows you to fetch updates asynchronously from your JS.

自动更新

🌐 Automatic updates

如果你的 app.json 中没有包含 updates.fallbackToCacheTimeout 字段,它将默认为 0,并且 expo-updates 会尝试立即使用缓存的包启动你的应用,同时在后台下载一个更新的包以供将来使用。在使用此配置时,从应用商店下载并首次启动应用的用户,将始终看到与二进制构建版本相对应的应用版本。Updates.addListener 提供了一个钩子,让你在新包下载完成时作出响应。你可以利用它来通知用户需要重启应用,也可以通过 Updates.reloadAsync() 编程方式重启应用,例如响应用户提示时。

🌐 If your app.json does not contain an updates.fallbackToCacheTimeout field it will default to 0 and expo-updates will attempt to start your app immediately with a cached bundle while downloading a newer one in the background for future use. When using this configuration, users who download the app from a store and launch it for the first time will always see the version of the app that the binary was built against. Updates.addListener provides a hook to let you respond when the new bundle is finished downloading. You can use this to notify users that they should restart the app, and you can also restart it programmatically with Updates.reloadAsync(), for example, in response to a prompt to the user.

你也可以设置一个非零超时值,在这种情况下,Expo 会尝试在启动应用之前下载新的更新。如果没有可用的网络连接,或者在规定时间内未完成下载,Expo 将回退到加载应用的缓存版本,并在后台继续尝试获取更新(届时它将被保存到缓存中,以便下次启动应用时使用)。我们强烈建议不要为了获取更新而阻塞应用加载,因为这可能会让用户觉得应用无法使用,如果下载更新需要较长时间的话,每次启动都会变慢,因为必须先发出网络请求检查更新,然后才能继续进入应用。

🌐 You can also set a nonzero timeout, in which case Expo will attempt to download a new update before launching the app. If there is no network connection available, or it has not finished downloading in the allotted time, Expo will fall back to loading a cached version of your app, and continue trying to fetch the update in the background (at which point it will be saved into the cache for the next app load). We strongly advise against blocking app loading on fetching an update because it can leave users with the perception that the app is not working if it takes a while to download the update, and every launch will be slower because a network request has to be made to check for an update before proceeding to the app.

在 Expo Go 中,无论你应用配置中的 updates 设置如何,都会始终启动你应用的最新发布包(除非请求超时或网络连接不可用)。

🌐 In Expo Go, the latest published bundle of your app will always be launched (unless the request times out or the network connection is unavailable), regardless of the updates settings in your app config.

手动更新

🌐 Manual updates

在独立应用中,也可以关闭自动更新,而完全在你的 JS 代码中控制更新。如果你希望在获取更新时有一些自定义逻辑(例如,只在 Wi-Fi 下),这是很有用的。

🌐 In standalone apps, it is also possible to turn off automatic updates and to instead control updates entirely within your JS code. This is desirable if you want some custom logic around fetching updates (for example, only over Wi-Fi).

在 app.json 中将 updates.checkAutomatically 设置为 "ON_ERROR_RECOVERY" 将阻止 Expo 在每次启动应用时自动获取最新更新。应用只会加载最近缓存的版本。只有当缓存的包在上一次运行中发生严重 JS 错误时,它才会自动获取更新。

🌐 Setting updates.checkAutomatically to "ON_ERROR_RECOVERY" in app.json will prevent Expo from automatically fetching the latest update every time your app is launched. Only the most recent cached version of your bundle will be loaded. It will only automatically fetch an update if the last run of the cached bundle produced a fatal JS error.

然后你可以使用 expo-updates 模块下载新的更新,并在合适的情况下通知用户重新加载他们的应用。

🌐 You can then use the expo-updates module to download new updates and, if appropriate, notify the user to reload their app.

import * as Updates from 'expo-updates'; try { const update = await Updates.checkForUpdateAsync(); if (update.isAvailable) { await Updates.fetchUpdateAsync(); // ... notify user of update ... await Updates.reloadAsync(); } } catch (e) { // handle or log error }

检查更新会像任何网络请求一样消耗设备的带宽和电池寿命。此外,由 Expo 提供的更新可能会受到速率限制。一个明智的做法是在用户启动或将应用切换到前台时检查更新。避免频繁循环地轮询更新。

🌐 Checking for an update uses a device's bandwidth and battery life like any network call. Additionally, updates served by Expo may be rate limited. A good rule of thumb to check for updates judiciously is to use check when the user launches or foregrounds the app. Avoid polling for updates in a frequent loop.

请注意,checkAutomatically: "ON_ERROR_RECOVERY" 在 Expo Go 中将被忽略,但命令式的 Updates 方法仍将正常工作。

🌐 Note that checkAutomatically: "ON_ERROR_RECOVERY" will be ignored in Expo Go, although the imperative Updates methods will still function normally.

禁用更新

🌐 Disabling updates

可以通过在 app.json 中将 updates.enabled 设置为 false 来完全禁用应用更新。这将忽略所有从 Expo 服务器获取应用包的代码路径。在这种情况下,应用的所有更新都需要通过 iOS App Store 和/或 Google Play Store 进行。

🌐 It is possible to entirely disable updates in an app, by setting updates.enabled to false in app.json. This will ignore all code paths that fetch app bundles from Expo's servers. In this case, all updates to your app will need to be routed through the iOS App Store and/or Google Play Store.

Expo Go 应用中会忽略此设置。

🌐 This setting is ignored in the Expo Go app.