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 Packager)集成的更多信息,请参阅该项目的自述文件。

¥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 更改了查找开发标头的位置。

    ¥HOME=~/.electron-gyp changes where to find development headers.

  • --target=1.2.3 是 Electron 的版本。

    ¥--target=1.2.3 is the version of Electron.

  • --dist-url=... 指定下载标头的位置。

    ¥--dist-url=... specifies where to download the headers.

  • --arch=x64 表示该模块是为 64 位系统构建的。

    ¥--arch=x64 says the module is built for a 64-bit system.

手动构建 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

    ¥When in doubt, run @electron/rebuild first.

  • 确保原生模块与你的 Electron 应用的目标平台和架构兼容。

    ¥Make sure the native module is compatible with the target platform and architecture for your Electron app.

  • 确保模块的 binding.gyp 中的 win_delay_load_hook 未设置为 false

    ¥Make sure win_delay_load_hook is not set to false in the module's binding.gyp.

  • 升级 Electron 后,通常需要重建模块。

    ¥After you upgrade Electron, you usually need to rebuild the modules.

关于 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 构建的,请确保 win_delay_load_hook 变量在 binding.gyp 文件中设置为 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 链接到 node.lib。如果链接到错误的 node.lib,当你在 Electron 中需要该模块时,你将收到加载时错误。

    ¥you link against node.lib from Electron and not Node. If you link against the wrong node.lib you will get load-time errors when you require the module in Electron.

  • 你包括标志 /DELAYLOAD:node.exe。如果 node.exe 链接未延迟,则延迟加载钩子将不会有机会触发,并且节点符号将无法正确解析。

    ¥you include the flag /DELAYLOAD:node.exe. If the node.exe link is not delayed, then the delay-load hook won't get a chance to fire and the node symbols won't be correctly resolved.

  • win_delay_load_hook.obj 直接链接到最终的 DLL 中。如果钩子是在依赖的 DLL 中设置的,则它不会在正确的时间触发。

    ¥win_delay_load_hook.obj is linked directly into the final DLL. If the hook is set up in a dependent DLL, it won't fire at the right time.

如果你要实现自己的延迟加载钩子,请参阅 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 和 Electron 发布带有预构建二进制文件的原生 Node 模块的方法。

¥prebuild provides a way to publish native Node modules with prebuilt binaries for multiple versions of Node and Electron.

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

¥If the prebuild-powered module provide 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.