limrun-expo-development
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDeveloping Expo Apps on Limrun
在Limrun上开发Expo应用
Use this skill for Expo / React Native-specific setup and dev-client iteration. Use the generic Limrun iOS skill for command details, simulator interaction, screenshots, recordings, cleanup, and non-Expo iOS workflows.
All iOS builds and simulator operations must run on Limrun. Do not use local Xcode, local simulators, or local macOS build tools.
本技能适用于Expo/React Native专属的设置与开发客户端迭代流程。如需命令详情、模拟器交互、截图、录屏、清理以及非Expo的iOS工作流,请使用通用的Limrun iOS技能。
所有iOS构建和模拟器操作必须在Limrun上执行,不得使用本地Xcode、本地模拟器或本地macOS构建工具。
Expo Readiness
Expo就绪检查
Before changing Expo dependencies or app config, check the app's Expo SDK version and use the matching Expo versioned docs.
Verify this is an Expo app:
bash
npx expo config --type introspect --jsonDerive:
- from
BUNDLE_IDios.bundleIdentifier - from
SLUGslug - from
SCHEME, falling back toschemeexp+${SLUG} - from
BRANCH, falling back togit branch --show-currentmain ASSET_NAME="${BUNDLE_ID}/${BRANCH}-debug.zip"
在修改Expo依赖或应用配置前,请检查应用的Expo SDK版本,并使用对应版本的Expo文档。
验证当前项目是否为Expo应用:
bash
npx expo config --type introspect --json提取以下信息:
- 从中获取
ios.bundleIdentifierBUNDLE_ID - 从中获取
slugSLUG - 从中获取
scheme,若不存在则回退为SCHEMEexp+${SLUG} - 从中获取
git branch --show-current,若不存在则回退为BRANCHmain ASSET_NAME="${BUNDLE_ID}/${BRANCH}-debug.zip"
Ensure Dev Client
确保安装开发客户端
Expo development builds require . If it is missing from , install it automatically:
expo-dev-clientpackage.jsonbash
npx expo install expo-dev-clientInstalling , adding/removing/updating native dependencies, or changing native app config means the uploaded Debug asset is stale. Build a fresh Debug app before starting the dev loop. Do not merely warn the user that a rebuild may be needed; perform the rebuild.
expo-dev-clientExpo开发构建需要。若中未包含该依赖,请自动安装:
expo-dev-clientpackage.jsonbash
npx expo install expo-dev-client若安装了、添加/移除/更新原生依赖,或是修改了原生应用配置,则已上传的Debug资源会失效。在启动开发循环前,请重新构建一个全新的Debug应用,仅告知用户可能需要重建是不够的,必须执行重建操作。
expo-dev-clientDebug Build Asset
Debug构建资源
First check whether a reusable Debug dev-client asset already exists:
bash
lim asset list --name-prefix "$BUNDLE_ID/"Reuse the exact only when:
$ASSET_NAME- it exists, and
- no native dependency or native config changed in this session.
If the current task changed native dependencies or native config, skip asset reuse even if exists.
$ASSET_NAMEWhen reusing the asset, create or reuse a simulator and install it:
bash
lim ios create \
--reuse-if-exists \
--install-asset "$ASSET_NAME" \
--label repo=<repo> \
--label agent=<agent>When building fresh, create or reuse an iOS simulator with Xcode:
bash
lim ios create --xcode \
--reuse-if-exists \
--label repo=<repo> \
--label agent=<agent>If an iOS simulator is already running from a reused asset and a later native rebuild becomes necessary, attach or create Xcode for that same simulator instead of creating a second iOS simulator:
bash
lim xcode create --reuse-if-exists --label repo=<repo> --label agent=<agent>
lim xcode attach-simulator <ios-instance-id> --id <xcode-instance-id>Then build and upload Debug:
bash
lim xcode build . \
--configuration Debug \
--upload "$ASSET_NAME"Use , , or when the project layout requires it. A successful build installs and launches the app on the attached simulator.
--expo-app-dir--scheme--workspace首先检查是否存在可复用的Debug开发客户端资源:
bash
lim asset list --name-prefix "$BUNDLE_ID/"仅在以下情况下才能复用指定的:
$ASSET_NAME- 该资源确实存在,且
- 当前会话中未修改原生依赖或原生配置
若当前任务修改了原生依赖或原生配置,即使存在,也不能复用该资源。
$ASSET_NAME复用资源时,创建或复用模拟器并安装该资源:
bash
lim ios create \
--reuse-if-exists \
--install-asset "$ASSET_NAME" \
--label repo=<repo> \
--label agent=<agent>构建全新资源时,使用Xcode创建或复用iOS模拟器:
bash
lim ios create --xcode \
--reuse-if-exists \
--label repo=<repo> \
--label agent=<agent>若已复用资源启动了iOS模拟器,但后续需要进行原生重建,请为该模拟器附加或创建Xcode实例,而非创建第二个iOS模拟器:
bash
lim xcode create --reuse-if-exists --label repo=<repo> --label agent=<agent>
lim xcode attach-simulator <ios-instance-id> --id <xcode-instance-id>随后构建并上传Debug资源:
bash
lim xcode build . \
--configuration Debug \
--upload "$ASSET_NAME"若项目布局需要,可使用、或参数。构建成功后,应用会自动安装并启动在已附加的模拟器上。
--expo-app-dir--scheme--workspaceStart Metro Tunnel
启动Metro隧道
Start Metro after the Debug app is installed:
bash
npx expo start --dev-client --tunnelIf is busy, choose a free port with . If tunnel startup fails or exits, retry a few times; if it still fails, use the Limrun reverse fallback below. Keep Metro running while the user iterates.
8081--port <port>Get the tunnel URL from Expo output. If Expo does not print it, query the local ngrok API:
https://*.exp.directbash
curl -sS http://127.0.0.1:4040/api/tunnels在Debug应用安装完成后启动Metro:
bash
npx expo start --dev-client --tunnel若端口被占用,请使用选择一个空闲端口。若隧道启动失败或退出,请重试几次;若仍失败,请使用下方的Limrun反向隧道作为备选方案。在用户进行迭代期间,请保持Metro持续运行。
8081--port <port>从Expo输出中获取格式的隧道URL。若Expo未打印该URL,请查询本地ngrok API:
https://*.exp.directbash
curl -sS http://127.0.0.1:4040/api/tunnelsFallback: Limrun Reverse Tunnel
备选方案:Limrun反向隧道
If Expo's repeatedly fails, use with a matched remote/local port. Expo dev-client can derive or advertise multiple packager URLs, so mismatched mappings like can leave some URLs pointing at the local Metro port instead of the simulator-facing tunnel port.
--tunnellim ios reverse57090:8081Use the simulator-facing host printed by in both and the encoded dev-client URL. Keep the reverse command running in a separate or background terminal while Metro is running:
lim ios reverseREACT_NATIVE_PACKAGER_HOSTNAMEbash
lim ios reverse 57090:57090 --id <ios-instance-id>
REACT_NATIVE_PACKAGER_HOSTNAME=<reverse-host> \
npx expo start --dev-client --host lan --port 57090
ENCODED_URL="$(node -e 'console.log(encodeURIComponent(process.argv[1]))' "http://<reverse-host>:57090")"
DEV_CLIENT_URL="${SCHEME}://expo-development-client/?url=${ENCODED_URL}"
lim ios open-url --id <ios-instance-id> "$DEV_CLIENT_URL"若Expo的参数反复失败,请使用命令匹配远程/本地端口。Expo开发客户端可推导或广播多个打包器URL,因此像这样不匹配的映射可能会导致部分URL指向本地Metro端口,而非模拟器面向的隧道端口。
--tunnellim ios reverse57090:8081请将输出的模拟器面向主机同时用于和编码后的开发客户端URL。在Metro运行期间,请将反向命令保持在单独终端或后台运行:
lim ios reverseREACT_NATIVE_PACKAGER_HOSTNAMEbash
lim ios reverse 57090:57090 --id <ios-instance-id>
REACT_NATIVE_PACKAGER_HOSTNAME=<reverse-host> \
npx expo start --dev-client --host lan --port 57090
ENCODED_URL="$(node -e 'console.log(encodeURIComponent(process.argv[1]))' "http://<reverse-host>:57090")"
DEV_CLIENT_URL="${SCHEME}://expo-development-client/?url=${ENCODED_URL}"
lim ios open-url --id <ios-instance-id> "$DEV_CLIENT_URL"Launch Dev Client
启动开发客户端
Open the Debug app through the dev-client URL:
bash
ENCODED_URL="$(node -e 'console.log(encodeURIComponent(process.argv[1]))' "$TUNNEL_URL")"
DEV_CLIENT_URL="${SCHEME}://expo-development-client/?url=${ENCODED_URL}"
lim ios open-url "$DEV_CLIENT_URL"If opening fails and the primary scheme came from , retry once with .
schemeexp+${SLUG}通过开发客户端URL打开Debug应用:
bash
ENCODED_URL="$(node -e 'console.log(encodeURIComponent(process.argv[1]))' "$TUNNEL_URL")"
DEV_CLIENT_URL="${SCHEME}://expo-development-client/?url=${ENCODED_URL}"
lim ios open-url "$DEV_CLIENT_URL"若打开失败,且主scheme来自参数,请使用重试一次。
schemeexp+${SLUG}Verify
验证
For quick static validation, prefer:
bash
npx tsc --noEmitOnly run or when the repo already has ESLint configured. Expo lint can create ESLint config and mutate dependencies in projects that have not configured linting yet.
npm run lintnpx expo lintUse the element tree first:
bash
lim ios element-treeSuccess means the app UI is visible or the Expo dev menu shows it is connected to the tunnel. Dismiss the dev menu overlay if needed. If the tree does not confirm the connection, inspect app logs:
bash
lim ios app-log "$BUNDLE_ID" --tail 100如需快速静态验证,优先使用:
bash
npx tsc --noEmit仅当仓库已配置ESLint时,才运行或。对于尚未配置代码检查的项目,Expo lint会创建ESLint配置并修改依赖。
npm run lintnpx expo lint优先使用元素树进行验证:
bash
lim ios element-tree验证成功意味着应用UI可见,或Expo开发菜单显示已连接至隧道。若有需要,请关闭开发菜单覆盖层。若元素树未确认连接状态,请检查应用日志:
bash
lim ios app-log "$BUNDLE_ID" --tail 100Iterating
迭代开发
Once connected, JS/TS edits should update through Metro without another native build. If the task changes native dependencies, native config, or build settings, rebuild Debug before relaunching the dev loop.
Tell the user:
- simulator stream as a short Markdown link, for example
[Open simulator stream](<signedStreamUrl>) - uploaded Debug asset name
- that JS/TS changes can now iterate through Metro
- that native changes require a new Debug build
连接成功后,JS/TS代码修改应通过Metro自动更新,无需再次进行原生构建。若任务修改了原生依赖、原生配置或构建设置,请在重启开发循环前重新构建Debug应用。
告知用户以下信息:
- 模拟器流的短Markdown链接,例如
[打开模拟器流](<signedStreamUrl>) - 已上传的Debug资源名称
- 现在可通过Metro进行JS/TS代码的迭代开发
- 原生代码修改需要重新构建Debug应用
Final Preview
最终预览
For a final shareable preview or PR demo, use a Release build so the user does not need Metro running:
bash
ASSET_NAME="<bundle-id>/<pr-or-session>.zip"
lim xcode build . --configuration Release --upload "$ASSET_NAME"Preview URL:
text
https://console.limrun.com/preview?asset=${ASSET_NAME}&platform=ios如需可分享的最终预览或PR演示,请使用Release构建,这样用户无需保持Metro运行:
bash
ASSET_NAME="<bundle-id>/<pr-or-session>.zip"
lim xcode build . --configuration Release --upload "$ASSET_NAME"预览URL:
text
https://console.limrun.com/preview?asset=${ASSET_NAME}&platform=iosGotchas
注意事项
- requires
npx expo start --dev-client; without it Expo cannot determine the development-build scheme.expo-dev-client - usually means the app is not a dev-client build or was launched without a dev-client URL.
No script URL provided - After a fresh native rebuild/install, a stale Metro/runtime error like may come from the old app process. Relaunch the dev-client URL and verify with
Cannot find native modulebefore assuming the rebuild failed.element-tree - If a Debug build after adding a native dependency still behaves like the old native graph, that is unexpected Limrun behavior. Retry the build; creating a fresh iOS/Xcode target is only a troubleshooting fallback.
- Expo tunnel startup can be flaky. Retry before changing the workflow.
- Do not reuse uploaded Debug assets after native dependency or native config changes.
- 命令需要
npx expo start --dev-client依赖;若无该依赖,Expo无法确定开发构建的scheme。expo-dev-client - 出现错误通常意味着应用不是开发客户端构建,或是未通过开发客户端URL启动。
No script URL provided - 在全新原生重建/安装后,若出现这类陈旧的Metro/运行时错误,可能是旧应用进程导致的。在假设重建失败前,请重新启动开发客户端URL并通过
Cannot find native module验证。element-tree - 若添加原生依赖后的Debug构建仍表现出旧原生图的行为,这属于Limrun的异常行为。请重试构建;创建全新的iOS/Xcode目标仅作为故障排查的备选方案。
- Expo隧道启动可能不稳定,请在更改工作流前重试几次。
- 修改原生依赖或原生配置后,请勿复用已上传的Debug资源。