Electron Node 原生模块
原生Node.js模块由Electron支持,但由于Electron具有与给定Node.js不同的 应用二进制接口 (ABI)(由于使用Chromium的 BoringSL 而不是 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 版本,为你的应用自动完成下载 headers、重新编译原生模块等步骤。 如果您正在使用 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)集成的更多信息,请参阅项目的自述文件。
通过 npm 安装
只要设置一些系统环境变量,你就可以通过 npm
直接安装原生模块。
例如,要安装所有Electron的依赖:
# Electron 的版本。
export npm_config_target=1.2.3
# Electron的目标架构, 可用的架构列表请参见
# https://electronjs.org/docs/tutorial/support#supported-platforms
export npm_config_arch=x64
export npm_config_target_arch=x64
# 下载 Electron 的 headers。
export npm_config_disturl=https://electronjs.org/headers
# 告诉 node-pre-gyp 我们是在为 Electron 生成模块。
export npm_config_runtime=electron
# 告诉 node-pre-gyp 从源代码构建模块。
export npm_config_build_from_source=true
# 安装所有依赖,并缓存到 ~/.electron-gyp。
HOME=~/.electron-gyp npm install
为 Electron 手动编译
如果你是一个原生模块的开发人员,想在 Electron 中进行测试, 你可能要手动编译 Electron 模块。 你可以 使用 node-gyp
直接编译:
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=...
设置了 Electron 的 headers 的下载地址。--arch=x64
设置了该模块为适配64位操作系统而编译。
为Electron的自定义编译手动编译
如果是为一个与公共发行版不匹配的Electron自定义版本编译原生Node模块,需要让npm
使用你的Electron自定义版本所对应的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和更高的版本中,原生模块需要的symbols由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 模块。
如果预构建模块提供二进制文件供 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 环境变量。
更多建议: