Skip to main content

原生 Node 模块

🌐 Native Node Modules

Electron 支持原生 Node.js 模块,但由于 Electron 与给定的 Node.js 二进制文件具有不同的 应用二进制接口(ABI)(由于使用 Chromium 的 BoringSSL 而不是 OpenSSL 等差异),你使用的原生模块需要为 Electron 重新编译。否则,当你尝试运行应用时,会出现以下类型的错误:

🌐 Native Node.js modules are supported by Electron, but since Electron has a different application binary interface (ABI) from a given Node.js binary (due to differences such as using Chromium's BoringSSL instead of OpenSSL), the native modules you use will need to be recompiled for Electron. Otherwise, you will get the following class of error when you try to run your app:

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`).

如何安装原生模块

🌐 How to install native modules

有几种不同的方法来安装原生模块:

🌐 There are several different ways to install native modules:

安装模块并重建 Electron

🌐 Installing modules and rebuilding for Electron

你可以像其他 Node 项目一样安装模块,然后使用 @electron/rebuild 包为 Electron 重新构建模块。这个模块可以自动确定 Electron 的版本,并处理为你的应用下载头文件和重新构建本地模块的手动步骤。如果你使用的是 Electron Forge,这个工具会在开发模式和制作可分发文件时自动使用。

🌐 You can install modules like other Node projects, and then rebuild the modules for Electron with the @electron/rebuild package. This module can automatically determine the version of Electron and handle the manual steps of downloading headers and rebuilding native modules for your app. If you are using Electron Forge, this tool is used automatically in both development mode and when making distributables.

例如,要安装独立的 @electron/rebuild 工具,然后通过命令行使用它重建模块:

🌐 For example, to install the standalone @electron/rebuild tool and then rebuild modules with it via the command line:

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 打包工具)的集成的更多信息,请查阅项目的 README。

🌐 For more information on usage and integration with other tools such as Electron Packager, consult the project's README.

使用 npm

🌐 Using npm

通过设置几个环境变量,你可以使用 npm 直接安装模块。

🌐 By setting a few environment variables, you can use npm to install modules directly.

例如,要安装 Electron 的所有依赖:

🌐 For example, to install all dependencies for 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.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

🌐 Manually building for Electron

如果你是开发原生模块的开发者,并且想要在 Electron 上测试它,你可能需要手动为 Electron 重新构建该模块。你可以直接使用 node-gyp 为 Electron 构建:

🌐 If you are a developer developing a native module and want to test it against Electron, you might want to rebuild the module for Electron manually. You can use node-gyp directly to build for Electron:

cd /path-to-module/
HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://electron.nodejs.cn/headers
  • HOME=~/.electron-gyp 更改了开发头文件的位置。
  • --target=1.2.3 是 Electron 的版本。
  • --dist-url=... 指定了下载头文件的位置。
  • --arch=x64 说明该模块是为 64 位系统构建的。

手动构建 Electron 的自定义构建

🌐 Manually building for a custom build of Electron

要针对与公开发行版本不匹配的自定义 Electron 构建编译原生 Node 模块,请指示 npm 使用你随自定义构建附带的 Node 版本。

🌐 To compile native Node modules against a custom build of Electron that doesn't match a public release, instruct npm to use the version of Node you have bundled with your custom build.

npm rebuild --nodedir=/path/to/src/out/Default/gen/node_headers

故障排除

🌐 Troubleshooting

如果你安装了本地模块但发现它无法工作,你需要检查以下内容:

🌐 If you installed a native module and found it was not working, you need to check the following things:

  • 有疑问时,先运行 @electron/rebuild
  • 确保本地模块与你的 Electron 应用的目标平台和架构兼容。
  • 确保模块的 binding.gypwin_delay_load_hook 没有被设置为 false
  • 升级 Electron 后,通常需要重建模块。

win_delay_load_hook 的说明

🌐 A note about 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'

🌐 On Windows, by default, node-gyp links native modules against node.dll. However, in Electron 4.x and higher, the symbols needed by native modules are exported by electron.exe, and there is no node.dll. In order to load native modules on Windows, node-gyp installs a delay-load hook that triggers when the native module is loaded, and redirects the node.dll reference to use the loading executable instead of looking for node.dll in the library search path (which would turn up nothing). As such, on Electron 4.x and higher, 'win_delay_load_hook': 'true' is required to load native modules.

如果你遇到类似 Module did not self-registerThe specified procedure could not be found 的错误,这可能意味着你尝试使用的模块没有正确包含延迟加载钩子。如果该模块是用 node-gyp 构建的,请确保在 binding.gyp 文件中将 win_delay_load_hook 变量设置为 true,并且没有在其他地方被覆盖。如果该模块是用其他系统构建的,你需要确保在主 .node 文件中安装了延迟加载钩子。你的 link.exe 调用应该如下所示:

🌐 If you get an error like Module did not self-register, or The specified procedure could not be found, it may mean that the module you're trying to use did not correctly include the delay-load hook. If the module is built with node-gyp, ensure that the win_delay_load_hook variable is set to true in the binding.gyp file, and isn't getting overridden anywhere. If the module is built with another system, you'll need to ensure that you build with a delay-load hook installed in the main .node file. Your link.exe invocation should look like this:

 link.exe /OUT:"foo.node" "...\node.lib" delayimp.lib /DELAYLOAD:node.exe /DLL
"my_addon.obj" "win_delay_load_hook.obj"

特别重要的是:

🌐 In particular, it's important that:

  • 你在 Electron 中链接 node.lib 而不是 Node。如果你链接了错误的 node.lib,在 Electron 中 require 该模块时会出现加载时错误。
  • 你需要包含标志 /DELAYLOAD:node.exe。如果 node.exe 链接没有延迟,那么延迟加载钩子将没有机会触发,节点符号也无法被正确解析。
  • win_delay_load_hook.obj 直接链接到最终的 DLL。如果钩子设置在一个依赖的 DLL 中,它不会在正确的时间触发。

请参见 node-gyp
如果你自己实现的话,可参考示例延迟加载钩子。

🌐 See node-gyp for an example delay-load hook if you're implementing your own.

依赖 prebuild 的模块

🌐 Modules that rely on prebuild

prebuild 提供了一种方法,可以发布带有预构建二进制文件的原生 Node 模块,支持多个版本的 Node 和 Electron。

如果 prebuild 驱动的模块提供用于 Electron 的二进制文件,请确保省略 --build-from-sourcenpm_config_build_from_source 环境变量,以充分利用预构建的二进制文件。

🌐 If the prebuild-powered module provides binaries for the usage in Electron, make sure to omit --build-from-source and the npm_config_build_from_source environment variable in order to take full advantage of the prebuilt binaries.

依赖 node-pre-gyp 的模块

🌐 Modules that rely on node-pre-gyp

node-pre-gyp 工具 提供了一种使用预构建二进制文件部署原生 Node 模块的方法,许多流行的模块都在使用它。

🌐 The node-pre-gyp tool provides a way to deploy native Node modules with prebuilt binaries, and many popular modules are using it.

有时这些模块在 Electron 下可以正常工作,但当没有 Electron 特定的二进制文件可用时,你需要从源码构建。 因此,建议对这些模块使用 @electron/rebuild

🌐 Sometimes those modules work fine under Electron, but when there are no Electron-specific binaries available, you'll need to build from source. Because of this, it is recommended to use @electron/rebuild for these modules.

如果你正在按照 npm 的方式安装模块,你需要将 --build-from-source 传递给 npm,或者设置 npm_config_build_from_source 环境变量。

🌐 If you are following the npm way of installing modules, you'll need to pass --build-from-source to npm, or set the npm_config_build_from_source environment variable.