React NativeのPhaseScriptExecutionエラー解決方法
問題
React NativeプロジェクトでiOSビルド時にPhaseScriptExecution [CP-User]
エラーが発生します。特に以下のようなエラーメッセージが表示されます:
** BUILD FAILED **
The following build commands failed:
PhaseScriptExecution [CP-User]\ Generate\ Specs /Users/.../Script-6B583FC85C8A2C3CF6842DBACCA71427.sh
このエラーはM1/M2 Macで特に頻繁に発生し、Xcodeからは正常にビルドできるものの、react-native run-ios
コマンドでは失敗する場合が多いです。
原因
主な原因は以下のいずれかです:
- パスにスペースが含まれている:プロジェクトのパスにスペースが含まれている
- Node.jsのパス問題:nvmやバージョンマネージャーによるNode.jsのパス検索の問題
- アーキテクチャの不一致:RosettaモードとネイティブARMモードの混在
- Flipperのバージョン不一致:React NativeとFlipperのバージョン互換性の問題
解決方法
方法1: パスからスペースを除去する
プロジェクトのパスにスペースが含まれている場合、エラーが発生することがあります。
# 悪い例: パスにスペースが含まれる
/Users/username/My Projects/React Native/MyApp
# 良い例: スペースをハイフンやアンダースコアで置換
/Users/username/My-Projects/React-Native/MyApp
パスを変更した後、以下のコマンドを実行してください:
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
npx react-native run-ios
方法2: Node.jsのパスを明示的に設定する
nvmを使用している場合、パス検索で問題が発生することがあります。
オプションA: 環境変数を設定
ios/.xcode.env.local
ファイルを作成または編集し、Node.jsのパスを明示的に設定します:
export NODE_BINARY="$(command -v node)"
または、特定のパスを指定:
export NODE_BINARY="/opt/homebrew/bin/node"
# または
export NODE_BINARY="/usr/local/bin/node"
正しいNode.jsのパスはwhich node
コマンドで確認できます。
オプションB: find-node.shスクリプトを修正
node_modules/react-native/scripts/find-node.sh
内のnvm関連の処理をコメントアウト:
# 以下のコードブロックをコメントアウト
# if [[ -s "$HOME/.nvm/nvm.sh" ]]; then
# . "$HOME/.nvm/nvm.sh"
# elif [[ -x "$(command -v brew)" && -s "$(brew --prefix nvm)/nvm.sh" ]]; then
# . "$(brew --prefix nvm)/nvm.sh"
# fi
方法3: Rosettaモードの一貫性を確保する
M1/M2 Macでは、すべてのツールが同じアーキテクチャで動作していることを確認します。
ターミナルをRosettaモードで実行:
- Finderでターミナルアプリを右クリック
- 「情報を見る」を選択
- 「Rosettaを使用して開く」にチェック
Homebrewのパスを確認:
bash# x86版Homebrew(Rosetta) /usr/local/homebrew/bin # ARM版Homebrew(ネイティブ) /opt/homebrew/bin
すべてのツールが同じパス体系を使用していることを確認してください。
ツールの再インストール:
bash# Homebrewのアンインストール(必要に応じて) /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)" # RosettaモードのターミナルでHomebrew再インストール /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # Node.jsと必須ツールのインストール brew install node watchman sudo gem install cocoapods
方法4: Flipperのバージョンを固定する
ios/Podfile
内でFlipperのバージョンを明示的に指定します:
use_flipper!({
'Flipper-Folly' => '2.5.3',
'Flipper' => '0.87.0',
'Flipper-RSocket' => '1.3.1'
})
その後、Podの再インストールを実行:
cd ios
rm -rf Pods Podfile.lock
pod install
cd ..
方法5: シンボリックリンクの作成
Node.jsのパスが正しく認識されない場合、シンボリックリンクを作成します:
sudo ln -s $(which node) /usr/local/bin/node
トラブルシューティング
ビルド設定の確認
Xcodeで以下の設定を確認してください:
- Build Settings → Build Active Architecture Only → Debug: Yesに設定
- Excluded Architectures: シミュレーターの場合のみ
arm64
を追加
キャッシュのクリーンアップ
定期的にキャッシュをクリーンアップすることで、問題が解決することがあります:
# Nodeモジュールのクリーンアップ
rm -rf node_modules
yarn cache clean
npm cache clean --force
# iOS関連のクリーンアップ
cd ios
rm -rf Pods Podfile.lock
pod cache clean --all
# Xcodeの派生データ削除
rm -rf ~/Library/Developer/Xcode/DerivedData
予防策
- プロジェクトパス:スペースや特殊文字を含まないパスを使用する
- バージョン管理:Node.jsとReact Nativeのバージョン互換性を確認する
- 一貫した環境:すべての開発ツールを同じアーキテクチャモードで使用する
- 定期的な更新:React Nativeと依存関係を定期的に更新する
まとめ
PhaseScriptExecution
エラーは主に環境設定の問題によって発生します。パスの問題、Node.jsの設定、アーキテクチャの不一致など、様々な要因が考えられます。上記の解決方法を順に試してみて、ご自身の環境に合った方法を見つけてください。
TIP
最も効果的な解決策は、プロジェクトパスからスペースを除去し、Node.jsのパスを明示的に設定することです。M1/M2 Macユーザーは、ツールのアーキテクチャ一貫性にも注意してください。
この記事がReact Native開発の悩みを解決する一助となれば幸いです。