Repack app

编辑页面

使用更新后的 JavaScript bundle 重新打包现有的 APK、IPA 或 .app,而无需进行完整的原生重建。


For the complete documentation index, see llms.txt. Use this file to discover all available pages.

@expo/repack-app 是一个 CLI 工具,可在不执行完整原生构建的情况下,重新打包现有的 Android APK、iOS IPA 或 iOS .app bundle。它会使用新的 JavaScript(JS)bundle、资源以及应用元数据(例如应用名称、版本以及包名或 bundle 标识符)来更新现有产物。由于不涉及原生编译,repack 通常比完整的原生构建快得多。

要了解 fingerprint 和 repack 如何协同工作以加速 CI,请参阅博客文章 使用 Fingerprint 和 Repack 在 EAS Workflows 中加速持续集成

Prerequisites

2 requirements

1.

现有的构建产物

由你的 Expo 项目生成的构建产物:Android 的 APK,或 iOS 的 IPA 或 .app bundle。

2.

签名凭据(可选)

如果重新打包后的产物需要能够安装到设备上,则这是必需的。更多信息请参阅 签名

何时使用 repack

repack 假定源二进制的原生部分自构建后没有变化。如果你添加了原生依赖、修改了 config plugin,或者升级了 Expo SDK,那么重新打包后的产物中的 JS 会期望存在那些并不存在的原生 API,并且很可能在运行时崩溃。使用 fingerprint 将源二进制的原生身份与当前项目进行比较。如果指纹匹配,那么 repack 就是安全的。如果不同,则应改为进行完整的原生构建。

repack 不是 EAS Update 的替代品。EAS Update 会向已经安装的应用推送新的 JS bundle,用户会在下次启动时看到更新。repack 生成的是一个新的、可安装的产物。一个实用的经验法则是:将 repack 用于内部测试(QA 设备、测试人员、CI 冒烟测试),并使用 EAS Update 将 JS 变更交付给生产用户。

使用场景

  • QA 周期:向测试人员分发一个基础构建,然后在每次迭代中使用 JS 修复进行 repack,而无需等待原生重新构建。
  • CI 优化:每个 fingerprint 只构建一次原生产物,然后在后续每个 PR 上 repack JS bundle,将等待时间从几分钟缩短到几秒钟。
  • 分支测试:将多个 JS 分支与同一个原生二进制进行测试,以隔离仅 JavaScript 的变更。

用法

独立 CLI

你需要从项目根目录运行下面针对 Android 和 iOS 平台指定的命令。至少需要提供 --platform--source-app。该工具在内部运行 npx expo export:embed 来生成一个新的 JS bundle,将其替换进源二进制,并写出输出产物。

输出格式始终与 --source-app 输入保持一致。输入 APK 会输出 APK,输入 IPA 会输出 IPA,而 .app bundle 会输出 .app bundle。

Terminal
npx @expo/repack-app --platform android --source-app MyApp.apk

使用 IPA:

Terminal
npx @expo/repack-app --platform ios --source-app MyApp.ipa

使用 .app bundle(对于模拟器构建,iOS 设备产物始终是 IPA):

Terminal
npx @expo/repack-app --platform ios --source-app MyApp.app

EAS Workflows

EAS Workflows 提供了一个预打包的 repack 作业类型,可自动处理签名和构建管理。有关完整语法、参数和示例,请参阅 EAS Workflows 预打包作业

签名

要生成可安装到物理设备上的产物,请在 --platform--source-app 之外再提供签名凭据。没有这些凭据时,Android APK 会以未签名形式输出,而 iOS IPA 无法安装到设备上。用于模拟器的 iOS .app bundle 不需要签名,可以跳过此步骤。

如果你本地还没有签名凭据,请参阅 应用凭据,了解如何获取 keystore(Android)或签名身份与 provisioning profile(iOS)。

Terminal
npx @expo/repack-app --platform android --source-app MyApp.apk --ks keystore.jks --ks-key-alias my-alias

有关 keystore 密码标志和其他设置,请参阅 Android 特定选项

传递签名身份和 provisioning profile:

注意:iOS repacking 仅支持 ad-hoc 和 development 签名。

Terminal
npx @expo/repack-app --platform ios --source-app MyApp.ipa --signing-identity "Apple Distribution: ..." --provisioning-profile /path/to/profile.mobileprovision

有关完整的签名标志列表,请参阅 iOS 特定选项

--js-bundle-only 模式

默认情况下,repack 会更新 JS bundle、资源以及应用元数据(应用名称、版本、bundle 标识符和 expo-updates manifest)。当你有意只想更新 JS bundle,并保持所有原生配置不变时,请传入 --js-bundle-only

Terminal
npx @expo/repack-app --platform android --source-app MyApp.apk --js-bundle-only

限制

不建议将 repack 用于面向生产的 Google Play Store 或 Apple App Store 提交。生产构建应通过完整的构建流程,以获得正确的符号化和签名。

CLI 参考

Usage: @expo/repack-app [options] [project-root]

参数

参数描述
[project-root]项目根目录的路径。默认为当前工作目录。

选项

选项描述
-p, --platform <platform>必需。 要为其重新打包应用的平台(androidios)。
--source-app <path>必需。 源应用的路径(Android 的 APK,或 iOS 的 IPA 或 .app)。输出格式与输入保持一致。
-o, --output <path>输出产物的路径。默认为项目根目录中的 repacked.apkrepacked.iparepacked.app,并与源格式匹配。
-w, --working-directory <path>临时文件的工作目录路径。
--skip-working-dir-cleanup在 repack 完成后跳过清理工作目录。适用于调试。
-v, --verbose启用详细日志。
--js-bundle-only仅更新 JS bundle,跳过原生配置更新(例如应用名称、版本和其他元数据)。
--embed-bundle-assets强制运行 npx expo export:embed 来生成 JS bundle 和资源,即使在通常从开发服务器加载 bundle 的调试构建中也是如此。
--bundle-assets-sourcemap-output <path>在指定路径生成 source map。需要 --embed-bundle-assets

Android 特定选项

选项描述
--ks <path>keystore 文件的路径。
--ks-pass <password>keystore 密码。默认为 pass:android。支持的格式:pass:<password>env:<name>file:<file>
--ks-key-alias <alias>keystore 密钥别名。
--ks-key-pass <password>keystore 密钥密码。支持的格式:pass:<password>env:<name>file:<file>
--android-build-tools-dir <path>Android SDK build-tools 目录的路径。

iOS 特定选项

选项描述
--signing-identity <identity>代码签名身份。
--provisioning-profile <path>provisioning profile 的路径。或者,也可以为多目标应用提供一个 JSON 编码的值(例如,在打包 app extension 时)。