T-CREATOR

Electron ビルド失敗解決:native module 再ビルドと node-gyp 地獄からの脱出

Electron ビルド失敗解決:native module 再ビルドと node-gyp 地獄からの脱出

Electron アプリケーションの開発中、ビルド時に突然現れる native module のエラーに頭を悩ませたことはありませんか。「node-gyp のビルドに失敗しました」「モジュールが見つかりません」といったメッセージを見て、途方に暮れた経験のある方も多いでしょう。

本記事では、Electron ビルドにおける native module の再ビルド問題と、node-gyp に関連するトラブルシューティングの方法を、初心者の方にもわかりやすく解説します。実際のエラーコードや解決手順を具体的に示しながら、この「地獄」から抜け出すための道筋をご案内しますね。

背景

Electron と native module の関係性

Electron は、Web 技術(HTML、CSS、JavaScript)を使ってデスクトップアプリケーションを構築できる強力なフレームワークです。しかし、その裏側では Node.js と Chromium が動作しており、これらは異なるバージョンの V8 エンジンや Node.js のバイナリを使用しています。

native module(ネイティブモジュール)とは、C/C++ で書かれた Node.js の拡張機能のことを指します。これらは高速な処理や OS レベルの機能にアクセスするために使われますが、JavaScript だけでなく、プラットフォーム固有のバイナリコードを含むため、適切な環境でコンパイルする必要があります。

以下の図は、Electron アプリケーションにおける各コンポーネントの関係性を示しています。

mermaidflowchart TB
  app["Electron アプリ"]
  renderer["Renderer<br/>Process<br/>(Chromium)"]
  main["Main Process<br/>(Node.js)"]
  native["Native Module<br/>(C/C++)"]
  os["OS API"]

  app --> renderer
  app --> main
  main --> native
  native --> os

  style native fill:#ff9999
  style main fill:#99ccff
  style renderer fill:#99ff99

この図からわかるように、Native Module は Main Process を通じて OS の機能にアクセスします。そのため、Electron の Node.js バージョンに合わせてコンパイルされる必要があるのです。

なぜ再ビルドが必要なのか

通常の Node.js アプリケーションでは、yarn installnpm install でインストールしたパッケージをそのまま使えます。しかし Electron の場合、以下の理由で native module の再ビルドが必要になります。

#理由説明
1Node.js バージョンの違いElectron が使用する Node.js と開発環境の Node.js バージョンが異なる
2ABI の非互換性Application Binary Interface が異なるため、バイナリの互換性がない
3V8 エンジンの違いChromium の V8 と Node.js の V8 でバージョンが異なる場合がある
4プラットフォーム依存性macOS、Windows、Linux でバイナリが異なる

これらの違いにより、通常の Node.js 用にビルドされた native module は Electron では動作しません。

よく使われる native module の例

実際のプロジェクトでよく使用される native module には、以下のようなものがあります。

#パッケージ名用途
1sqlite3SQLite データベース操作
2serialportシリアルポート通信
3node-sassSass のコンパイル
4bcryptパスワードのハッシュ化
5sharp画像処理
6canvasCanvas API の実装

これらのパッケージを使用している場合、Electron ビルド時に特別な対処が必要になります。

課題

典型的なエラーメッセージ

Electron で native module を使用する際、以下のようなエラーメッセージに遭遇することがよくあります。実際のエラーコードとともに見ていきましょう。

エラー 1: Module version mismatch

最も頻繁に発生するのが、モジュールのバージョン不一致エラーです。

javascriptError: The module '/path/to/module.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 93. This version of Node.js requires
NODE_MODULE_VERSION 109. Please try re-compiling or re-installing
the module (for instance, using `npm rebuild` or `npm install`).

このエラーは、インストールされた native module が開発環境の Node.js バージョン用にコンパイルされており、Electron の Node.js バージョンと一致していないことを示しています。

エラー 2: node-gyp のビルド失敗

node-gyp は native module をビルドするためのツールですが、環境設定が不完全だと以下のようなエラーが発生します。

vbnetgyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit
gyp ERR! System Darwin 21.6.0
gyp ERR! command "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /path/to/project/node_modules/some-native-module
gyp ERR! node -v v16.14.0
gyp ERR! node-gyp -v v8.4.1
gyp ERR! not ok

これは、C/C++ のビルドツールチェーンが正しくインストールされていないか、設定が不適切な場合に発生します。

エラー 3: electron-rebuild の失敗

electron-rebuild を使用した場合でも、以下のようなエラーが出ることがあります。

vbnet✖ Rebuild Failed

An unhandled error occurred inside electron-rebuild
node-gyp failed to rebuild '/path/to/project/node_modules/sqlite3'.
Error: Command failed: node-gyp rebuild --target=18.3.5 --arch=x64 --dist-url=https://electronjs.org/headers

これは、特定のパッケージの再ビルドプロセス自体が失敗していることを示しています。

エラーが発生する主な原因

以下の図は、native module のビルドエラーが発生する主な原因とその関係性を示しています。

mermaidflowchart TD
  start["ビルドエラー発生"]
  env_check{"環境設定<br/>確認"}
  tools_missing["ビルドツール<br/>未インストール"]
  version_mismatch["バージョン<br/>不一致"]
  config_error["設定ファイル<br/>エラー"]

  start --> env_check
  env_check -->|ツール不足| tools_missing
  env_check -->|バージョン問題| version_mismatch
  env_check -->|設定問題| config_error

  tools_missing --> python_missing["Python 未導入"]
  tools_missing --> compiler_missing["C++ コンパイラ<br/>未導入"]

  version_mismatch --> node_version["Node.js<br/>バージョン違い"]
  version_mismatch --> electron_version["Electron<br/>バージョン違い"]

  config_error --> npmrc["npmrc 設定"]
  config_error --> gyp_config["node-gyp 設定"]

  style start fill:#ff9999
  style tools_missing fill:#ffcc99
  style version_mismatch fill:#ffcc99
  style config_error fill:#ffcc99

この図から、エラーの原因は主に 3 つのカテゴリーに分類できることがわかります。それぞれに適切な対処法があるため、まずは原因の特定が重要です。

プラットフォーム別の注意点

#プラットフォーム主な課題必要なツール
1macOSXcode Command Line Tools の導入Xcode CLI、Python
2WindowsVisual Studio Build Tools の設定VS Build Tools、Python
3Linux各種開発パッケージのインストールbuild-essential、Python

それぞれのプラットフォームで必要な準備が異なるため、クロスプラットフォーム開発では特に注意が必要になります。

解決策

基本的な解決フロー

native module のビルド問題を解決するには、段階的なアプローチが効果的です。以下のフローチャートに従って進めていきましょう。

mermaidflowchart TD
  step1["1. 環境確認"]
  step2["2. ビルドツール<br/>インストール"]
  step3["3. electron-rebuild<br/>実行"]
  step4{"ビルド<br/>成功?"}
  step5["5. アプリ起動<br/>テスト"]
  step6["完了"]
  step7["4. トラブル<br/>シューティング"]

  step1 --> step2
  step2 --> step3
  step3 --> step4
  step4 -->|はい| step5
  step4 -->|いいえ| step7
  step5 --> step6
  step7 --> step3

  style step1 fill:#99ccff
  style step6 fill:#99ff99
  style step7 fill:#ffcc99

このフローに沿って、具体的な手順を見ていきます。

ステップ 1: 環境の確認

まず、現在の環境を確認します。以下のコマンドで、必要な情報を収集しましょう。

bash# Node.js のバージョン確認
node -v
bash# Yarn のバージョン確認
yarn -v
bash# Python のバージョン確認(Python 3.x が必要)
python3 --version
bash# Electron のバージョン確認
yarn list electron

これらのコマンドで、各ツールのバージョンが正しく表示されることを確認してください。特に Python は 3.x 系が必要です。

ステップ 2: ビルドツールのインストール

プラットフォームごとに、必要なビルドツールをインストールします。

macOS の場合

macOS では、Xcode Command Line Tools をインストールする必要があります。

bash# Xcode Command Line Tools のインストール
xcode-select --install

インストール後、以下のコマンドで確認できます。

bash# インストール確認
xcode-select -p

正常にインストールされている場合、​/​Library​/​Developer​/​CommandLineTools のようなパスが表示されます。

Windows の場合

Windows では、Visual Studio Build Tools をインストールします。

bash# Windows Build Tools を一括インストール(管理者権限で実行)
yarn global add windows-build-tools

または、Visual Studio 2019 以降をインストールし、「C++ によるデスクトップ開発」ワークロードを選択します。

bash# Python のインストール確認(必要に応じて)
python --version

Windows では、Python が自動的にインストールされない場合があるため、別途インストールが必要です。

Linux (Ubuntu/Debian) の場合

Linux では、build-essential パッケージをインストールします。

bash# 必要なパッケージのインストール
sudo apt-get update
sudo apt-get install build-essential python3

これで、gcc、g++、make などの基本的なビルドツールがインストールされます。

ステップ 3: electron-rebuild のインストールと実行

electron-rebuild は、Electron 用に native module を再ビルドする公式ツールです。

electron-rebuild のインストール

開発依存関係として、electron-rebuild をインストールします。

bash# electron-rebuild をインストール
yarn add -D electron-rebuild

インストール後、package.jsondevDependencies に追加されたことを確認してください。

package.json への scripts 追加

自動化のため、package.json に再ビルドスクリプトを追加します。

json{
  "scripts": {
    "rebuild": "electron-rebuild -f -w sqlite3",
    "postinstall": "electron-rebuild"
  }
}

この設定では、以下のような動作になります。

  • rebuild: 特定のモジュール(例:sqlite3)を強制再ビルド
  • postinstall: パッケージインストール後に自動で全モジュールを再ビルド

再ビルドの実行

scripts を追加したら、実際に再ビルドを実行します。

bash# すべての native module を再ビルド
yarn run rebuild

特定のモジュールだけを再ビルドする場合は、以下のようにします。

bash# 特定のモジュールのみ再ビルド(-w オプションで指定)
yarn run electron-rebuild -f -w sqlite3

-f オプションは強制再ビルド、-w オプションは対象モジュールの指定を意味します。

複数モジュールの再ビルド

複数の native module を使用している場合は、カンマ区切りで指定できます。

bash# 複数モジュールの再ビルド
yarn run electron-rebuild -f -w sqlite3,serialport,bcrypt

これにより、指定したモジュールのみが効率的に再ビルドされます。

ステップ 4: node-gyp の設定

electron-rebuild でもうまくいかない場合は、node-gyp の設定を見直します。

Python パスの指定

node-gyp は Python を使用するため、正しいパスを指定する必要があります。

bash# Python のパスを確認
which python3
bash# node-gyp に Python パスを設定
yarn config set python /usr/bin/python3

Windows の場合は、以下のようになります。

bash# Windows での Python パス設定
yarn config set python "C:\Python39\python.exe"

設定後、以下のコマンドで確認できます。

bash# 設定確認
yarn config get python

Visual Studio のバージョン指定 (Windows)

Windows では、使用する Visual Studio のバージョンを明示的に指定することで、ビルドの成功率が上がります。

bash# Visual Studio 2019 を使用する場合
yarn config set msvs_version 2019

Visual Studio 2022 を使用する場合は、以下のようにします。

bash# Visual Studio 2022 を使用する場合
yarn config set msvs_version 2022

ステップ 5: .npmrc ファイルの設定

プロジェクトルートに .npmrc ファイルを作成し、ビルド設定を永続化します。

text# Electron のバージョンを指定
target=18.3.5
# アーキテクチャの指定
arch=x64
# Electron のヘッダー URL
disturl=https://electronjs.org/headers
# ランタイムの指定
runtime=electron
# ビルドを常に実行
build_from_source=true

この設定ファイルにより、毎回コマンドラインオプションを指定する必要がなくなります。各項目の意味は以下の通りです。

#設定項目説明
1target使用する Electron のバージョン
2archターゲットアーキテクチャ(x64, arm64 など)
3disturlElectron のヘッダーファイルのダウンロード先
4runtime実行環境(electron または node)
5build_from_sourceプリビルドバイナリではなくソースからビルド

