mcpField
L
local-build

local-build

github.com/code-with-beto开发144240 次安装15 周前更新
代码仓库

关于 local-build

这项技能为 Expo 和 React Native 项目创建本地发布构建脚本,生成 Android APK 和 iOS 模拟器 .app。它从项目配置读取应用标识并调用平台工具链,产物路径固定,适用于本地测试和端到端测试。

主要功能

  1. 01生成 Android 发布 APK 脚本
  2. 02生成 iOS 模拟器 .app 脚本
  3. 03从 Expo 配置读取应用标识
  4. 04在固定路径替换构建产物
  5. 05将构建产物目录加入 .gitignore

适用场景

  1. 01构建 APK 以测试 Android 设备
  2. 02创建用于端到端测试的 iOS 模拟器版本
  3. 03为团队预览准备发布构建产物

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/code-with-beto/skills --skill local-build

安装后在 Claude Code 中输入/local-build确认已加载。

详细介绍

本地构建工作流(APK 和 .app)

概述

生成两个 Shell 脚本,直接使用平台工具链为 Expo / React Native 项目构建发布产物:

  • scripts/build-android.sh → 运行 ./gradlew assembleRelease,并将 APK 复制到 builds/
  • scripts/build-ios.sh → 为 iOS 模拟器运行 xcodebuild,并将 .app 复制到 builds/

每次运行时,两个脚本都会替换之前的产物,因此输出路径始终是可预测的。

存在这些脚本的原因: Expo 项目的调试构建包含 expo-dev-client,启动后显示“Development Servers”选择器,而不是应用界面。对于端到端测试、供队友预览或安装到真实设备,你需要 Release 构建,而这正是这些脚本生成的内容。

步骤 0:确认项目是 React Native / Expo 应用

在进行其他操作之前,确认当前目录是 Expo / React Native 项目:

  1. 检查 package.json 中的 dependencies 是否包含 expo。
  2. 检查是否存在 app.json 或 app.config.ts / app.config.js。

如果这两者都不存在,请停止并告知用户,此技能仅适用于 Expo 项目。

步骤 1:从 Expo 配置中读取应用标识信息

脚本需要三个特定于用户项目的值。不要硬编码 "YourApp",也不要假设应用名称。 请从配置中读取这些值。

要提取的值
值查找位置用途
nameapp.config.ts / app.config.js / app.json → expo.nameiOS scheme 和 .app 文件名
slugexpo.slugAPK 文件名(备用值:小写的 name)
ios.bundleIdentifierexpo.ios.bundleIdentifierxcrun simctl launch 命令
android.packageexpo.android.packageadb shell am start 命令
如何读取各种配置格式
  • app.json — 纯 JSON,直接解析。顶层键通常是 expo。
  • app.config.ts / app.config.js — 导出一个返回配置的函数。读取文件,并从返回的对象中提取字面值。不要尝试执行它。如果某个值是动态计算的,请询问用户要使用什么值。
确认磁盘上存在 iOS scheme

iOS scheme 文件是在 expo prebuild 期间根据 expo.name 生成的。将其写入脚本之前,请先确认它存在:

