Repack app

编辑页面

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


For the complete documentation index, see llms.txt. Use this 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 中加速持续集成

前提条件

  • 一个由你的 Expo 项目生成的现有构建产物:Android 的 APK,或 iOS 的 IPA 或 .app bundle。
  • (可选)如果重新打包后的产物需要能够安装到设备上,则需要签名凭据。更多信息请参阅 签名

何时使用 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 时)。