ステップ 6: electron-builder の設定

アプリケーションのパッケージング時にも native module の扱いに注意が必要です。electron-builder を使用している場合の設定例を見てみましょう。

package.json への electron-builder 設定追加

json{
  "build": {
    "appId": "com.example.app",
    "productName": "MyElectronApp",
    "npmRebuild": true,
    "buildDependenciesFromSource": true
  }
}

重要な設定項目について説明します。

  • npmRebuild: パッケージング前に自動で npm rebuild を実行
  • buildDependenciesFromSource: ソースからビルドを強制

asarUnpack の設定

一部の native module は、asar アーカイブから除外する必要があります。

json{
  "build": {
    "asar": true,
    "asarUnpack": [
      "**/node_modules/sqlite3/**/*",
      "**/node_modules/serialport/**/*"
    ]
  }
}

この設定により、指定したモジュールは asar ファイルに含めず、通常のディレクトリ構造で配置されます。これは、動的にバイナリを読み込むモジュールで必要になることがあります。

具体例

実践例 1: sqlite3 を使用した Electron アプリ

実際のプロジェクトで、sqlite3 モジュールを使用する場合の完全な手順を見ていきましょう。

プロジェクトの初期化

まず、新規プロジェクトを作成します。

bash# プロジェクトディレクトリの作成
mkdir electron-sqlite-app
cd electron-sqlite-app
bash# package.json の初期化
yarn init -y

必要なパッケージのインストール

Electron と関連パッケージをインストールします。

bash# Electron と sqlite3 のインストール
yarn add electron
yarn add sqlite3
bash# 開発用パッケージのインストール
yarn add -D electron-rebuild electron-builder

これで、基本的なパッケージがインストールされました。

package.json の設定

package.json に必要なスクリプトと設定を追加します。

json{
  "name": "electron-sqlite-app",
  "version": "1.0.0",
  "main": "main.js",
  "scripts": {
    "start": "electron .",
    "rebuild": "electron-rebuild -f -w sqlite3",
    "postinstall": "electron-rebuild",
    "build": "electron-builder"
  }
}

main.js をエントリーポイントとして指定し、各種スクリプトを定義しています。

.npmrc ファイルの作成

プロジェクトルートに .npmrc を作成します。

textruntime=electron
target=18.3.5
disturl=https://electronjs.org/headers
build_from_source=true

Electron 18.3.5 を使用する設定になっています。使用する Electron のバージョンに合わせて target を変更してください。

sqlite3 の再ビルド実行

設定が完了したら、sqlite3 を再ビルドします。

bash# sqlite3 の再ビルド
yarn run rebuild

成功すると、以下のようなメッセージが表示されます。

✔ Rebuild Complete

メインプロセスのコード作成

main.js ファイルを作成し、基本的な Electron アプリケーションを実装します。

javascript// Electron モジュールのインポート
const { app, BrowserWindow } = require('electron');
const path = require('path');
javascript// sqlite3 のインポートとデータベース初期化
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('./mydb.sqlite');

ここで sqlite3 を読み込み、データベースファイルを作成しています。

javascript// メインウィンドウの作成関数
function createWindow() {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      nodeIntegration: true,
      contextIsolation: false,
    },
  });

  // HTML ファイルの読み込み
  mainWindow.loadFile('index.html');
}

BrowserWindow を作成し、HTML ファイルを読み込む基本的な設定です。

javascript// アプリケーションの初期化処理
app.whenReady().then(() => {
  // データベーステーブルの作成
  db.run(`
    CREATE TABLE IF NOT EXISTS users (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      name TEXT NOT NULL,
      email TEXT UNIQUE NOT NULL
    )
  `);

  createWindow();
});

アプリ起動時にデータベーステーブルを作成します。

javascript// すべてのウィンドウが閉じられたときの処理
app.on('window-all-closed', () => {
  // データベース接続のクローズ
  db.close((err) => {
    if (err) {
      console.error('Database close error:', err.message);
    }
  });

  if (process.platform !== 'darwin') {
    app.quit();
  }
});

アプリ終了時には、データベース接続を適切にクローズすることが重要です。

