Node.jsとPython 3.11の互換性問題:node-gypエラーの解決方法
問題概要
Node.jsプロジェクトでyarn installまたはnpm installを実行中、以下のようなエラーが発生する場合があります:
gyp info spawn args ]
Traceback (most recent call last):
...
File ".../gyp/pylib/gyp/input.py", line 234, in LoadOneBuildFile
build_file_contents = open(build_file_path, 'rU').read()
ValueError: invalid mode: 'rU' while trying to load binding.gyp
gyp ERR! configure errorこのエラーは主に:
- Mac OS(特にM1チップ搭載機) で発生
- Python 3.11 を使用している環境で顕著
- node-gypがネイティブモジュールのビルドに失敗
- 次のような環境変数エラーも併発:
No pre-built artifacts for your OS/architecture
根本原因
rUファイルモードの非推奨化: Python 3.11で'rU'モード(universal newlinesモード)が完全に廃止されました。node-gypの古いバージョン(v8.0.0未満)はこのモードを使用しているため、Python 3.11環境では動作しません。
環境の変化に注意
Node.jsのネイティブモジュールビルドツールであるnode-gypはPythonに依存しています。Python 3.11のリリース(2022年10月)以降、互換性問題が発生しています。
解決策一覧
方法1: Pythonを3.10にダウングレード(推奨)
最も安全で確実な解決策です。Homebrewを使用した方法:
# Python 3.10のインストール
brew install python@3.10
# 環境変数PATHの先頭に追加(ターミナル再起動時にリセットされます)
export PATH="/opt/homebrew/opt/python@3.10/bin:$PATH"
# 永続化する場合(zsh利用時)
echo 'export PATH="/opt/homebrew/opt/python@3.10/bin:$PATH"' >> ~/.zshrc仮想環境の利用
プロジェクトごとに異なるPythonバージョンを使用するにはpyenvが便利です:
# pyenvのインストール
brew install pyenv
# Python 3.10の設定
pyenv install 3.10.6
pyenv local 3.10.6 # カレントディレクトリ専用設定方法2: node-gypの強制更新
依存関係がnode-gypの古いバージョンを使用している場合:
{
"devDependencies": {
"node-gyp": "^9.0.0" // 最新バージョンを指定
},
"overrides": {
"prebuild": { // 問題を起こすパッケージ名に変更
"node-gyp": "$node-gyp"
}
}
}適用のポイント
package.jsonのoverridesセクションに追加prebuildは実際の依存パッケージ名に置き換える(例:@newrelic/native-metrics)- Node.js v16以上が必要
- 設定後
npm installを再実行
方法3: 環境変数でPythonパスを指定
システムに複数のPythonがインストールされている場合:
# 一時的な解決(現在のターミナルセッションのみ)
export PYTHON="/opt/homebrew/bin/python3.10"
# 永続化する場合
echo 'export PYTHON="/opt/homebrew/bin/python3.10"' >> ~/.zshrcあるいはnpm設定で指定:
npm config set python /opt/homebrew/bin/python3.10方法4: コード修正(緊急時限定)
他の解決方法が適用できない場合の最終手段:
- エラーメッセージ内のパスを特定:
.../node_modules/node-gyp/gyp/pylib/gyp/input.py - 該当ファイルを開き、以下の行を変更:python↓
build_file_contents = open(build_file_path, 'rU').read()pythonbuild_file_contents = open(build_file_path, 'r').read()
注意
この方法は:
- 一時的な修正であり、
npm installの度に修正が必要 - 依存関係更新時に上書きされる可能性大
- 他の互換性問題を引き起こすリスクあり
予防策とベストプラクティス
プロジェクトメンバー間での環境統一
.npmrcファイルを作成:
python = /opt/homebrew/bin/python3.10enginesフィールドでNode.jsバージョンを固定:
"engines": {
"node": ">=18.0.0"
}ネイティブモジュールの代替検討
問題のモジュールが頻発する場合、純JavaScript実装の代替ライブラリを検討:
npm install javascript-alternative-package --saveM1 Macユーザー向けチェックリスト
- Python管理者情報を確認:
which python3 - アクティブなPythonバージョンを確認:
python3 --version - node-gypの依存関係を検査:
npm ls node-gyp yarn install前に環境変数を設定:export PYTHON=...
まとめ
rUモードエラーは「Node.jsツールチェーンとPython 3.11の非互換性」が原因です。主な解決策として:
| 方法 | 適用ケース | 持続性 |
|---|---|---|
| Python 3.10ダウングレード | 安定性優先 | ★★★★★ |
overridesによるnode-gyp更新 | プロジェクト全体固定 | ★★★★☆ |
| 環境変数でのパス指定 | 一時的な対応 | ★★☆☆☆ |
| ソースコード修正 | 緊急避難用 | ★☆☆☆☆ |
プロダクション環境ではPython 3.10へのダウングレードが最も安全です。開発環境ではoverridesメソッドで問題のあるパッケージの依存関係を上書きする方法が効果的です。これらの対策により、最新のPython環境でもNode.jsネイティブモジュールが正常にビルドできるようになります。