Skip to content

Commit c223866

Browse files
authored
fix: dependency path is undefined (#9013)
fix #9011 Under the two `package.json` framework, if there are no `node_modules` in the `app` directory and `npmRebuild` is set to `false`, dependencies will not be reinstalled. As a result, `npm list` will return empty. In this case, we should attempt to retrieve the `node_modules` using the `projectDir`, which can resolve this issue. Using `getProjectRootPath` directly from `electron/rebuild` is not accurate because it recursively searches upward level by level and returns the first match it finds. If I set the `app` directory outside the `project dir`, such as in another directory, the result returned by `getProjectRootPath` in `electron/rebuild` will be incorrect. Therefore, the `projectDir` should be passed in directly instead of searching upward level by level. https://github.com/electron/rebuild/blob/ff1ec40f82ca64e014079b246053f039b3cf4f23/src/search-module.ts#L76-L86 ![image](https://github.com/user-attachments/assets/3bd72083-4a4c-453d-84a5-811070c66f6f)
1 parent 5c1a82c commit c223866

File tree

7 files changed

+5200
-17
lines changed

7 files changed

+5200
-17
lines changed

.changeset/tall-geese-invite.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"app-builder-lib": patch
3+
"electron-builder": patch
4+
---
5+
6+
fix: dependency path is undefined

packages/app-builder-lib/src/packager.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -600,12 +600,16 @@ export class Packager {
600600
if (config.buildDependenciesFromSource === true && platform.nodeName !== process.platform) {
601601
log.info({ reason: "platform is different and buildDependenciesFromSource is set to true" }, "skipped dependencies rebuild")
602602
} else {
603-
await installOrRebuild(config, this.appDir, {
604-
frameworkInfo,
605-
platform: platform.nodeName,
606-
arch: Arch[arch],
607-
productionDeps: this.getNodeDependencyInfo(null, false) as Lazy<Array<NodeModuleDirInfo>>,
608-
})
603+
await installOrRebuild(
604+
config,
605+
{ appDir: this.appDir, projectDir: this.projectDir },
606+
{
607+
frameworkInfo,
608+
platform: platform.nodeName,
609+
arch: Arch[arch],
610+
productionDeps: this.getNodeDependencyInfo(null, false) as Lazy<Array<NodeModuleDirInfo>>,
611+
}
612+
)
609613
}
610614
}
611615
}

packages/app-builder-lib/src/util/appFileCopier.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,18 @@ function validateFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {
178178

179179
/** @internal */
180180
export async function computeNodeModuleFileSets(platformPackager: PlatformPackager<any>, mainMatcher: FileMatcher): Promise<Array<ResolvedFileSet>> {
181-
const deps = await getNodeModules(platformPackager.info.appDir)
181+
const projectDir = platformPackager.info.projectDir
182+
const appDir = platformPackager.info.appDir
183+
184+
let deps = await getNodeModules(appDir)
185+
if (projectDir !== appDir && deps.length === 0) {
186+
const packageJson = require(path.join(appDir, "package.json"))
187+
if (Object.keys(packageJson.dependencies || {}).length > 0) {
188+
log.debug({ projectDir, appDir }, "no node_modules in app dir, trying to find in project dir")
189+
deps = await getNodeModules(projectDir)
190+
}
191+
}
192+
182193
log.debug({ nodeModules: deps }, "collected node modules")
183194

184195
const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager)

packages/app-builder-lib/src/util/yarn.ts

+12-9
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as electronRebuild from "@electron/rebuild"
2-
import { getProjectRootPath } from "@electron/rebuild/lib/search-module"
32
import { RebuildMode } from "@electron/rebuild/lib/types"
43
import { asArray, log, spawn } from "builder-util"
54
import { pathExists } from "fs-extra"
@@ -12,7 +11,7 @@ import { PM, detect, getPackageManagerVersion } from "../node-module-collector"
1211
import { NodeModuleDirInfo } from "./packageDependencies"
1312
import { rebuild as remoteRebuild } from "./rebuild/rebuild"
1413

15-
export async function installOrRebuild(config: Configuration, appDir: string, options: RebuildOptions, forceInstall = false) {
14+
export async function installOrRebuild(config: Configuration, { appDir, projectDir }: DirectoryPaths, options: RebuildOptions, forceInstall = false) {
1615
const effectiveOptions: RebuildOptions = {
1716
buildFromSource: config.buildDependenciesFromSource === true,
1817
additionalArgs: asArray(config.npmArgs),
@@ -29,9 +28,9 @@ export async function installOrRebuild(config: Configuration, appDir: string, op
2928
}
3029

3130
if (forceInstall || !isDependenciesInstalled) {
32-
await installDependencies(config, appDir, effectiveOptions)
31+
await installDependencies(config, { appDir, projectDir }, effectiveOptions)
3332
} else {
34-
await rebuild(config, appDir, effectiveOptions)
33+
await rebuild(config, { appDir, projectDir }, effectiveOptions)
3534
}
3635
}
3736

@@ -91,12 +90,11 @@ async function checkYarnBerry(pm: PM) {
9190
return version.split(".")[0] >= "2"
9291
}
9392

94-
async function installDependencies(config: Configuration, appDir: string, options: RebuildOptions): Promise<any> {
93+
async function installDependencies(config: Configuration, { appDir, projectDir }: DirectoryPaths, options: RebuildOptions): Promise<any> {
9594
const platform = options.platform || process.platform
9695
const arch = options.arch || process.arch
9796
const additionalArgs = options.additionalArgs
9897

99-
const projectDir = await getProjectRootPath(appDir)
10098
const pm = await detect({ cwd: projectDir })
10199
log.info({ pm, platform, arch, projectDir, appDir }, `installing production dependencies`)
102100
const execArgs = ["install"]
@@ -123,7 +121,7 @@ async function installDependencies(config: Configuration, appDir: string, option
123121

124122
// Some native dependencies no longer use `install` hook for building their native module, (yarn 3+ removed implicit link of `install` and `rebuild` steps)
125123
// https://github.com/electron-userland/electron-builder/issues/8024
126-
return rebuild(config, appDir, options)
124+
return rebuild(config, { appDir, projectDir }, options)
127125
}
128126

129127
export async function nodeGypRebuild(platform: NodeJS.Platform, arch: string, frameworkInfo: DesktopFrameworkInfo) {
@@ -170,8 +168,13 @@ export interface RebuildOptions {
170168
additionalArgs?: Array<string> | null
171169
}
172170

171+
export interface DirectoryPaths {
172+
appDir: string
173+
projectDir: string
174+
}
175+
173176
/** @internal */
174-
export async function rebuild(config: Configuration, appDir: string, options: RebuildOptions) {
177+
export async function rebuild(config: Configuration, { appDir, projectDir }: DirectoryPaths, options: RebuildOptions) {
175178
const configuration = {
176179
dependencies: await options.productionDeps.value,
177180
nodeExecPath: process.execPath,
@@ -205,7 +208,7 @@ export async function rebuild(config: Configuration, appDir: string, options: Re
205208
arch,
206209
platform,
207210
buildFromSource,
208-
projectRootPath: await getProjectRootPath(appDir),
211+
projectRootPath: projectDir,
209212
mode: (config.nativeRebuilder as RebuildMode) || "sequential",
210213
disablePreGypCopy: true,
211214
}

packages/electron-builder/src/cli/install-app-deps.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,10 @@ export async function installAppDeps(args: any) {
5757
// if two package.json — force full install (user wants to install/update app deps in addition to dev)
5858
await installOrRebuild(
5959
config,
60-
appDir,
60+
{
61+
appDir,
62+
projectDir,
63+
},
6164
{
6265
frameworkInfo: { version, useCustomDist: true },
6366
platform: args.platform,

0 commit comments

Comments
 (0)