Skip to content

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を使用した方法:

bash
# 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が便利です:

bash
# pyenvのインストール
brew install pyenv

# Python 3.10の設定
pyenv install 3.10.6
pyenv local 3.10.6  # カレントディレクトリ専用設定

方法2: node-gypの強制更新

依存関係がnode-gypの古いバージョンを使用している場合:

json
{
  "devDependencies": {
    "node-gyp": "^9.0.0"  // 最新バージョンを指定
  },
  "overrides": {
    "prebuild": {         // 問題を起こすパッケージ名に変更
      "node-gyp": "$node-gyp"
    }
  }
}

適用のポイント

  1. package.jsonoverridesセクションに追加
  2. prebuildは実際の依存パッケージ名に置き換える(例:@newrelic/native-metrics
  3. Node.js v16以上が必要
  4. 設定後 npm install を再実行

方法3: 環境変数でPythonパスを指定

システムに複数のPythonがインストールされている場合:

bash
# 一時的な解決(現在のターミナルセッションのみ)
export PYTHON="/opt/homebrew/bin/python3.10"

# 永続化する場合
echo 'export PYTHON="/opt/homebrew/bin/python3.10"' >> ~/.zshrc

あるいはnpm設定で指定:

bash
npm config set python /opt/homebrew/bin/python3.10

方法4: コード修正(緊急時限定)

他の解決方法が適用できない場合の最終手段:

  1. エラーメッセージ内のパスを特定:
    .../node_modules/node-gyp/gyp/pylib/gyp/input.py
  2. 該当ファイルを開き、以下の行を変更:
    python
    build_file_contents = open(build_file_path, 'rU').read()
    python
    build_file_contents = open(build_file_path, 'r').read()

注意

この方法は:

  • 一時的な修正であり、npm installの度に修正が必要
  • 依存関係更新時に上書きされる可能性大
  • 他の互換性問題を引き起こすリスクあり

予防策とベストプラクティス

プロジェクトメンバー間での環境統一

  1. .npmrcファイルを作成:
python = /opt/homebrew/bin/python3.10
  1. enginesフィールドでNode.jsバージョンを固定:
json
"engines": {
  "node": ">=18.0.0"
}

ネイティブモジュールの代替検討

問題のモジュールが頻発する場合、純JavaScript実装の代替ライブラリを検討:

bash
npm install javascript-alternative-package --save

M1 Macユーザー向けチェックリスト

  1. Python管理者情報を確認: which python3
  2. アクティブなPythonバージョンを確認: python3 --version
  3. node-gypの依存関係を検査: npm ls node-gyp
  4. yarn install前に環境変数を設定: export PYTHON=...

まとめ

rUモードエラーは「Node.jsツールチェーンとPython 3.11の非互換性」が原因です。主な解決策として:

方法適用ケース持続性
Python 3.10ダウングレード安定性優先★★★★★
overridesによるnode-gyp更新プロジェクト全体固定★★★★☆
環境変数でのパス指定一時的な対応★★☆☆☆
ソースコード修正緊急避難用★☆☆☆☆

プロダクション環境ではPython 3.10へのダウングレードが最も安全です。開発環境ではoverridesメソッドで問題のあるパッケージの依存関係を上書きする方法が効果的です。これらの対策により、最新のPython環境でもNode.jsネイティブモジュールが正常にビルドできるようになります。