原生 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://electronjs.org/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://electronjs.org/headers
HOME=~/.electron-gyp更改查找开发头文件的位置。--target=1.2.3是 Electron 的版本。--dist-url=...指定下载头文件的位置。--arch=x64表示该模块为 64 位系统构建。
手动为 Electron 的自定义构建版本构建¶
要将原生 Node 模块编译为与某个公开版本不匹配的 Electron 自定义构建版本,请指示 npm 使用你自定义构建中捆绑的 Node 版本。
故障排除¶
如果你安装了原生模块但发现它无法工作,需要检查以下内容:
- 如有疑问,请先运行
@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 构建的,请确保 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"
特别是,以下事项非常重要:
- 你要链接来自 Electron 的
node.lib,而不是 Node 的node.lib。如果你链接了错误的node.lib,在 Electron 中 require 该模块时会出现加载时错误。 - 你要包含
/DELAYLOAD:node.exe标志。如果node.exe链接未被延迟,则延迟加载钩子将没有机会触发,node 符号也无法正确解析。 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 的方式安装模块,你需要向 npm 传递 --build-from-source,或设置 npm_config_build_from_source 环境变量。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 el/electron