了解如何在同一设备上安装应用的多个变体。
创建 开发、预览和生产版本 时,在同一设备上同时安装这些构建变体是很常见的。这允许进行开发、预览应用的下一个版本以及在设备上运行生产版本,而无需卸载并重新安装应用。
¥When creating development, preview, and production builds, installing these build variants simultaneously on the same device is common. This allows working in development, previewing the next version of the app, and running the production version on a device without needing to uninstall and reinstall the app.
本指南提供了配置多个(开发和生产)变体以在同一设备上安装和使用它们所需的步骤。
¥This guide provides the steps required to configure multiple (development and production) variants to install and use them on the same device.
¥Prerequisites
要在你的设备上安装应用的多个变体,每个变体必须具有唯一的 应用 ID (Android) 或 打包包标识符 (iOS)。
¥To have multiple variants of an app installed on your device, each variant must have a unique Application ID (Android) or Bundle Identifier (iOS).
¥Configure development and production variants
你已经使用 Expo 工具创建了一个项目,现在你想要创建一个开发和生产版本。你的项目的 app.json 可能具有以下配置:
¥You have created a project using Expo tooling, and now you want to create a development and a production build. Your project's app.json may have the following configuration:
{
"expo": {
"name": "MyApp",
"slug": "my-app",
"ios": {
"bundleIdentifier": "com.myapp"
},
"android": {
"package": "com.myapp"
}
}
}
如果你的项目配置了 EAS Build,则 eas.json 也具有类似的配置,如下所示:
¥If your project has EAS Build configured, the eas.json also has a similar configuration as shown below:
{
"build": {
"development": {
"developmentClient": true
},
"production": {}
}
}
¥Convert app.json to app.config.js
要在同一设备上安装应用的多个变体,请将 app.json 重命名为 app.config.js 并导出配置,如下所示:
¥To have multiple variants of the app installed on the same device, rename the app.json to app.config.js and export the configuration as shown below:
export default {
name: 'MyApp',
slug: 'my-app',
ios: {
bundleIdentifier: 'com.myapp',
},
android: {
package: 'com.myapp',
},
};
在 app.config.js 中,添加一个名为 IS_DEV
的环境变量,以根据该变量切换每个变体的 android.package
和 ios.bundleIdentifier
:
¥In app.config.js, add an environment variable called IS_DEV
to switch the android.package
and ios.bundleIdentifier
for each variant based on the variable:
const IS_DEV = process.env.APP_VARIANT === 'development';
export default {
name: IS_DEV ? 'MyApp (Dev)' : 'MyApp',
slug: 'my-app',
ios: {
bundleIdentifier: IS_DEV ? 'com.myapp.dev' : 'com.myapp',
},
android: {
package: IS_DEV ? 'com.myapp.dev' : 'com.myapp',
},
};
在上面的例子中,环境变量 IS_DEV
用于区分开发环境和生产环境。根据其值,为每个变体设置不同的应用 ID 或打包包标识符。
¥In the above example, the environment variable IS_DEV
is used to differentiate between the development and production environment. Based on its value, the different Application IDs or Bundle Identifiers are set for each variant.
注意:如果你使用的任何库要求你向外部服务注册应用标识符才能使用 SDK,例如 Google 地图或 Firebase Cloud Messaging (FCM),则你需要为
android.package
的该 API 进行单独的配置 和ios.bundleIdentifier
。你还可以使用与上述相同的方法交换此配置。¥Note: If you are using any libraries that require you to register your application identifier with an external service to use the SDK, such as Google Maps or Firebase Cloud Messaging (FCM), you'll need to have a separate configuration for that API for the
android.package
andios.bundleIdentifier
. You can also swap this configuration using the same approach as above.
¥Configuration for EAS Build
在 eas.json 中,使用 env
属性设置 APP_VARIANT
环境变量以使用开发配置文件运行构建:
¥In eas.json, set the APP_VARIANT
environment variable to run builds with the development profile by using the env
property:
{
"build": {
"development": {
"developmentClient": true,
"env": {
"APP_VARIANT": "development"
}
},
"production": {}
}
}
现在,当你运行 eas build --profile development
时,在本地和 EAS Build 构建器上评估 app.config.js 时,环境变量 APP_VARIANT
将设置为 development
。
¥Now, when you run eas build --profile development
, the environment variable APP_VARIANT
is set to development
when evaluating app.config.js both locally and on the EAS Build builder.
¥Using the development server
当你启动开发服务器时,你需要运行 APP_VARIANT=development npx expo start
(或者如果你使用 Windows,则运行等效平台)。
¥When you start your development server, you'll need to run APP_VARIANT=development npx expo start
(or the platform equivalent if you use Windows).
一个快捷方式是将以下脚本添加到 package.json 中:
¥A shortcut for this is to add the following script to your package.json:
{
"scripts": {
"dev": "APP_VARIANT=development npx expo start"
}
}
¥Using production variant
当你运行 eas build --profile production
时,未设置 APP_VARIANT
变量环境,并且构建作为生产变体运行。
¥When you run eas build --profile production
the APP_VARIANT
variable environment is not set, and the build runs as the production variant.
注意:如果你使用 EAS 更新来发布应用的 JavaScript 更新,则在运行
eas update
命令时应谨慎为要发布的应用变体设置正确的环境变量。请参阅 EAS Build 环境变量和秘密 了解更多信息。¥Note: If you use EAS Update to publish JavaScript updates of your app, you should be cautious to set the correct environment variables for the app variant that you are publishing for when you run the
eas update
command. See the EAS Build Environment variables and secrets for more information.
¥In bare project
¥Android
在 android/app/build.gradle 中,为要构建的 eas.json 中的每个构建配置文件创建一个单独的风格。
¥In android/app/build.gradle, create a separate flavor for every build profile from eas.json that you want to build.
android {
%%placeholder-start%%... %%placeholder-end%%
flavorDimensions "env"
productFlavors {
production {
dimension "env"
applicationId 'com.myapp'
}
development {
dimension "env"
applicationId 'com.myapp.dev'
}
}
%%placeholder-start%%... %%placeholder-end%%
}
注意:目前,EAS CLI 仅支持
applicationId
字段。如果你在productFlavors
或buildTypes
部分中使用applicationIdSuffix
,则将无法正确检测到该值。¥Note: Currently, EAS CLI supports only the
applicationId
field. If you useapplicationIdSuffix
insideproductFlavors
orbuildTypes
sections then this value will not be detected correctly.
通过在 eas.json 中指定 gradleCommand
,将 Android 风格分配给 EAS 构建配置文件:
¥Assign Android flavors to EAS Build profiles by specifying a gradleCommand
in the eas.json:
{
"build": {
"development": {
"android": {
"gradleCommand": ":app:assembleDevelopmentDebug"
}
},
"production": {
"android": {
"gradleCommand": ":app:bundleProductionRelease"
}
}
}
}
默认情况下,每种风格都可以在调试或发布模式下构建。如果你想将某些风格限制为特定模式,请参阅下面的代码片段,并修改 build.gradle。
¥By default, every flavor can be built in either debug or release mode. If you want to restrict some flavor to a specific mode, see the snippet below, and modify build.gradle.
android {
%%placeholder-start%%... %%placeholder-end%%
variantFilter { variant ->
def validVariants = [
["production", "release"],
["development", "debug"],
]
def buildTypeName = variant.buildType*.name
def flavorName = variant.flavors*.name
def isValid = validVariants.any { flavorName.contains(it[0]) && buildTypeName.contains(it[1]) }
if (!isValid) {
setIgnore(true)
}
}
%%placeholder-start%%... %%placeholder-end%%
}
此时的其余配置并非特定于 EAS,它与任何具有风格的 Android 项目相同。你可能希望将一些常见配置应用于你的项目:
¥The rest of the configuration at this point is not specific to EAS, it's the same as it would be for any Android project with flavors. There are a few common configurations that you might want to apply to your project:
要更改使用开发配置文件构建的应用的名称,请创建 android/app/src/development/res/value/strings.xml 文件:
¥To change the name of the app built with the development profile, create a android/app/src/development/res/value/strings.xml file:
<resources>
<string name="app_name">MyApp - Dev</string>
</resources>
要更改使用开发配置文件构建的应用的图标,请使用适当的资源创建 android/app/src/development/res/mipmap-* 目录(你可以从 android/app/src/main/res 复制它们并替换图标文件)。
¥To change the icon of the app built with the development profile, create android/app/src/development/res/mipmap-* directories with appropriate assets (you can copy them from android/app/src/main/res and replace the icon files).
要为特定风格指定 google-services.json,请将其放入 android/app/src{flavor}google-services.json 文件中。
¥To specify google-services.json for a specific flavor, put it in the android/app/src{flavor}google-services.json file.
要配置 sentry,请将 project.ext.sentryCli = [ flavorAware: true ]
添加到 android/app/build.gradle,并将属性文件命名为 android/sentry-{flavor}-{buildType}.properties(例如,android/sentry-production-release.properties)
¥To configure sentry, add project.ext.sentryCli = [ flavorAware: true ]
to android/app/build.gradle and name your properties file android/sentry-{flavor}-{buildType}.properties (for example, android/sentry-production-release.properties)
¥iOS
为 eas.json 中的每个构建配置文件分配不同的 scheme
:
¥Assign a different scheme
to every build profile in eas.json:
{
"build": {
"development": {
"ios": {
"buildConfiguration": "Debug",
"scheme": "myapp-dev"
}
},
"production": {
"ios": {
"buildConfiguration": "Release",
"scheme": "myapp"
}
}
}
}
Podfile 应该有一个如下定义的目标:
¥Podfile should have a target defined like this:
target 'myapp' do
%%placeholder-start%%... %%placeholder-end%%
end
将其替换为抽象目标,其中可以从旧目标复制通用配置:
¥Replace it with an abstract target, where the common configuration can be copied from the old target:
abstract_target 'common' do
# put common target configuration here
target 'myapp' do
end
target 'myapp-dev' do
end
end
在 Xcode 中打开项目,在导航面板中单击项目名称,右键单击现有目标,然后单击 "复制":
¥Open project in Xcode, click on the project name in the navigation panel, right click on the existing target, and click "Duplicate":
将目标重命名为更有意义的名称,例如 myapp copy
-> myapp-dev
。
¥Rename the target to something more meaningful, for example, myapp copy
-> myapp-dev
.
为新目标配置方案:
¥Configure a scheme for the new target:
转到 Product
-> Scheme
-> Manage schemes
。
¥Go to Product
-> Scheme
-> Manage schemes
.
在列表中找到方案 myapp copy
。
¥Find scheme myapp copy
on the list.
更改方案名称 myapp copy
-> myapp-dev
。
¥Change scheme name myapp copy
-> myapp-dev
.
默认情况下,新方案应标记为共享,但 Xcode 不会创建 .xcscheme
文件。要解决此问题,请取消选中 "共享" 复选框并再次选中它,之后新的 .xcscheme
文件应显示在 ios/myapp.xcodeproj/xcshareddata/xcschemes 目录中。
¥By default, the new scheme should be marked as shared, but Xcode does not create .xcscheme
files. To fix that, uncheck the "Shared" checkbox and check it again, after that new .xcscheme
file should show up in the ios/myapp.xcodeproj/xcshareddata/xcschemes directory.
默认情况下,新创建的目标具有单独的 Info.plist 文件(在上面的示例中,它是 ios/myapp copy-Info.plist)。为了简化你的项目,我们建议对所有目标使用相同的文件:
¥By default, the newly created target has separate Info.plist file (in the above example, it's ios/myapp copy-Info.plist). To simplify your project we recommend using the same file for all targets:
删除./ios/myapp copy-Info.plist。
¥Delete ./ios/myapp copy-Info.plist.
单击新目标。
¥Click on the new target.
转到 Build Settings
选项卡。
¥Go to Build Settings
tab.
找到 Packaging
部分。
¥Find Packaging
section.
更改 Info.plist 值 - myapp 复制-Info.plist -> myapp/Info.plist。
¥Change Info.plist value - myapp copy-Info.plist -> myapp/Info.plist.
改变 Product Bundle Identifier
。
¥Change Product Bundle Identifier
.
要更改显示名称:
¥To change the display name:
打开 Info.plist 并添加键 Bundle display name
和值 $(DISPLAY_NAME)
。
¥Open Info.plist and add key Bundle display name
with value $(DISPLAY_NAME)
.
打开两个目标的 Build Settings
并找到 User-Defined
部分。
¥Open Build Settings
for both targets and find User-Defined
section.
添加密钥 DISPLAY_NAME
以及你要用于该目标的名称。
¥Add key DISPLAY_NAME
with the name you want to use for that target.
要更改应用图标:
¥To change the app icon:
创建一个新的图片集(你可以根据当前图标的现有图片集创建它,通常命名为 AppIcon
)
¥Create a new image set (you can create it from the existing image set for the current icon, it's usually named AppIcon
)
打开你要更改图标的目标的 Build Settings
。
¥Open Build Settings
for the target that you want to change icon.
找到 Asset Catalog Compiler - Options
部分。
¥Find Asset Catalog Compiler - Options
section.
将 Primary App Icon Set Name
更改为新图片集的名称。
¥Change Primary App Icon Set Name
to the name of the new image set.