跳至主要內容

原生 Node 模組

Electron 支援原生 Node.js 模組,但由於 Electron 與指定的 Node.js 二進制檔具有不同的應用程式二進制介面 (ABI)(例如,由於使用 Chromium 的 BoringSSL 而非 OpenSSL),因此您使用的原生模組需要針對 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

# Every time you run "npm install", run this:
./node_modules/.bin/electron-rebuild

# If you have trouble on Windows, try:
.\node_modules\.bin\electron-rebuild.cmd

如需有關使用方式以及與其他工具 (例如 Electron Packager) 整合的更多資訊,請參閱專案的 README。

使用 npm

透過設定一些環境變數,您可以使用 npm 直接安裝模組。

例如,安裝 Electron 的所有相依性

# Electron's version.
export npm_config_target=1.2.3
# The architecture of your machine
export npm_config_arch=x64
export npm_config_target_arch=x64
# Download headers for Electron.
export npm_config_disturl=https://electron.dev.org.tw/headers
# Tell node-pre-gyp that we are building for Electron.
export npm_config_runtime=electron
# Tell node-pre-gyp to build module from source code.
export npm_config_build_from_source=true
# Install all dependencies, and store cache to ~/.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://electron.dev.org.tw/headers
  • HOME=~/.electron-gyp 會變更尋找開發標頭的位置。
  • --target=1.2.3 是 Electron 的版本。
  • --dist-url=... 指定下載標頭的位置。
  • --arch=x64 表示模組是針對 64 位元系統建置的。

手動針對自訂版本的 Electron 建置

若要針對與公開發行版本不符的 Electron 自訂版本編譯原生 Node 模組,請指示 npm 使用您與自訂版本捆綁在一起的 Node 版本。

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

疑難排解

如果您安裝原生模組並發現它無法運作,您需要檢查以下事項

  • 如有疑問,請先執行 @electron/rebuild
  • 請確認原生模組與您的 Electron 應用程式的目標平台和架構相容。
  • 請確認在模組的 binding.gyp 中,win_delay_load_hook 未設定為 false
  • 在您升級 Electron 之後,通常需要重新建置模組。

關於 win_delay_load_hook 的注意事項

在 Windows 上,依預設,node-gyp 會將原生模組連結到 node.dll。然而,在 Electron 4.x 和更高版本中,原生模組所需的符號由 electron.exe 匯出,而且沒有 node.dll。為了在 Windows 上載入原生模組,node-gyp 會安裝延遲載入 Hook,該 Hook 會在載入原生模組時觸發,並將 node.dll 參考重新導向,以使用載入的可執行檔,而不是在程式庫搜尋路徑中尋找 node.dll(這會找不到任何內容)。因此,在 Electron 4.x 和更高版本上,必須使用 'win_delay_load_hook': 'true' 才能載入原生模組。

如果您收到類似 Module did not self-registerThe specified procedure could not be found 的錯誤,這可能表示您嘗試使用的模組未正確包含延遲載入 Hook。如果模組是使用 node-gyp 建置的,請確保在 binding.gyp 檔案中,win_delay_load_hook 變數設定為 true,並且未在任何地方被覆寫。如果模組是使用另一個系統建置的,您需要確保您在主要 .node 檔案中安裝延遲載入 Hook 的情況下進行建置。您的 link.exe 調用應如下所示

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

特別是,以下事項很重要

  • 您連結的應是Electronnode.lib 而非 Node 的。如果您連結錯誤的 node.lib,當您在 Electron 中要求模組時,會收到載入時錯誤。
  • 您應包含旗標 /DELAYLOAD:node.exe。如果未延遲 node.exe 連結,則延遲載入 Hook 將無法觸發,且 Node 符號將無法正確解析。
  • win_delay_load_hook.obj 直接連結到最終 DLL 中。如果 Hook 是在相依 DLL 中設定的,則它不會在正確的時間觸發。

如果您要實作自己的延遲載入 Hook,請參閱node-gyp 以取得範例。

依賴 prebuild 的模組

prebuild 提供了一種方式,可以使用針對多個 Node 和 Electron 版本預先建置的二進制檔發布原生 Node 模組。

如果由 prebuild 驅動的模組提供在 Electron 中使用的二進制檔,請務必省略 --build-from-sourcenpm_config_build_from_source 環境變數,以便充分利用預先建置的二進制檔。

依賴 node-pre-gyp 的模組

node-pre-gyp 工具提供了一種方式,可以使用預先建置的二進制檔部署原生 Node 模組,而且許多熱門模組都在使用它。

有時這些模組在 Electron 下可以正常運作,但是當沒有 Electron 專用的二進制檔時,您需要從原始程式碼建置。因此,建議針對這些模組使用 @electron/rebuild

如果您遵循 npm 安裝模組的方式,您需要將 --build-from-source 傳遞給 npm,或設定 npm_config_build_from_source 環境變數。