app-builder-lib
Version:
electron-builder lib
122 lines (121 loc) • 5.92 kB
TypeScript
import { TmpDir } from "builder-util";
import { Lazy } from "lazy-val";
import { ModuleManager } from "./moduleManager";
import { PM } from "./packageManager";
import type { Dependency, DependencyGraph, NodeModuleInfo, PackageJson } from "./types";
export declare abstract class NodeModulesCollector<ProdDepType extends Dependency<ProdDepType, OptionalDepType>, OptionalDepType> {
protected readonly rootDir: string;
private readonly tempDirManager;
private readonly nodeModules;
protected readonly allDependencies: Map<string, ProdDepType>;
protected readonly productionGraph: DependencyGraph;
protected readonly cache: ModuleManager;
protected isHoisted: Lazy<boolean>;
constructor(rootDir: string, tempDirManager: TmpDir);
/**
* Retrieves and collects all Node.js modules for a given package.
*
* This method orchestrates the entire module collection process by:
* 1. Fetching the dependency tree from the package manager
* 2. Collecting all dependencies recursively
* 3. Extracting workspace references if applicable
* 4. Building a production dependency graph
* 5. Hoisting the dependencies to their final locations
* 6. Resolving and returning module information
*/
getNodeModules({ packageName }: {
packageName: string;
}): Promise<{
nodeModules: NodeModuleInfo[];
logSummary: ModuleManager["logSummary"];
}>;
abstract readonly installOptions: {
manager: PM;
lockfile: string;
};
protected abstract getArgs(): string[];
protected abstract extractProductionDependencyGraph(tree: Dependency<ProdDepType, OptionalDepType>, dependencyId: string): Promise<void>;
protected abstract collectAllDependencies(tree: Dependency<ProdDepType, OptionalDepType>, appPackageName: string): Promise<void>;
/**
* Retrieves the dependency tree from the package manager.
*
* Executes the appropriate package manager command to fetch the dependency tree and writes
* the output to a temporary file. Includes retry logic to handle transient failures such as
* incomplete JSON output or missing files. Will retry up to 1 time with exponential backoff.
*/
protected getDependenciesTree(pm: PM): Promise<ProdDepType>;
/**
* Parses the dependencies tree from shell command output.
*
**/
protected parseDependenciesTree(shellOutput: string): ProdDepType | Promise<ProdDepType>;
protected extractJsonFromPollutedOutput<T>(shellOutput: string): T;
protected cacheKey(pkg: Pick<ProdDepType, "name" | "version" | "path">): string;
protected normalizePackageVersion(key: string, pkg: ProdDepType): {
id: string;
pkgOverride: ProdDepType & {
name: string;
};
};
/**
* Determines if a given dependency is a production dependency of a package.
*
* Checks both the dependencies and optionalDependencies of a package to see if
* the specified dependency name is listed.
*
* @param depName - The name of the dependency to check
* @param pkg - The package to search for the dependency in
* @returns True if the dependency is found in either dependencies or optionalDependencies, false otherwise
*/
protected isProdDependency(depName: string, pkg: ProdDepType): boolean;
protected locatePackageWithVersion(depTree: Pick<ProdDepType, "name" | "version" | "path">): Promise<{
packageDir: string;
packageJson: PackageJson;
} | null>;
/**
* Parses a dependency identifier string into name and version components.
*
* Handles both scoped packages (e.g., "@scope/pkg@1.2.3") and regular packages (e.g., "pkg@1.2.3").
* If the identifier is malformed or cannot be parsed, defaults to treating the entire string as
* the package name with an "unknown" version.
*/
protected parseNameVersion(identifier: string): {
name: string;
version: string;
};
/**
* Retrieves the dependency tree and handles workspace package self-references.
*
* If the project is a workspace project, this method removes the root package's self-reference
* from the dependency tree to avoid circular dependencies. It promotes the root package's
* direct dependencies to the top level of the tree.
*
* @param tree - The original dependency tree
* @param packageName - The name of the package to check for and remove from the tree
* @returns The extracted dependency subtree
*/
protected getTreeFromWorkspaces(tree: ProdDepType, packageName: string): ProdDepType;
private transformToHoisterTree;
private _getNodeModules;
asyncExec(command: string, args: string[], cwd?: string): Promise<{
stdout: string | undefined;
stderr: string | undefined;
}>;
/**
* Executes a command and streams its output to a file.
*
* Spawns a child process to execute the specified command with arguments, capturing stdout
* to a file. Handles Windows-specific quirks by wrapping .cmd files in a temporary .bat file
* when necessary. Enables corepack strict mode by default but allows process.env overrides.
*
* Special handling for `npm list` exit code 1, which is expected in certain scenarios.
*
* @param command - The command to execute
* @param args - Array of command-line arguments
* @param cwd - The working directory to execute the command in
* @param tempOutputFile - The path to the temporary file where stdout will be written
* @returns Promise that resolves when the command completes successfully or rejects if it fails
* @throws {Error} If the child process spawn fails or exits with a non-zero code
*/
streamCollectorCommandToFile(command: string, args: string[], cwd: string, tempOutputFile: string): Promise<void>;
}