@electron/rebuild

repository·main·Indexed 22 days ago

https://github.com/electron/rebuild

A utility designed to rebuild native Node.js modules against the specific version of Electron used in a project to ensure binary compatibility. It provides a CLI and a programmatic rebuild() API, supporting various rebuilding strategies including node-gyp, prebuildify, prebuild-install, and node-pre-gyp. It can be integrated into workflows such as Electron Packager via the afterCopy hook.

Tokens
7.8K
Snippets
17
Records
23
Agent score
77%

What's inside @electron/rebuild

  1. Integrate @electron/rebuild with Electron Packager

    main

    You can integrate @electron/rebuild into your Electron Packager workflow using the afterCopy hook. This ensures native modules are rebuilt after the files are copied to the build path.

    import { packager } from "@electron/packager";
    import { rebuild } from "@electron/rebuild";
    
    packager({
      // … other options
      afterCopy: [
        async ({ buildPath, electronVersion, arch }) => {
          await rebuild({ buildPath, electronVersion, arch });
        },
      ],
      // … other options
    });
  2. Install and use @electron/rebuild via CLI

    main

    Use @electron/rebuild to rebuild native Node.js modules against the specific version of Electron your project uses. This ensures compatibility even if your system Node.js version differs.

    Installation

    Install as a development dependency:

    npm install --save-dev @electron/rebuild

    Running the rebuild

    After installing new npm packages, run the rebuild command:

    macOS/Linux:

    $(npm bin)/electron-rebuild

    Windows:

    .\node_modules\.bin\electron-rebuild.cmd

    Troubleshooting Windows build errors

    If you encounter errors like Could not load the Visual C++ component "VCBuild.exe" on Windows, try running the command through an npm script to ensure the environment is correctly initialized:

    1. Add a script to your package.json:
    "scripts": {
      "rebuild": "electron-rebuild -f -w yourmodule"
    }
    1. Run the script:
    npm run rebuild
    npm install --save-dev @electron/rebuild
  3. How @electron/rebuild uses node-pre-gyp

    main

    When @electron/rebuild detects node-pre-gyp in your project's dependencies, it attempts to use it as a module type to download prebuilt binaries instead of compiling from source.

    Specifically, it performs the following logic:

    1. Detection: It checks for the presence of node-pre-gyp in your dependencies.
    2. Binary Location: It locates the node-pre-gyp binary within your node_modules.
    3. Architecture Check: It inspects existing module binaries. If the architecture of the existing binary differs from the target architecture (this.rebuilder.arch), it triggers a redownload using the --update-binary flag.
    4. Execution: It runs node-pre-gyp reinstall with specific flags to ensure compatibility with Electron, such as --fallback-to-build, --target_arch, --target_platform, and runtime-specific arguments like --runtime=electron and --target=<electron_version>.
  4. Monitor rebuild progress via lifecycle events

    main

    The rebuild function (and the Rebuilder class) provides a lifecycle EventEmitter that allows you to hook into the rebuild process. This is useful for logging or updating UI in build tools.

    Available events:

    • start: Emitted when the rebuild process begins.
    • modules-found: Emitted with an array of paths for native modules detected during the walk.
    • module-found: Emitted with the name of a specific module being processed.
    • module-done: Emitted when a module has finished rebuilding (or was skipped).
    • module-skip: Emitted when a module is skipped (e.g., because it is already built, ignored, or prebuilt).
  5. How Prebuildify module type works

    main

    The Prebuildify module type is used to detect and utilize prebuilt native modules generated by the prebuildify tool. It looks for a prebuilds directory within the module's path and attempts to locate compatible binaries based on the target platform, architecture, and ABI.

    To use this module type, the prebuildify package must be present in your devDependencies.

    When searching for binaries, it prioritizes Node-API modules in the following order:

    1. electron.napi.[extension]
    2. node.napi.[extension]
    3. electron.abi[ABI].[extension]

    Where [extension] is determined by the architecture (e.g., armv8.node for arm64, armv7.node for armv7l, or node for others).

  6. Use the rebuild() API

    main

    The rebuild function can be imported into your build scripts or application code to programmatically rebuild native modules.

    API Signature

    rebuild(options): Promise<void>

    Options

    PropertyTypeDefaultDescription
    buildPathstringRequiredAbsolute path to your app's directory (containing node_modules).
    electronVersionstringRequiredThe version of Electron to rebuild for.
    archstringprocess.archThe architecture to rebuild for.
    extraModulesstring[][]Array of additional modules to rebuild.
    onlyModulesstring[]nullArray of module names to rebuild ONLY. If set, types is ignored.
    forcebooleanfalseForce rebuild regardless of current state.
    headerURLstringhttps://www.electronjs.org/headersURL to download Electron header files from.
    typesstring[]['prod', 'optional']Types of modules to rebuild (prod, dev, optional).
    mode'sequential' | 'parallel'Platform dependentRebuild mode.
    useElectronClangbooleanfalseUse the clang executable used by Electron for compiler compatibility.
    // ESM
    import { rebuild } from "@electron/rebuild";
    
    rebuild({
      buildPath: import.meta.dirname,
      electronVersion: "35.1.5",
    })
      .then(() => console.info("Rebuild Successful"))
      .catch((e) => {
        console.error("Building modules didn't work!");
        console.error(e);
      });
  7. Configure RebuildOptions for @electron/rebuild

    main

    When using the rebuild function or the Rebuilder class, you can provide a RebuildOptions object to control the rebuilding process.

    Core Options

    • buildPath (string): The absolute path to the node_modules directory to rebuild.
    • electronVersion (string): The version of Electron to build against.
    • platform (NodeJS.Platform, optional): Target platform (e.g., 'darwin', 'win32'). Defaults to process.platform. Note: This only affects downloading prebuilt binaries; cross-compilation is not supported.
    • arch (string, optional): Target architecture (e.g., 'x64', 'arm64'). Defaults to process.arch.
    • force (boolean): Force a rebuild of modules regardless of their current build state.
    • debug (boolean): If true, generates a Debug build. Otherwise, a Release build is generated.
    • mode (RebuildMode, optional): Whether to rebuild modules sequential (default) or in parallel.

    Module Selection

    • extraModules (string[], optional): Additional module names to rebuild.
    • onlyModules (string[] | null, optional): Only these specific modules will be rebuilt.
    • ignoreModules (string[], optional): Modules to skip during the process.
    • types (ModuleType[], optional): Types of dependencies to rebuild. Possible values: 'prod', 'dev', 'optional'. Defaults to ['prod', 'optional'].

    Advanced & Experimental Options

    • useCache (boolean, experimental): Enables hash-based caching to speed up local rebuilds.
    • cachePath (string, experimental): Custom path for the cache. Defaults to a .electron-rebuild-cache folder in the user's home directory.
    • buildFromSource (boolean): Skip prebuild downloads and rebuild modules from source.
    • jobs (number, optional): Number of parallel compile jobs for node-gyp (passed via --jobs).
    • forceABI (number, optional): Override the Application Binary Interface (ABI) version. Use this when targeting nightly releases.
    • headerURL (string, optional): URL to download Electron header files from. Defaults to https://www.electronjs.org/headers.
    • useElectronClang (boolean): Use the clang executable used by Electron to guarantee compiler compatibility.
    • projectRootPath (string, optional): Path to the project root (required for npm/yarn workspaces).
  8. Configure the rebuild source URL via environment variables

    main

    If you need to provide a custom header tarball URL for downloading prebuilds, you can use the ELECTRON_REBUILD_DIST_URL environment variable instead of the --dist-url flag.

    export ELECTRON_REBUILD_DIST_URL=https://your-custom-url.com/tarball
  9. CLI arguments for electron-rebuild

    main

    The electron-rebuild CLI allows you to fine-tune the rebuilding process.

    Note on dependency types: By default, only prod and optional dependencies are rebuilt. To include devDependencies, you must explicitly use the --types flag with dev included (e.g., --types prod,optional,dev).

    Note on Dist URL: The --dist-url flag can also be set via the ELECTRON_REBUILD_DIST_URL environment variable. The CLI flag takes precedence.

    Usage: electron-rebuild --version [version] --module-dir [path]
    
    Options:
      -v, --version                The version of Electron to build against [string]
      -f, --force                  Force rebuilding modules, even if we would skip
                                   it otherwise                            [boolean]
      -a, --arch                   Override the target architecture to something
                                   other than your system's                 [string]
      -m, --module-dir             The path to the node_modules directory to rebuild
                                                                            [string]
      -w, --which-module           A specific module to build, or comma separated
                                   list of modules. Modules will only be rebuilt if
                                   they also match the types of dependencies being
                                   rebuilt (see --types).                   [string]
      -o, --only                   Only build specified module, or comma separated
                                   list of modules. All others are ignored. [string]
      -e, --electron-prebuilt-dir  The path to the prebuilt electron module [string]
      -d, --dist-url               Custom header tarball URL [string]
      -t, --types                  The types of dependencies to rebuild.  Comma
                                   separated list of "prod", "dev" and "optional".
                                   Default is "prod,optional"               [string]
      -p, --parallel               Rebuild in parallel, this is enabled by default
                                   on macOS and Linux                        [boolean]
      -s, --sequential             Rebuild modules sequentially, this is enabled by
                                   default on Windows                         [boolean]
      -b, --debug                  Build debug version of modules          [boolean]
      -j, --jobs                   Number of parallel compile jobs node-gyp should
                                   run (passed as node-gyp --jobs). Defaults to
                                   node-gyp's own default.                   [number]
          --prebuild-tag-prefix    GitHub tag prefix passed to prebuild-install.
                                   Default is "v"                           [string]
          --force-abi              Override the ABI version for the version of
                                   Electron you are targeting.              [number]
          --use-electron-clang     Use the clang executable that Electron used when
                                   building its binary. This will guarantee compiler
                                   compatibility                           [boolean]
          --disable-pre-gyp-copy   Disables the pre-gyp copy step          [boolean]
          --build-from-source      Skips prebuild download and rebuilds module from
                                   source.                                   [boolean]
      -h, --help                   Show help                               [boolean]
  10. Locate node_modules directories using searchForNodeModules()

    main

    Use searchForNodeModules to find all node_modules subdirectories while traversing up ancestor directories from a starting directory. The search stops when it reaches the project root or encounters a package.json file.

    import { searchForNodeModules } from '@electron/rebuild/src/search-module';
    
    // Finds all node_modules directories up the directory tree
    const nodeModulesPaths = await searchForNodeModules('/path/to/cwd');
  11. Locate a specific module using searchForModule()

    main

    Use searchForModule to find all instances of a specific Node module (including scoped modules) by traversing up the directory tree from a starting directory. The search stops when it reaches the project root or encounters a package.json file.

    import { searchForModule } from '@electron/rebuild/src/search-module';
    
    // Finds all instances of 'module-name' in node_modules up the directory tree
    const modulePaths = await searchForModule('/path/to/cwd', 'module-name');