What is prebuildify?
The prebuildify npm package is used to prebuild native Node.js modules for multiple platforms and architectures. It simplifies the process of distributing prebuilt binaries, which can save users from having to compile the module from source.
What are prebuildify's main functionalities?
Prebuild Native Modules
This feature allows you to prebuild native modules for specified Node.js versions, platforms, and architectures. The code sample demonstrates how to prebuild a module for Node.js versions 14.17.0 and 16.0.0 on a Windows 64-bit platform.
const prebuildify = require('prebuildify');
prebuildify({
targets: ['node-14.17.0', 'node-16.0.0'],
platform: 'win32',
arch: 'x64'
});
Generate Prebuilds for Multiple Platforms
This feature allows you to generate prebuilds for multiple platforms. The code sample shows how to prebuild a module for Node.js versions 14.17.0 and 16.0.0 on Windows, Linux, and macOS platforms for 64-bit architecture.
const prebuildify = require('prebuildify');
prebuildify({
targets: ['node-14.17.0', 'node-16.0.0'],
platforms: ['win32', 'linux', 'darwin'],
arch: 'x64'
});
Custom Prebuild Scripts
This feature allows you to define custom scripts to run before and after the prebuild process. The code sample demonstrates how to add preinstall and postinstall scripts to the prebuild process.
const prebuildify = require('prebuildify');
prebuildify({
targets: ['node-14.17.0', 'node-16.0.0'],
platform: 'win32',
arch: 'x64',
scripts: {
preinstall: 'echo Preinstall script',
postinstall: 'echo Postinstall script'
}
});
Other packages similar to prebuildify
node-pre-gyp
node-pre-gyp is a tool that makes it easy to publish and install Node.js C++ addons from binaries. It provides a way to package and distribute prebuilt binaries, similar to prebuildify, but with additional features like S3 hosting and versioning.
prebuild
prebuild is another tool for prebuilding binaries for Node.js native modules. It offers similar functionality to prebuildify, allowing developers to prebuild and distribute binaries for multiple platforms and architectures.
cmake-js
cmake-js is a tool that simplifies the process of building native Node.js modules using CMake. While it does not directly provide prebuilding capabilities, it can be used in conjunction with other tools to achieve similar results.
prebuildify
Create and package prebuilds for native modules
npm install -g prebuildify
With prebuildify
, all prebuilt binaries are shipped inside the package that is published to npm, which means there's no need for a separate download step like you find in prebuild
. The irony of this approach is that it is faster to download all prebuilt binaries for every platform when they are bundled than it is to download a single prebuilt binary as an install script.
Always use prebuildify --@mafintosh
Usage
Note. Options, environment variables and prebuild names have changed in prebuildify@3
. Please see the documentation below. You will also need to upgrade node-gyp-build
.
First go to your native module and make a bunch of prebuilds.
cd your-native-module
prebuildify --all --strip
ls prebuilds
If your module is using the new node core N-API, then you can prebuild using the --napi
flag:
prebuildify --napi
Then only remaining thing you need to do now is make your module use a prebuild if one exists
for the platform/runtime you are using.
Use node-gyp-build to do this.
npm install --save node-gyp-build
Then add node-gyp-build
as an install script to your module's package.json
:
{
"name": "your-native-module",
"scripts": {
"install": "node-gyp-build"
}
}
The install script will check if a compatible prebuild is bundled. If so it does nothing. If not it will run node-gyp rebuild
to produce a build.
This means that if the user using your module has disabled install scripts your module will still work (!) as long as a compatible prebuild is bundled.
When loading your native binding from your index.js
you should use node-gyp-build
as will to make sure to get the right binding
var binding = require('node-gyp-build')(__dirname)
module.exports = binding
An added benefit of this approach is that your native modules will work across multiple node and electron versions without having the user
need to reinstall or recompile them - as long as you produce prebuilds for all versions. With N-API you only have to produce prebuilds for every runtime.
When publishing your module to npm remember to include the ./prebuilds
folder.
That's it! Happy native hacking.
Options
Options can be provided via (in order of precedence) the programmatic API, the CLI or environment variables. The environment variables, whether they are defined on the outside or not, are also made available to subprocesses. For example, prebuildify --arch arm64 --strip
sets PREBUILD_ARCH=arm64 PREBUILD_STRIP=1
.
CLI | Environment | Default | Description |
---|
--target -t | - | Depends. | One or more targets* |
--all -a | - | false | Build all known targets. Takes precedence over --target . |
--napi | - | false | Make N-API build(s). Targets default to latest node which is compatible with Electron > 3, which can be overridden with --target . Note: --all should be avoided for now because it includes targets that don't support N-API. |
--electron-compat | - | false | Make two N-API builds, one for node and one for Electron. Useful if you support Electron <= 3. |
--debug | - | false | Make Debug build(s) |
--arch | PREBUILD_ARCH | os.arch() | Target architecture** |
--platform | PREBUILD_PLATFORM | os.platform() | Target platform** |
--uv | PREBUILD_UV | From process.versions.uv | Major libuv version*** |
--armv | PREBUILD_ARMV | Auto-detected on ARM machines | Numeric ARM version (e.g. 7)*** |
--libc | PREBUILD_LIBC | glibc , musl on Alpine | libc flavor*** |
--tag-uv | - | false | Tag prebuild with uv *** |
--tag-armv | - | false | Tag prebuild with armv *** |
--tag-libc | - | false | Tag prebuild with libc *** |
--preinstall | - | - | Command to run before build |
--postinstall | - | - | Command to run after build |
--shell | PREBUILD_SHELL | 'sh' on Android | Shell to spawn commands in |
--artifacts | - | - | Directory containing additional files. Recursively copied into prebuild directory. |
--strip | PREBUILD_STRIP | false | Enable stripping |
--strip-bin | PREBUILD_STRIP_BIN | 'strip' | Custom strip binary |
--node-gyp | PREBUILD_NODE_GYP | 'node-gyp(.cmd)' | Custom node-gyp binary**** |
--quiet | - | false | Suppress node-gyp output |
--cwd | - | process.cwd() | Working directory |
* A target takes the form of (runtime@)?version
, where runtime
defaults to 'node'
. For example: -t 8.14.0 -t electron@3.0.0
. At least one of --target
, --all
or --napi
must be specified.
** The arch
option is passed to node-gyp
as --target-arch
. Target architecture and platform (what you're building for) default to the host platform and architecture (what you're building on). They can be overridden for cross-compilation, in which case you'll likely also want to override the strip binary. The platform and architecture dictate the output folder. For example on Linux x64 prebuilds end up in prebuilds/linux-x64
.
*** The filenames of prebuilds are composed of tags which by default include runtime and either napi
or abi<version>
. For example: electron.abi40.node
. To make more specific prebuilds (for node-gyp-build
to select) you can add additional tags. Values for these tags are auto-detected. For example, --napi --tag-uv --tag-armv
could result in a build called node.napi.uv1.armv8.node
if the host machine has an ARM architecture. When cross-compiling you can override values either through the relevant option (--tag-armv --armv 7
) or the tag (--tag-armv 7
) as a shortcut. They're separate because you may want to build a certain version without tagging the prebuild as such, assuming that the prebuild is forward compatible.
**** To enable the use of forks like nodejs-mobile-gyp
.
License
MIT