アプリケーションの起動テスト

すべての設定が完了したら、アプリケーションを起動してテストします。

bash# アプリケーションの起動
yarn start

エラーなく起動し、データベース操作ができれば成功です。

実践例 2: serialport モジュールのトラブルシューティング

次に、シリアルポート通信を行う serialport モジュールで発生しやすい問題と解決方法を見ていきましょう。

エラーの発生状況

serialport をインストール後、以下のようなエラーが発生したとします。

swiftError: The module '/path/to/node_modules/@serialport/bindings/build/Release/bindings.node'
was compiled against a different Node.js version using
NODE_MODULE_VERSION 93. This version of Node.js requires
NODE_MODULE_VERSION 109.

このエラーは、serialport の内部バインディングが Electron のバージョンと一致していないことを示しています。

解決手順の実行

まず、現在インストールされているモジュールをクリーンアップします。

bash# node_modules の削除
rm -rf node_modules
bash# yarn のキャッシュクリア
yarn cache clean

クリーンアップにより、古いビルド成果物を完全に削除します。

次に、パッケージを再インストールします。

bash# パッケージの再インストール
yarn install
bash# serialport の再ビルド
yarn run electron-rebuild -f -w serialport

serialport は複数のサブパッケージを持つため、特定のビルドオプションが必要になることがあります。

詳細な再ビルドオプションの使用

serialport で問題が続く場合は、より詳細なオプションを指定します。

bash# Electron のバージョンを明示的に指定
yarn run electron-rebuild -f -w serialport \
  --version=18.3.5 \
  --arch=x64

バックスラッシュ(\)は、コマンドを複数行に分けて記述するための記号です。

プラットフォーム固有の問題への対応

macOS で権限エラーが発生する場合は、以下のように対処します。

bash# macOS でのアクセス権限設定
sudo chown -R $(whoami) node_modules
bash# 再度ビルドを実行
yarn run rebuild

権限の問題が解決されたら、通常通りビルドできるようになります。

実践例 3: よくあるエラーパターンと解決法

実際の開発現場で頻繁に遭遇するエラーパターンをまとめました。

パターン 1: Python が見つからない

エラーコード

arduinogyp ERR! find Python
gyp ERR! find Python Python is not set from command line or npm configuration
gyp ERR! find Python Python is not set from environment variable PYTHON
gyp ERR! find Python checking if "python3" can be used
gyp ERR! find Python - "python3" is not in PATH or produced an error

発生条件

  • Python がインストールされていない
  • PATH に Python が含まれていない
  • node-gyp が Python を認識できない

解決方法

ステップ 1: Python のインストール確認

bash# Python のバージョン確認
python3 --version

ステップ 2: PATH の確認と設定

bash# Python のパスを確認(macOS/Linux)
which python3
bash# node-gyp に Python パスを明示的に設定
yarn config set python /usr/bin/python3

ステップ 3: 環境変数の設定(永続化)

macOS/Linux の場合、.bashrc.zshrc に以下を追加します。

bash# .zshrc または .bashrc に追加
export PYTHON=/usr/bin/python3

設定後、ターミナルを再起動するか、以下を実行します。

bash# 設定の再読み込み
source ~/.zshrc

パターン 2: C++ コンパイラが見つからない

エラーコード

arduinogyp ERR! stack Error: Could not find any Visual Studio installation to use
gyp ERR! stack     at VisualStudioFinder.fail
gyp ERR! stack     at VisualStudioFinder.findVisualStudio
gyp ERR! stack     at ChildProcess.<anonymous>

発生条件

  • Visual Studio Build Tools がインストールされていない(Windows)
  • Xcode Command Line Tools がインストールされていない(macOS)
  • build-essential がインストールされていない(Linux)

解決方法(Windows)

ステップ 1: Visual Studio Build Tools のインストール

bash# 管理者権限で実行
yarn global add windows-build-tools

または、Visual Studio Installer から「C++ によるデスクトップ開発」をインストールします。

ステップ 2: Visual Studio のバージョン指定

bash# 使用する Visual Studio のバージョンを指定
yarn config set msvs_version 2019