ls ios/*.xcworkspace 2>/dev/null
ls ios/*.xcodeproj/xcshareddata/xcschemes/*.xcscheme 2>/dev/null

.xcworkspace 名称和 .xcscheme 文件名(不含扩展名)是传给 xcodebuild -workspace 和 -scheme 的值。它们通常与 expo.name 相同,但如果不同,请使用磁盘上的实际值。

如果 ios/ 或 android/ 尚不存在,请运行:

npx expo prebuild

然后再次检查 scheme。

步骤 2:创建 Android 构建脚本

编写 scripts/build-android.sh。将 <SLUG> 替换为步骤 1 中的值。

#!/usr/bin/env bash
set -euo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$HERE/.." && pwd)"
ARTIFACT="$ROOT/android/app/build/outputs/apk/release/app-release.apk"
DEST_DIR="$ROOT/builds"
DEST="$DEST_DIR/<SLUG>.apk"

echo "==> Building Android release APK"
cd "$ROOT/android"
./gradlew assembleRelease

if [ ! -f "$ARTIFACT" ]; then
  echo "Build did not produce $ARTIFACT" >&2
  exit 1
fi

mkdir -p "$DEST_DIR"
rm -f "$DEST"
cp "$ARTIFACT" "$DEST"

echo "Done: $DEST"

注意:

  • 必须使用 assembleRelease。assembleDebug 会启动 expo-dev-client,而不是应用。
  • 如果项目未配置发布签名,Gradle 会回退到调试密钥库;这适合本地测试,但不能用于提交到 Play Store。

步骤 3:创建 iOS 构建脚本

编写 scripts/build-ios.sh。将 <SCHEME> 替换为步骤 1 中的值(它与 -workspace <SCHEME>.xcworkspace 和 -scheme <SCHEME> 使用的字符串相同,输出文件为 <SCHEME>.app)。

#!/usr/bin/env bash
set -euo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
ROOT="$(cd "$HERE/.." && pwd)"
ARTIFACT="$ROOT/ios/build/Build/Products/Release-iphonesimulator/<SCHEME>.app"
DEST_DIR="$ROOT/builds"
DEST="$DEST_DIR/<SCHEME>.app"

echo "==> Building iOS Simulator .app (Release)"
cd "$ROOT/ios"
xcodebuild \
  -workspace <SCHEME>.xcworkspace \
  -scheme <SCHEME> \
  -configuration Release \
  -sdk iphonesimulator \
  -derivedDataPath build \
  CODE_SIGNING_ALLOWED=NO \
  -quiet

if [ ! -d "$ARTIFACT" ]; then
  echo "Build did not produce $ARTIFACT" >&2
  exit 1
fi

mkdir -p "$DEST_DIR"
rm -rf "$DEST"
cp -R "$ARTIFACT" "$DEST"

echo "Done: $DEST"

注意:

  • -sdk iphonesimulator 会生成模拟器用的 .app,无法在实体设备上运行。
  • CODE_SIGNING_ALLOWED=NO 可安全用于模拟器构建,并且无需签名身份。
  • .app 是目录包,而不是文件,因此必须使用 cp -R。

步骤 4:使脚本可执行

chmod +x scripts/build-android.sh scripts/build-ios.sh

步骤 5:将 builds/ 添加到 .gitignore

将以下内容追加到 .gitignore(先检查是否已存在):

# Local build artifacts
builds/

步骤 6:告知用户如何使用

向用户提供以下摘要:

Built two scripts for you:

  ./scripts/build-android.sh   → builds/<slug>.apk
  ./scripts/build-ios.sh       → builds/<scheme>.app

Install and run:

  # Android (connected device or emulator)
  adb install -r builds/<slug>.apk
  adb shell am start -n <android.package>/.MainActivity

  # iOS Simulator
  xcrun simctl boot "iPhone 16" 2>/dev/null; open -a Simulator
  xcrun simctl install booted builds/<scheme>.app
  xcrun simctl launch booted <ios.bundleIdentifier>

生成消息时,将步骤 1 中的实际值代入,以便用户可以直接复制粘贴。

重要说明

  • 使用 Release,而非 Debug。 Debug 构建会启动 expo-dev-client,显示带有“Development Servers”列表的启动器屏幕。若要查看实际 UI,必须使用 Release。
  • 此处的 iOS 构建仅支持模拟器。 设备构建需要配置描述文件和签名身份,不在本技能的范围内。如果用户需要设备构建,请引导他们使用 eas build 或手动进行 Xcode 归档。
  • Android 仅使用调试密钥签名。 这个 APK 可用于本地测试和端到端测试,但不能用于提交到 Play Store。生产环境请配置发布密钥库,或使用 eas build。
  • 配置值因项目而异。 不要硬编码“YourApp”或 Platano 示例中的值。务必从 app.config.ts / app.json 中读取,并对照磁盘上的文件进行验证。

故障排除

“Build did not produce ...”

xcodebuild 或 gradlew 命令已成功运行,但产物不在脚本预期的位置。通常意味着:

  • scheme 或 workspace 名称有误(检查 ios/*.xcworkspace 和 ios/*.xcodeproj/xcshareddata/xcschemes/)
  • 在构建脚本或 Gradle 覆盖配置中设置了自定义的 derivedDataPath 或输出目录
xcodebuild: error: The workspace ... does not exist

运行 npx expo prebuild 以重新生成 ios/。如果已有 ios/ 文件夹,但其中没有 workspace,可能是 CocoaPods 安装失败了——运行 cd ios && pod install。

APK 安装成功,但打开后显示 expo-dev-client 启动器

说明脚本在执行过程中调用了 assembleDebug。请确保第 2 步的脚本调用 assembleRelease。

.app 打开后显示“Development Servers”

iOS 上也是同样的问题——脚本使用 -configuration Debug 而不是 Release 构建。请检查第 3 步的脚本。

xcrun simctl install 提示“incorrect executable format”

用户尝试在 macOS 上直接 open .app。模拟器的 .app 包只能在 xcrun simctl 中运行,不能作为 macOS 应用运行。请使用 xcrun simctl install booted <path> 命令。

评论

支持 Markdown