如何解决Xcode构建RN新项目FBReactNativeSpec脚本执行失败问题
React Native 新项目FBReactNativeSpec阶段Xcode构建失败问题
问题描述
- 所有存量React Native项目可在Xcode中正常构建,仅新创建的RN项目构建失败
- 报错归类在
FBReactNativeSpec项下,为未分类错误,核心报错信息:Command PhaseScriptExecution failed with a nonzero exit code - 同一份项目代码在其他同事的设备上可正常完成构建
- 补充验证:使用React Native 0.66.1旧版本初始化新项目,可正常构建无该报错
已尝试的无效操作
- 重启电脑
- 删除本地代码仓库后重新克隆
- 测试多个全新初始化的RN项目
- 重新安装pods
- 更新pods版本
- 重新安装CocoaPods
- 卸载移除nvm
- 彻底清理电脑上所有Xcode相关文件后重新安装Xcode
环境信息
- 设备:搭载2.6 GHz 6核Intel Core i7处理器的MacBook Pro
- Xcode版本:13.4.1
报错关联构建脚本
pushd "$PODS_ROOT/../" > /dev/null RCT_SCRIPT_POD_INSTALLATION_ROOT=$(pwd) popd >/dev/null export RCT_SCRIPT_RN_DIR=${PODS_TARGET_SRCROOT}/../.. export RCT_SCRIPT_LIBRARY_NAME=FBReactNativeSpec export RCT_SCRIPT_OUTPUT_DIR=$RCT_SCRIPT_POD_INSTALLATION_ROOT/build/generated/ios export RCT_SCRIPT_LIBRARY_TYPE=modules export RCT_SCRIPT_JS_SRCS_PATTERN=Native*.js export RCT_SCRIPT_JS_SRCS_DIR=../../Libraries export RCT_SCRIPT_CODEGEN_MODULE_DIR=. export RCT_SCRIPT_CODEGEN_COMPONENT_DIR=react/renderer/components export RCT_SCRIPT_FILE_LIST="[\"../../Libraries/ActionSheetIOS/NativeActionSheetManager.js\", \"../../Libraries/Alert/NativeAlertManager.js\", \"../../Libraries/Animated/NativeAnimatedHelper.js\", \"../../Libraries/Animated/NativeAnimatedModule.js\", \"../../Libraries/Animated/NativeAnimatedTurboModule.js\", \"../../Libraries/AppState/NativeAppState.js\", \"../../Libraries/BatchedBridge/NativeModules.js\", \"../../Libraries/Blob/NativeBlobModule.js\", \"../../Libraries/Blob/NativeFileReaderModule.js\", \"../../Libraries/BugReporting/NativeBugReporting.js\", \"../../Libraries/Components/AccessibilityInfo/NativeAccessibilityInfo.js\", \"../../Libraries/Components/AccessibilityInfo/NativeAccessibilityManager.js\", \"../../Libraries/Components/Clipboard/NativeClipboard.js\", \"../../Libraries/Components/DatePickerAndroid/NativeDatePickerAndroid.js\", \"../../Libraries/Components/Keyboard/NativeKeyboardObserver.js\", \"../../Libraries/Components/Sound/NativeSoundManager.js\", \"../../Libraries/Components/StatusBar/NativeStatusBarManagerAndroid.js\", \"../../Libraries/Components/StatusBar/NativeStatusBarManagerIOS.js\", \"../../Libraries/Components/ToastAndroid/NativeToastAndroid.js\", \"../../Libraries/Core/NativeExceptionsManager.js\", \"../../Libraries/Core/SegmentFetcher/NativeSegmentFetcher.js\", \"../../Libraries/Core/Timers/NativeTiming.js\", \"../../Libraries/EventEmitter/NativeEventEmitter.js\", \"../../Libraries/EventEmitter/__mocks__/NativeEventEmitter.js\", \"../../Libraries/HeapCapture/NativeJSCHeapCapture.js\", \"../../Libraries/Image/NativeImageEditor.js\", \"../../Libraries/Image/NativeImageLoaderAndroid.js\", \"../../Libraries/Image/NativeImageLoaderIOS.js\", \"../../Libraries/Image/NativeImagePickerIOS.js\", \"../../Libraries/Image/NativeImageStoreAndroid.js\", \"../../Libraries/Image/NativeImageStoreIOS.js\", \"../../Libraries/Interaction/NativeFrameRateLogger.js\", \"../../Libraries/Linking/NativeIntentAndroid.js\", \"../../Libraries/Linking/NativeLinkingManager.js\", \"../../Libraries/Modal/NativeModalManager.js\", \"../../Libraries/NativeComponent/NativeComponentRegistry.js\", \"../../Libraries/NativeComponent/NativeComponentRegistryUnstable.js\", \"../../Libraries/NativeModules/specs/NativeAnimationsDebugModule.js\", \"../../Libraries/NativeModules/specs/NativeDevMenu.js\", \"../../Libraries/NativeModules/specs/NativeDevSettings.js\", \"../../Libraries/NativeModules/specs/NativeDeviceEventManager.js\", \"../../Libraries/NativeModules/specs/NativeDialogManagerAndroid.js\", \"../../Libraries/NativeModules/specs/NativeLogBox.js\", \"../../Libraries/NativeModules/specs/NativeRedBox.js\", \"../../Libraries/NativeModules/specs/NativeSourceCode.js\", \"../../Libraries/Network/NativeNetworkingAndroid.js\", \"../../Libraries/Network/NativeNetworkingIOS.js\", \"../../Libraries/Performance/NativeJSCSamplingProfiler.js\", \"../../Libraries/PermissionsAndroid/NativePermissionsAndroid.js\", \"../../Libraries/PushNotificationIOS/NativePushNotificationManagerIOS.js\", \"../../Libraries/ReactNative/NativeHeadlessJsTaskSupport.js\", \"../../Libraries/ReactNative/NativeI18nManager.js\", \"../../Libraries/ReactNative/NativeUIManager.js\", \"../../Libraries/Settings/NativeSettingsManager.js\", \"../../Libraries/Share/NativeShareModule.js\", \"../../Libraries/Storage/NativeAsyncLocalStorage.js\", \"../../Libraries/Storage/NativeAsyncSQLiteDBStorage.js\", \"../../Libraries/TurboModule/samples/NativeSampleTurboModule.js\", \"../../Libraries/Utilities/NativeAppearance.js\", \"../../Libraries/Utilities/NativeDevLoadingView.js\", \"../../Libraries/Utilities/NativeDevSplitBundleLoader.js\", \"../../Libraries/Utilities/NativeDeviceInfo.js\", \"../../Libraries/Utilities/NativeJSDevSupport.js\", \"../../Libraries/Utilities/NativePlatformConstantsAndroid.js\", \"../../Libraries/Utilities/NativePlatformConstantsIOS.js\", \"../../Libraries/Vibration/NativeVibration.js\", \"../../Libraries/WebSocket/NativeWebSocketModule.js\"]" SCRIPT_PHASES_SCRIPT="$RCT_SCRIPT_RN_DIR/scripts/react_native_pods_utils/script_phases.sh" /bin/sh -c "$SCRIPT_PHASES_SCRIPT"
问题解答与修复方案
关于脚本中$(pwd)的含义
这不是Shell内置的预定义变量,是Shell的命令替换语法:执行$()包裹的命令,将命令的标准输出结果直接替换到对应位置。这里的作用是执行pwd命令获取当前工作目录的绝对路径,赋值给RCT_SCRIPT_POD_INSTALLATION_ROOT变量,用来定位项目pod安装的根目录。
构建失败根因
React Native 0.67及以上版本新增了新架构Codegen脚本逻辑,FBReactNativeSpec阶段的构建脚本依赖Node环境执行JS代码生成原生规格文件;0.66.1版本未引入该逻辑因此可正常构建。
该问题在Intel芯片Mac + Xcode 13.4环境下触发的核心原因是:Xcode执行构建脚本时使用的PATH环境变量不包含Node的实际安装路径,导致脚本调用Node时找不到命令,直接返回非0退出码触发构建失败。卸载nvm后如果Node是通过官网pkg包安装到/usr/local/bin路径下,Xcode默认的PATH不会加载该路径,就会触发该问题。
修复步骤
- 打开终端执行
which node,记录输出的Node绝对路径,常见路径为/usr/local/bin/node - 打开项目ios目录下的Pods工程,在Target列表中找到
FBReactNativeSpec,切换到Build Phases标签 - 找到名为
[CP-User] Generate Specs的脚本阶段,在脚本内容的最开头添加一行PATH配置,将Node所在目录加入环境变量,例如:
export PATH="/usr/local/bin:$PATH"
- 按下快捷键
Cmd+Shift+K清理Xcode构建缓存,重新构建即可。
内容的提问来源于stack exchange,提问作者JSharles
相关产品推荐
相关产品推荐

