原生 Node 模組
Electron 支援原生 Node.js 模組,但由於 Electron 的 應用程式二進位制介面 (ABI) 與給定的 Node.js 二進位制檔案不同(由於諸如使用 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.nodejs.com.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.nodejs.com.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 會安裝一個 延遲載入鉤子,該鉤子在載入原生模組時觸發,並將 node.dll 引用重定向到使用載入的可執行檔案,而不是在庫搜尋路徑中查詢 node.dll(這將找不到任何內容)。因此,在 Electron 4.x 及更高版本中,載入原生模組需要 'win_delay_load_hook': 'true'。
如果您收到類似 Module did not self-register 或 The specified procedure could not be found 的錯誤,這可能意味著您嘗試使用的模組沒有正確包含延遲載入鉤子。如果模組使用 node-gyp 構建,請確保 win_delay_load_hook 變數在 binding.gyp 檔案中設定為 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"
特別是,重要的是
- 您連結的是來自 Electron 而不是 Node 的
node.lib。如果您連結到錯誤的node.lib,您將在 Electron 中 require 模組時遇到載入時錯誤。 - 您包含標誌
/DELAYLOAD:node.exe。如果未延遲node.exe連結,則延遲載入鉤子將無法觸發,並且節點符號將無法正確解析。 win_delay_load_hook.obj直接連結到最終的 DLL 中。如果鉤子設定在依賴 DLL 中,它將不會在正確的時間觸發。
有關示例延遲載入鉤子,請參閱 node-gyp,如果您正在實現自己的鉤子。
依賴 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 環境變數。