解決方法(macOS)

ステップ 1: Xcode Command Line Tools のインストール

bash# Command Line Tools のインストール
xcode-select --install

ステップ 2: インストールの確認

bash# インストールパスの確認
xcode-select -p

正しくインストールされていれば、​/​Library​/​Developer​/​CommandLineTools が表示されます。

パターン 3: アーキテクチャの不一致

エラーコード

vbnetError: dlopen(/path/to/module.node, 0x0001):
tried: '/path/to/module.node'
(mach-o file, but is an incompatible architecture
(have 'x86_64', need 'arm64'))

発生条件

  • Apple Silicon (M1/M2) Mac で x86_64 用のバイナリを使用
  • ARM 環境で x86 用のビルド成果物を使用

解決方法

ステップ 1: 現在のアーキテクチャの確認

bash# アーキテクチャの確認
uname -m

arm64 または x86_64 が表示されます。

ステップ 2: 正しいアーキテクチャでの再ビルド

bash# ARM64 用に再ビルド(Apple Silicon の場合)
yarn run electron-rebuild --arch=arm64
bash# x86_64 用に再ビルド(Intel Mac の場合)
yarn run electron-rebuild --arch=x64

ステップ 3: .npmrc でアーキテクチャを固定

texttarget_arch=arm64
runtime=electron
target=18.3.5
disturl=https://electronjs.org/headers

使用する Mac のアーキテクチャに合わせて、target_arch を設定してください。

デバッグのベストプラクティス

トラブルシューティングを効率的に行うためのチェックリストです。

#確認項目コマンド/方法
1Node.js バージョンnode -v
2Electron バージョンyarn list electron
3Python バージョンpython3 --version
4ビルドツールの存在xcode-select -p (macOS)
5アーキテクチャuname -m
6node_modules の状態ls -la node_modules
7.npmrc の設定cat .npmrc
8yarn configyarn config list

これらを順番に確認することで、問題の原因を特定しやすくなります。

まとめ

Electron アプリケーションにおける native module のビルド問題は、初めて遭遇すると非常に複雑に感じられますが、体系的なアプローチで解決できます。

本記事で解説した内容を振り返ってみましょう。

重要なポイント

  1. native module は Electron の Node.js バージョンに合わせて再ビルドが必要です。通常の Node.js 用にビルドされたモジュールは、そのまま使用できません。

  2. electron-rebuild ツールを活用することで、再ビルドプロセスを自動化できます。postinstall スクリプトに設定しておけば、パッケージインストール時に自動実行されますね。

  3. プラットフォームごとに必要なビルドツールが異なるため、開発環境の準備が重要です。macOS では Xcode Command Line Tools、Windows では Visual Studio Build Tools、Linux では build-essential が必要になります。

  4. .npmrc ファイルでビルド設定を永続化すると、毎回コマンドラインオプションを指定する手間が省けます。特に、Electron のバージョンやアーキテクチャの指定は重要です。

  5. エラーメッセージを正確に読み取ることで、問題の原因を素早く特定できます。エラーコードやスタックトレースには、解決のヒントが含まれています。

トラブルシューティングの基本フロー

問題に遭遇したときは、以下の順序で対処してみてください。

  1. 環境の確認(Node.js、Python、ビルドツールのバージョン)
  2. node_modules の削除とキャッシュクリア
  3. パッケージの再インストール
  4. electron-rebuild の実行
  5. エラーメッセージの分析と個別対応

開発効率を上げるヒント

  • package.json に再ビルドスクリプトを追加しておく
  • .npmrc で設定を統一し、チーム全体で共有する
  • プラットフォーム固有の問題は、CI/CD パイプラインで早期発見する
  • よく使う native module は、動作確認済みのバージョンを記録しておく

native module のビルド問題は、一度解決方法を理解すれば、次回からはスムーズに対処できるようになります。本記事が、皆様の Electron 開発における「node-gyp 地獄」からの脱出の一助となれば幸いです。

開発を進める中で新たな問題に遭遇した場合も、今回ご紹介した基本的なアプローチを応用することで、多くのケースに対応できるでしょう。

関連リンク