运行时版本和更新

了解不同的运行时版本策略以及它们如何适合你的项目。


运行时版本是一种属性,用于保证构建的本地代码与更新之间的兼容性。当一个项目被制作成构建时,该构建将包含一些无法通过更新更改的本地代码。因此,更新必须与构建的本地代码兼容,才能在该构建上运行。

🌐 Runtime versions are a property that guarantees compatibility between a build's native code and an update. When a project is made into a build, the build will contain some native code that cannot be changed with an update. Therefore, an update must be compatible with a build's native code to run on the build.

为了说明构建和更新如何交互,请看下图:

🌐 To illustrate how builds and updates interact, take a look at the following diagram:

构建可以被看作是两层结构:一层是内置于应用二进制文件的本地层,另一层是可以与其他兼容更新互换的更新层。这种分离使我们能够向构建推送错误修复,只要包含错误修复的更新可以在构建中的本地层上运行即可。"runtimeVersion" 属性使我们能够保证更新与特定构建的本地代码兼容。

🌐 Builds can be thought of as two layers: a native layer that's built into the app's binary, and an update layer, that is swappable with other compatible updates. This separation allows us to ship bug fixes to builds as long as the update with the bug fix can run on the native layer inside the build. The "runtimeVersion" property allows us to guarantee that an update is compatible with a specific build's native code.

由于更新必须与构建的本地代码兼容,所以每次本地代码更新时,我们都需要在发布更新之前创建一个新的构建。有些开发者只在升级到新的 Expo SDK 时更新本地代码,而有些开发者可能会在构建之间或其他时间间隔升级本地代码。以下是不同情况和配置的说明,可能适合你的项目。

🌐 Since updates must be compatible with a build's native code, any time native code is updated, we're required to make a new build before publishing an update. Some developers only update native code when upgrading to a new Expo SDK, while others may upgrade native code between builds or at other intervals. Below is an explanation of different situations and configurations that may suit your project.

设置 "runtimeVersion"

🌐 Setting "runtimeVersion"

为了在构建和更新之间更容易管理 "runtimeVersion" 属性,我们创建了从项目中已有的其他信息派生运行时版本的策略。如果这些策略与项目的开发流程不符,也可以选择手动设置 "runtimeVersion"

🌐 To make managing the "runtimeVersion" property easier between builds and updates, we've created policies that derive the runtime version from another piece of information already present in your project. If these policies do not match the development flow of a project, there's also an option to set the "runtimeVersion" manually.

服务器组件

🌐 Runtime version policies

可用的策略已记录在 expo-updates 库文档 中。

🌐 The available policies are documented in the expo-updates library documentation.

自定义运行时版本

🌐 Custom runtime version

你也可以设置符合运行时版本格式要求的自定义运行时版本:

🌐 You can also set a custom runtime version that meets the runtime version formatting requirements:

{ "expo": { "runtimeVersion": "1.0.0" } }

此选项适用于希望手动管理运行时版本的开发者,独立于项目应用配置中存在的其他版本号。它让开发者完全控制哪些更新与哪些构建兼容。

🌐 This option is good for developers who want to manage the runtime version manually, separately from any other version numbers present in a project's app config. It gives the developer complete control over which updates are compatible with which builds.

平台特定运行时版本

🌐 Platform-specific runtime version

你还可以为每个平台设置运行时版本,例如

🌐 You can also set runtime version per-platform, for example

{ "expo": { "android": { "runtimeVersion": "1.0.0" } } }

或者:

🌐 Or:

{ "expo": { "android": { "runtimeVersion": { "policy": "appVersion" } } } }

当同时设置顶层运行时和特定于平台的运行时时,特定于平台的运行时优先。

🌐 When both a top level runtime and a platform specific runtime are set, the platform specific one takes precedence.

避免不兼容的更新

🌐 Avoiding incompatible updates

发布更新时可能出现的主要问题是,更新可能依赖于构建时不支持的本地代码。例如,假设我们做了一个运行时版本为 "1.0.0" 的构建。然后,我们将该构建提交到应用商店并向公众发布。

