メインコンテンツへ飛ぶ

ネイティブ Node モジュール

Electron ではネイティブ Node.js モジュールがサポートされていますが、Electron は (OpenSSL ではなく Chromium の BoringSSL を使用するなどの違いにより) 指定の Node.js バイナリと異なる アプリケーションバイナリインターフェイス (ABI) であるため、使用するネイティブモジュールを Electron 向けに再コンパイルする必要があります。 そうしなければ、以下の類のエラーが実行しようとしたときに発生します。

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

ネイティブモジュールのインストール方法

ネイティブモジュールをインストールするにはいくつかの異なる方法があります。

モジュールをインストールして Electron をリビルド

他の Node プロジェクト同様にモジュールをインストールしてから、@electron/rebuild パッケージで Electron 向けにモジュールを再ビルドします。 このモジュールは自動で Electron のバージョンを取得でき、ヘッダのダウンロードやアプリ向けにネイティブモジュールを再ビルドする手動の手順を処理できます。 Electron Forge を使用している場合、このツールは開発モードでも頒布物の作成でも自動で使用されます。

例えば、スタンドアローンの @electron/rebuild ツールをインストールして、コマンドラインからモジュールを再ビルドするには、以下のようにします。

npm install --save-dev @electron/rebuild

# "npm install" を実行するごとに、こちらを実行します。
./node_modules/.bin/electron-rebuild

# Windows で問題が発生する場合はこちらをお試しください。
.\node_modules\.bin\electron-rebuild.cmd

Electron Packager のような他ツールとの統合や使い方の詳細は、当該プロジェクトの README を参照してください。

npm を使用

いくつかの環境変数を設定することにより、モジュールを直接インストールするのに npm を使用できます。

例として、以下のように Electron 向けにすべての依存関係をインストールします。

# Electronのバージョン
export npm_config_target=1.2.3
# マシンのアーキテクチャ
export npm_config_arch=x64
export npm_config_target_arch=x64
# Electron のヘッダーをダウンロードします。
export npm_config_disturl=https://electronjs.org/headers
# node-pre-gyp にElectronのビルドであることを知らせる
export npm_config_runtime=electron
# node-pre-gypにソースコードからのビルドであることを知らせる
export npm_config_build_from_source=true
# すべての依存をインストールし、キャッシュを~/.electron-gypに保存する
HOME=~/.electron-gyp npm install

Electron の手動ビルド

もしあなたがネイティブモジュールの開発者でElectronでの動作を検証したいのであれば、Electron用にモジュールを手動で再構築したいことと思います。 node-gypを使用することで、モジュールをElectron用にビルドできます。

cd /path-to-module/
HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://electronjs.org/headers
  • HOME=~/.electron-gyp は開発用のヘッダーを探す場所によって変わります。
  • --target=1.2.3 は Electron のバージョンです。
  • --dist-url=... はヘッダをダウンロードする場所を指定します。
  • --arch=x64 はモジュールを 64bit システム向けにビルドします。

Electron のカスタムビルドを手動ビルド

公開されているリリースと一致しない Electron のカスタムビルドに対してネイティブの Node モジュールをコンパイルするには、カスタムビルドにバンドルされている Node のバージョンを使用するように npm に指示します。

npm rebuild --nodedir=/path/to/src/out/Default/gen/node_headers

トラブルシューティング

もしネイティブモジュールがインストールされていてもうまく動いていないと気づいた場合は、下記のことを確認してみてください。

  • 何かおかしいと思ったら、まず@electron/rebuildを走らせてみてください。
  • ネイティブモジュールが Electron アプリのターゲットプラットフォームおよびアーキテクチャと互換性があることを確認してください。
  • モジュールの binding.gyp 内の win_delay_load_hookfalse にセットされていないことを確認してください。
  • Electron のアップグレード後は、モジュールの再ビルドが必要になります。

win_delay_load_hook についての注釈

Windows のデフォルトでは、node-gypnode.dll に対してネイティブモジュールをリンクします。 しかし Electron 4.x 以降では、ネイティブモジュールで必要とされるシンボルは electron.exe によってエクスポートされ、node.dll は存在しません。 Windows にネイティブモジュールをロードするために、node-gyp はネイティブモジュールがロードされたときにトリガーされる delay-load-hook をインストールします。これはライブラリの (何も出てこない) 検索パスで node.dll を探す代わりに、ロード可能な実行可能ファイルを使用するように node.dll 参照をリダイレクトします。 そのため、Electron 4.x 以降でネイティブモジュールをロードするには 'win_delay_load_hook': 'true' が必要です。

モジュールが自己登録されなかった指定されたプロシージャが見つかりませんでした のようなエラーが得られた場合は、使用しようとしているモジュールが見つからないことを意味しているかもしれません。遅延読み込みフックを正しくインクルードしてください。 モジュールが node-gyp でビルドされている場合、binding.gyp ファイルで win_delay_load_hook 変数が true に設定されておらず、どこかで上書きされていないことを確認します。 モジュールが別のシステムでビルドされている場合は、メインの .node ファイルにインストールされている遅延読み込みフックを使用してビルドする必要があります。 link.exe の呼び出しは以下ようにしなければなりません。

 link.exe /OUT:"foo.node" "...\node.lib" delayimp.lib /DELAYLOAD:node.exe /DLL
"my_addon.obj" "win_delay_load_hook.obj"

特に、次のことが重要です。

  • Node ではなく Electronnode.lib に対してリンクします。 間違った node.lib に対してリンクすると、Electron のモジュールが必要になったときにロード時エラーが発生します。
  • /DELAYLOAD:node.exe フラグをインクルードします。 node.exe のリンクが遅延されていない場合、遅延読み込みフックが起動する機会がなく、Node のシンボルは正しく解決されません。
  • win_delay_load_hook.obj は、最終的な DLL に直接リンクされます。 依存 DLL にフックが設定されていると、正しいタイミングで起動しません。

遅延ロードフックを独自で実装する例については node-gyp を参照してください。

prebuildを使用したモジュール

prebuild は、ネイティブの Node モジュールを複数の Node と Electron のバージョン向けに、ビルド済みバイナリとともに公開する方法を提供します。

prebuild を搭載したモジュールが Electron 向けのバイナリを提供している場合、ビルド済みバイナリを最大限に活用するために --build-from-sourcenpm_config_build_from_source 環境変数は省略してください。

node-pre-gypを使用したモジュール

node-pre-gypは、ビルド済みのバイナリを含んだネイティブNodeモジュールを展開する方法を提供します。多くの人気のモジュールがこのツールを使用しています。

これらのモジュールが Electron でも正常に動作することはありますが、Electron 固有のバイナリがない場合はソースからビルドする必要があります。 このため、これらのモジュールには @electron/rebuild の使用を推奨します。

npm でモジュールをインストールする場合は、--build-from-sourcenpm に渡すか npm_config_build_from_source 環境変数を設定する必要があります。