原生 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 建置的,請確保 win_delay_load_hook
變數在 binding.gyp
檔案中設定為 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 的
node.lib
。如果您連結到錯誤的node.lib
,當您在 Electron 中需要該模組時,將會收到載入時錯誤。 - 您包含旗標
/DELAYLOAD:node.exe
。如果node.exe
連結未延遲,則延遲載入 Hook 將沒有機會觸發,並且 Node 符號將無法正確解析。 win_delay_load_hook.obj
直接連結到最終的 DLL 中。如果在相依 DLL 中設定了 Hook,則它不會在正確的時間觸發。
如果您要實作自己的延遲載入 Hook,請參閱 node-gyp
以取得範例延遲載入 Hook。
依賴 prebuild
的模組
prebuild
提供了一種發布原生 Node 模組的方法,其中包含適用於多個 Node 和 Electron 版本的預建二進制檔。
如果由 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
環境變數。