You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS打包报错Command PhaseScriptExecution失败,疑似expo-updates问题

问题描述

我尝试通过Xcode构建React Native iOS应用,该项目最初在Windows电脑上使用Expo托管工作流开发。由于应用仅供公司内部支持人员使用,无需发布至App Store,因此我将项目转为裸工作流以制作无需ExpoGo的独立安装包。在MacBook上完成Brew、NPM、Pods、Watchman等环境配置后,构建时出现以下错误:

PhaseScriptExecution [CP-User]\ Generate\ app.manifest\ for\ expo-updates /Users/myusername/Library/Developer/Xcode/DerivedData/myAppName-bfzizgdigfiavjaaxczcpfyuwfnp/Build/Intermediates.noindex/Pods.build/Release-iphoneos/EXUpdates.build/Script-46EB2E00013D80.sh (in target 'EXUpdates' from project 'Pods')
/Xcode/DerivedData/myAppName-bfzizgdigfiavjaaxczcpfyuwfnp/Build/Intermediates.noindex/Pods.build/Release-iphoneos/EXUpdates.build/Script-46EB2E00013D80.sh

Node found at: /usr/local/bin/node
          Welcome to Metro!
       Fast - Scalable - Integrated

node:events:491
   throw er; // Unhandled 'error' event
   ^

Error: EMFILE: too many open files, watch
  at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:204:21)
Emitted 'error' event on NodeWatcher instance at:
  at NodeWatcher.checkedEmitError (/Users/myusername/Develop/projectFolder/ProjectSubFolder/react-apps/myAppname/node_modules/jest-haste-map/build/watchers/NodeWatcher.js:141:12)
  at FSWatcher.emit (node:events:513:28)
  at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:210:12) {
 errno: -24,
 syscall: 'watch',
 code: 'EMFILE',
 filename: null
}
Command PhaseScriptExecution failed with a nonzero exit code

Node found at: /usr/local/bin/node
          Welcome to Metro!
       Fast - Scalable - Integrated

node:events:491
   throw er; // Unhandled 'error' event
   ^

Error: EMFILE: too many open files, watch
  at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:204:21)
Emitted 'error' event on NodeWatcher instance at:
  at NodeWatcher.checkedEmitError (/Users/myusername/Develop/projectFolder/ProjectSubFolder/react-apps/myAppname/node_modules/jest-haste-map/build/watchers/NodeWatcher.js:141:12)
  at FSWatcher.emit (node:events:513:28)
  at FSEvent.FSWatcher._handle.onchange (node:internal/fs/watchers:210:12) {
 errno: -24,
 syscall: 'watch',
 code: 'EMFILE',
 filename: null
}

Command PhaseScriptExecution failed with a nonzero exit code

环境信息

  • MacBook Air M1
  • Xcode 14.1
  • macOS Monterey v12.5
  • NPM 8.19.2
  • Node v16.18.1
  • Homebrew 3.6.12
  • Watchman 2022.11.14.00

已尝试的解决方案

  • 执行 pod deintegrate 和 pod install
  • 重新安装Watchman无效
  • 将Node从v18降级至v16
  • 删除node_modules后重新执行 npm install
  • 执行Brew cleanup
  • 锁定并解锁钥匙串
  • 清理Xcode项目
  • 使用arch -x86_64执行 pod deintegrate 和 pod install
  • 通过x86_64架构的Homebrew安装watchman
  • 在Rosetta终端运行Metro服务器
  • 不使用Rosetta运行XCode
  • 执行命令:sudo launchctl limit maxfiles 16384 16384 && ulimit -n 16384

特殊尝试后的崩溃问题

在Pods目标的**[CP-User] Generate app.manifest for expo-updates**部分勾选"Run script only when installing"后,应用可成功构建并安装到iPhone,但打开时显示启动页后崩溃,Xcode抛出以下错误:

libc++abi: terminating with uncaught exception of type NSException
terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'The embedded manifest is invalid or could not be read. Make sure you have configured expo-updates correctly in your Xcode Build Phases.

我已为此问题困扰近一周,尝试了各种方法均无效,尚未尝试的最后方案是新建裸项目并迁移代码,但希望能修复当前项目。请问是否有遗漏的expo-updates配置问题?还有其他解决办法吗?


解决方案建议

针对EMFILE文件句柄不足的问题

  1. 永久调整系统文件句柄限制
    临时命令重启后会失效,需写入系统配置永久生效:

    • 创建或编辑 /Library/LaunchDaemons/limit.maxfiles.plist 文件,内容如下:
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
        <dict>
          <key>Label</key>
          <string>limit.maxfiles</string>
          <key>ProgramArguments</key>
          <array>
            <string>launchctl</string>
            <string>limit</string>
            <string>maxfiles</string>
            <string>65536</string>
            <string>200000</string>
          </array>
          <key>RunAtLoad</key>
          <true/>
          <key>ServiceIPC</key>
          <false/>
        </dict>
      </plist>
      
    • 执行以下命令加载配置并重启Mac:
      sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
      sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
      

    重启后验证:launchctl limit maxfiles,确认数值已更新。

  2. 强制Metro使用Watchman监控文件
    确保项目根目录的 metro.config.js 开启Watchman支持:

    const { getDefaultConfig } = require('expo/metro-config');
    const config = getDefaultConfig(__dirname);
    
    config.watchFolders = [__dirname];
    config.resolver.useWatchman = true;
    
    module.exports = config;
    

    检查Watchman监控状态:watchman watch-list,若项目目录不在列表中,执行 watchman watch-project /path/to/your/project 手动添加。

针对expo-updates的Manifest无效问题

勾选"Run script only when installing"会导致manifest未在每次构建时生成,这是崩溃的核心原因,按以下步骤修复:

  1. 恢复脚本默认运行设置
    取消勾选"Run script only when installing",先解决EMFILE问题再重新构建。
  2. 手动预生成manifest
    构建前手动执行命令生成manifest:
    npx expo export --platform ios --output-dir ios/build
    
    将生成的 app.manifest 复制到 ios/Pods/EXUpdates/ 目录后,再尝试Xcode构建。
  3. 检查expo-updates配置
    • 确认 app.json/app.config.js 中更新配置正确:
      "updates": {
        "enabled": true,
        "fallbackToCacheTimeout": 0,
        "checkAutomatically": "ON_LOAD"
      }
      
    • 检查Xcode中 EXUpdates 目标的Build Phases,确认 [CP-User] Generate app.manifest for expo-updates 脚本路径和参数无误,脚本应包含调用 npx expo-updates export-manifest 的逻辑。
  4. 重置expo-updates状态
    执行以下命令清除缓存并重新配置:
    npx expo-updates clean
    npx pod-install ios
    

其他备选方案

  1. 禁用expo-updates(内部使用场景适用)
    若无需更新功能,可直接禁用:
    • 在 app.json 中设置 "updates": { "enabled": false }
    • 移除Xcode中 EXUpdates 相关的Build Phases脚本
    • 执行 pod deintegrate && pod install 重新安装依赖
  2. 清理项目目录
    Windows转Mac的项目可能存在冗余隐藏文件,执行命令清理:
    find . -name ".DS_Store" -delete
    
    同时尽量缩短项目路径层级,减少文件监控压力。

内容的提问来源于stack exchange,提问作者Nox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 08:35:17