原生 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-register
或 The 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"
特別是,以下事項很重要
- 您連結的應是Electron 的
node.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-source
和 npm_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
環境變數。