🌐 The main issue that can arise when publishing updates is that the update could rely on native code that the build it's running on does not support. For instance, imagine we made a build with a runtime version of "1.0.0". Then, we submitted that build to the app stores and released it to the public.

后来,想象一下,我们开发了一个依赖于新安装的本地库(比如 expo-camera 库)的更新,但我们没有更新 "runtimeVersion" 属性,因此它仍然是 "1.0.0"。如果我们发布了一个更新,具有 "1.0.0""runtimeVersion" 构建会认为具有相同运行时版本的传入更新是兼容的,并会尝试加载该更新。由于该更新会调用构建中不存在的代码,expo-updates 可能会检测到错误并尝试回滚到之前可用的更新(了解有关错误恢复行为的更多信息)。

🌐 Later on, imagine that we developed an update that relied on a newly installed native library, like the expo-camera library, and we did not update the "runtimeVersion" property, so that it is still "1.0.0". If we published an update, the builds with the "runtimeVersion" of "1.0.0" would think the incoming update with the same runtime version was compatible and it would attempt to load the update. Since the update would make calls to code that does not exist inside the build, expo-updates may detect an error and attempt to roll back to the previously working update (learn more about error recovery behavior).

以下是一些避免部署与构建原生代码不兼容的更新的策略。

🌐 The following are some strategies to avoid deploying updates that are incompatible with a build's native code.

使用运行时版本策略,在原生代码更新时自动更新运行时版本

🌐 Use a runtime version policy that automatically updates the runtime version when native code is updated

"appVersion" 策略会在应用版本增加时递增运行时版本,但如果在更改本地运行时时忘记增加应用版本,就会导致运行时版本不匹配。如果你希望将不兼容更新的可能性降到极低,但代价是需要更频繁地创建构建,那么你可以使用 "fingerprint" 策略。该策略会在任何可能影响本地运行时的更改发生时递增运行时版本(了解有关指纹识别的更多信息)。

🌐 The "appVersion" policy will increment the runtime version whenever the app version is incremented, but if you forget to bump the app version when changing the native runtime, then you'll have a runtime version mismatch. If you want to make incompatible updates extremely unlikely, at the cost of making it necessary to create builds more often, then you can use the "fingerprint" policy. This will increment the runtime version whenever anything that may impact the native runtime changes (learn more about fingerprinting).

手动增加运行时版本

🌐 Manually increment the runtime version

每当安装或更新原生代码时,请在项目的应用配置手动递增 "runtimeVersion" 属性

🌐 Whenever installing or updating native code, manually increment the "runtimeVersion" property in the project's app config.

逐步推出更新

🌐 Roll out the update gradually

如果你不确定新更新的影响,可以先将其推送给一小部分用户。使用 rollouts 将更新发布给小部分用户,并在 EAS 仪表板上监控更新的错误率。如果你发现错误率很高,则取消推送。如果你已经完全推送了更新,则 回滚 更新。

🌐 If you're not sure about the impact of a new update, you can roll it out to a small group of users first. Use rollouts to publish the update to a small percentage of users and monitor the error rate for the update on the EAS dashboard. If you are noticing high error rates, then cancel the rollout. If you already rolled it out fully, then roll it back.

手动与较小用户组验证更新

🌐 Manually verify updates with a smaller group of users

当你部署到生产环境时,创建一个预览构建,该构建使用相同的运行时但指向不同的渠道。在将更新推广到生产环境之前,在这些构建上测试你的更新(在 部署指南 中了解更多)。或者,你可以选择让应用的某些用户接收更新,通过在运行时覆盖更新参数来实现(了解更多)。

🌐 When you deploy to production, create a preview build that uses the same runtime but points to a different channel. Test your updates on those builds before promoting them to production (learn more about this in the deployment guide). Alternatively, you can opt-in certain users of your app to receive the update by overriding update parameters at runtime (learn more).