原生 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.js.cn/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.js.cn/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 构建的,请确保 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 的
node.lib
。如果您链接到错误的node.lib
,则在 Electron 中需要模块时会出现加载时错误。 - 您包含标志
/DELAYLOAD:node.exe
。如果node.exe
链接未延迟,则延迟加载钩子将没有机会触发,并且节点符号将无法正确解析。 win_delay_load_hook.obj
直接链接到最终的 DLL 中。如果钩子是在依赖 DLL 中设置的,则它不会在正确的时间触发。
如果您要实现自己的延迟加载钩子,请参阅 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
环境变量。