Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Migrate to electron-rebuild for handling native dependencies #7196

Merged
merged 4 commits into from
Oct 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/shy-lizards-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"app-builder-lib": major
"electron-builder": major
---

fix: Migrate to electron-rebuild for handling native dependencies
1 change: 1 addition & 0 deletions packages/app-builder-lib/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"ejs": "^3.1.7",
"electron-osx-sign": "^0.6.0",
"electron-publish": "workspace:*",
"electron-rebuild": "^3.2.9",
"form-data": "^4.0.0",
"fs-extra": "^10.1.0",
"hosted-git-info": "^4.1.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/packager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,7 @@ export class Packager {
const frameworkInfo = { version: this.framework.version, useCustomDist: true }
const config = this.config
if (config.nodeGypRebuild === true) {
await nodeGypRebuild(platform.nodeName, Arch[arch], frameworkInfo)
await nodeGypRebuild(Arch[arch])
}

if (config.npmRebuild === false) {
Expand Down
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/util/packageMetadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function checkMetadata(metadata: Metadata, devMetadata: any | null, appPa
const devDependencies = (metadata as any).devDependencies
if (devDependencies != null && "electron-rebuild" in devDependencies) {
log.info(
'electron-rebuild not required if you use electron-builder, please consider to remove excess dependency from devDependencies\n\nTo ensure your native dependencies are always matched electron version, simply add script `"postinstall": "electron-builder install-app-deps" to your `package.json`'
'electron-rebuild is already incorporated into electron-builder, please consider to remove excess dependency from devDependencies\n\nTo ensure your native dependencies are always matched electron version, simply add script `"postinstall": "electron-builder install-app-deps" to your `package.json`'
)
}

Expand Down
60 changes: 22 additions & 38 deletions packages/app-builder-lib/src/util/yarn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,28 @@ import { Lazy } from "lazy-val"
import { homedir } from "os"
import * as path from "path"
import { Configuration } from "../configuration"
import { executeAppBuilderAndWriteJson } from "./appBuilder"
import { NodeModuleDirInfo } from "./packageDependencies"
import * as electronRebuild from "electron-rebuild"
import { getElectronVersion } from "../electron/electronVersion"

export async function installOrRebuild(config: Configuration, appDir: string, options: RebuildOptions, forceInstall = false) {
const effectiveOptions = {
buildFromSource: config.buildDependenciesFromSource === true,
additionalArgs: asArray(config.npmArgs),
...options,
}
let isDependenciesInstalled = false

for (const fileOrDir of ["node_modules", ".pnp.js"]) {
if (await pathExists(path.join(appDir, fileOrDir))) {
isDependenciesInstalled = true

break
}
}

if (forceInstall || !isDependenciesInstalled) {
const effectiveOptions: RebuildOptions = {
buildFromSource: config.buildDependenciesFromSource === true,
additionalArgs: asArray(config.npmArgs),
...options,
}
await installDependencies(appDir, effectiveOptions)
} else {
await rebuild(appDir, effectiveOptions)
await rebuild(appDir, config.buildDependenciesFromSource === true, options.arch)
}
}

Expand Down Expand Up @@ -119,23 +118,8 @@ function installDependencies(appDir: string, options: RebuildOptions): Promise<a
})
}

export async function nodeGypRebuild(platform: NodeJS.Platform, arch: string, frameworkInfo: DesktopFrameworkInfo) {
log.info({ platform, arch }, "executing node-gyp rebuild")
// this script must be used only for electron
const nodeGyp = `node-gyp${process.platform === "win32" ? ".cmd" : ""}`
const args = ["rebuild"]
// headers of old Electron versions do not have a valid config.gypi file
// and --force-process-config must be passed to node-gyp >= 8.4.0 to
// correctly build modules for them.
// see also https://github.com/nodejs/node-gyp/pull/2497
const [major, minor] = frameworkInfo.version
.split(".")
.slice(0, 2)
.map(n => parseInt(n, 10))
if (major <= 13 || (major == 14 && minor <= 1) || (major == 15 && minor <= 2)) {
args.push("--force-process-config")
}
await spawn(nodeGyp, args, { env: getGypEnv(frameworkInfo, platform, arch, true) })
export async function nodeGypRebuild(arch: string) {
return rebuild(process.cwd(), false, arch)
}

function getPackageToolPath() {
Expand Down Expand Up @@ -164,17 +148,17 @@ export interface RebuildOptions {
}

/** @internal */
export async function rebuild(appDir: string, options: RebuildOptions) {
const configuration: any = {
dependencies: await options.productionDeps!.value,
nodeExecPath: process.execPath,
platform: options.platform || process.platform,
arch: options.arch || process.arch,
additionalArgs: options.additionalArgs,
execPath: process.env.npm_execpath || process.env.NPM_CLI_JS,
buildFromSource: options.buildFromSource === true,
export async function rebuild(appDir: string, buildFromSource: boolean, arch = process.arch) {
log.info({ appDir, arch }, "executing electron-rebuild")
const options: electronRebuild.RebuildOptions = {
buildPath: appDir,
electronVersion: await getElectronVersion(appDir),
arch,
force: true,
debug: log.isDebugEnabled,
}

const env = getGypEnv(options.frameworkInfo, configuration.platform, configuration.arch, options.buildFromSource === true)
await executeAppBuilderAndWriteJson(["rebuild-node-modules"], configuration, { env, cwd: appDir })
if (buildFromSource) {
options.prebuildTagPrefix = "totally-not-a-real-prefix-to-force-rebuild"
}
return electronRebuild.rebuild(options)
}
4 changes: 1 addition & 3 deletions packages/electron-builder/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import { InvalidConfigurationError, log } from "builder-util"
import * as chalk from "chalk"
import { getElectronVersion } from "app-builder-lib/out/electron/electronVersion"
import { readJson } from "fs-extra"
import * as isCi from "is-ci"
import * as path from "path"
Expand Down Expand Up @@ -76,7 +75,6 @@ async function checkIsOutdated() {
}

async function rebuildAppNativeCode(args: any) {
const projectDir = process.cwd()
// this script must be used only for electron
return nodeGypRebuild(args.platform, args.arch, { version: await getElectronVersion(projectDir), useCustomDist: true })
return nodeGypRebuild(args.arch)
}