docs: clean up the native module tutorial (#17624)

This commit is contained in:
Mark Lee 2019-04-24 10:32:37 -07:00 committed by Shelley Vohr
parent 4588fc2232
commit aed0b1ee54

View file

@ -1,25 +1,57 @@
# Using Native Node Modules # Using Native Node Modules
The native Node modules are supported by Electron, but since Electron is very Native Node modules are supported by Electron, but since Electron is very
likely to use a different V8 version from the Node binary installed in your likely to use a different V8 version from the Node binary installed on your
system, you have to manually specify the location of Electron's headers when system, the modules you use will need to be recompiled for Electron. Otherwise,
building native modules. you will get the following class of error when you try to run your app:
```sh
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 ## How to install native modules
Three ways to install native modules: There are several different ways to install native modules:
### Installing modules and rebuilding for Electron
You can install modules like other Node projects, and then rebuild the modules
for Electron with the [`electron-rebuild`][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.
For example, to install `electron-rebuild` and then rebuild modules with it
via the command line:
```sh
npm install --save-dev electron-rebuild
# Every time you run "npm install", run this:
./node_modules/.bin/electron-rebuild
# On Windows if you have trouble, try:
.\node_modules\.bin\electron-rebuild.cmd
```
For more information on usage and integration with other tools, consult the
project's README.
### Using `npm` ### Using `npm`
By setting a few environment variables, you can use `npm` to install modules By setting a few environment variables, you can use `npm` to install modules
directly. directly.
An example of installing all dependencies for Electron: For example, to install all dependencies for Electron:
```sh ```sh
# Electron's version. # Electron's version.
export npm_config_target=1.2.3 export npm_config_target=1.2.3
# The architecture of Electron, can be ia32 or x64. # The architecture of Electron, see https://electronjs.org/docs/tutorial/support#supported-platforms
# for supported architectures.
export npm_config_arch=x64 export npm_config_arch=x64
export npm_config_target_arch=x64 export npm_config_target_arch=x64
# Download headers for Electron. # Download headers for Electron.
@ -32,25 +64,6 @@ export npm_config_build_from_source=true
HOME=~/.electron-gyp npm install HOME=~/.electron-gyp npm install
``` ```
### Installing modules and rebuilding for Electron
You can also choose to install modules like other Node projects, and then
rebuild the modules for Electron with the [`electron-rebuild`][electron-rebuild]
package. This module can get the version of Electron and handle the manual steps
of downloading headers and building native modules for your app.
An example of installing `electron-rebuild` and then rebuild modules with it:
```sh
npm install --save-dev electron-rebuild
# Every time you run "npm install", run this:
./node_modules/.bin/electron-rebuild
# On Windows if you have trouble, try:
.\node_modules\.bin\electron-rebuild.cmd
```
### Manually building for Electron ### Manually building for Electron
If you are a developer developing a native module and want to test it against If you are a developer developing a native module and want to test it against
@ -62,44 +75,44 @@ cd /path-to-module/
HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://atom.io/download/electron HOME=~/.electron-gyp node-gyp rebuild --target=1.2.3 --arch=x64 --dist-url=https://atom.io/download/electron
``` ```
The `HOME=~/.electron-gyp` changes where to find development headers. The * `HOME=~/.electron-gyp` changes where to find development headers.
`--target=1.2.3` is version of Electron. The `--dist-url=...` specifies * `--target=1.2.3` is the version of Electron.
where to download the headers. The `--arch=x64` says the module is built for * `--dist-url=...` specifies where to download the headers.
64bit system. * `--arch=x64` says the module is built for a 64-bit system.
### Manually building for a custom build of Electron ### Manually building for a custom build of Electron
To compile native Node addons against a custom build of Electron that doesn't 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 match a public release, instruct `npm` to use the version of Node you have bundled
with your custom build. with your custom build.
```sh ```sh
npm rebuild --nodedir=$HOME/.../path/to/electron/vendor/node npm rebuild --nodedir=/path/to/electron/vendor/node
``` ```
## Troubleshooting ## Troubleshooting
If you installed a native module and found it was not working, you need to check If you installed a native module and found it was not working, you need to check
following things: the following things:
* The architecture of the module has to match Electron's architecture (ia32 or x64).
* `win_delay_load_hook` is not set to `false` in the module's `binding.gyp`.
* After you upgrade Electron, you usually need to rebuild the modules.
* When in doubt, run `electron-rebuild` first. * When in doubt, run `electron-rebuild` first.
* Make sure the native module is compatible with the target platform and
architecture for your Electron app.
* Make sure `win_delay_load_hook` is not set to `false` in the module's `binding.gyp`.
* After you upgrade Electron, you usually need to rebuild the modules.
### A note about `win_delay_load_hook` ### A note about `win_delay_load_hook`
On Windows, by default, node-gyp links native modules against `node.dll`. 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 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 Electron 4.x. In exported by `electron.exe`, and there is no `node.dll`. In order to load native
order to load native modules on Windows, node-gyp installs a [delay-load modules on Windows, `node-gyp` installs a [delay-load
hook](https://msdn.microsoft.com/en-us/library/z9h1h6ty.aspx) that triggers hook](https://msdn.microsoft.com/en-us/library/z9h1h6ty.aspx) that triggers
when the native module is loaded, and redirects the `node.dll` reference to use 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 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, 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. `'win_delay_load_hook': 'true'` is required to load native modules.
If you get an error like `Module did not self-register`, or `The specified 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 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 did not correctly include the delay-load hook. If the module is built with
@ -125,12 +138,13 @@ In particular, it's important that:
- `win_delay_load_hook.obj` is linked directly into the final DLL. If the hook - `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. is set up in a dependent DLL, it won't fire at the right time.
See [node-gyp](https://github.com/nodejs/node-gyp/blob/e2401e1395bef1d3c8acec268b42dc5fb71c4a38/src/win_delay_load_hook.cc) for an example delay-load hook if you're implementing your own. See [`node-gyp`](https://github.com/nodejs/node-gyp/blob/e2401e1395bef1d3c8acec268b42dc5fb71c4a38/src/win_delay_load_hook.cc)
for an example delay-load hook if you're implementing your own.
## Modules that rely on `prebuild` ## Modules that rely on `prebuild`
[`prebuild`](https://github.com/mafintosh/prebuild) provides a way to [`prebuild`](https://github.com/prebuild/prebuild) provides a way to publish
publish native Node modules with prebuilt binaries for multiple versions of Node native Node modules with prebuilt binaries for multiple versions of Node
and Electron. and Electron.
If modules provide binaries for the usage in Electron, make sure to omit If modules provide binaries for the usage in Electron, make sure to omit
@ -143,13 +157,13 @@ The [`node-pre-gyp` tool][node-pre-gyp] provides a way to deploy native Node
modules with prebuilt binaries, and many popular modules are using it. modules with prebuilt binaries, and many popular modules are using it.
Usually those modules work fine under Electron, but sometimes when Electron uses Usually those modules work fine under Electron, but sometimes when Electron uses
a newer version of V8 than Node, and there are ABI changes, bad things may a newer version of V8 than Node and/or there are ABI changes, bad things may
happen. So in general it is recommended to always build native modules from happen. So in general, it is recommended to always build native modules from
source code. source code. `electron-rebuild` handles this for you automatically.
If you are following the `npm` way of installing modules, then this is done If you are following the `npm` way of installing modules, then this is done
by default, if not, you have to pass `--build-from-source` to `npm`, or set the by default, if not, you have to pass `--build-from-source` to `npm`, or set the
`npm_config_build_from_source` environment variable. `npm_config_build_from_source` environment variable.
[electron-rebuild]: https://github.com/paulcbetts/electron-rebuild [electron-rebuild]: https://github.com/electron/electron-rebuild
[node-pre-gyp]: https://github.com/mapbox/node-pre-gyp [node-pre-gyp]: https://github.com/mapbox/node-pre-gyp