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

feat: switch app-builder-bin to node-module-collector to get all production node modules #8571

Open
wants to merge 112 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
112 commits
Select commit Hold shift + click to select a range
8a34240
switch app-builder-bin to node-module-collector
Oct 4, 2024
f438899
fix ut
Oct 4, 2024
8523bfd
fix ut
Oct 4, 2024
5748dff
fix ut
Oct 4, 2024
150f031
delete ut
Oct 4, 2024
3c38a9e
fix ut
Oct 4, 2024
4e10883
fix ut
Oct 4, 2024
4ea2d53
fix ut
Oct 4, 2024
257b603
update ut
Oct 4, 2024
601bef9
update node modules collector
Oct 4, 2024
2b051a0
fix ut
Oct 4, 2024
b0ef651
update gitinore
Oct 4, 2024
c9c4071
update
Oct 4, 2024
352f08e
update yarn.lock
Oct 4, 2024
f7d91c6
update gitinogre
Oct 4, 2024
2453a15
fix ut
Oct 4, 2024
6823a87
update
Oct 4, 2024
aafd1be
fix ut
Oct 4, 2024
59aa878
fix ut
beyondkmp Oct 4, 2024
c571825
fix ut
Oct 4, 2024
24dbf44
use detect
Oct 5, 2024
1b8cc02
format code
Oct 5, 2024
98021d1
format code
Oct 5, 2024
5bff81b
fix ut
Oct 5, 2024
6da8b0a
fix ut
Oct 5, 2024
69e827a
update to 1.1.4
Oct 5, 2024
accaf6a
fix others submodule filter
beyondkmp Oct 6, 2024
fdb9dd0
add ut
Oct 6, 2024
4f0d78a
format code
Oct 6, 2024
14efc3a
format code
Oct 6, 2024
aca68c2
fix ut
Oct 6, 2024
8b1e1e2
format code
Oct 6, 2024
8bf110d
fix ut
Oct 6, 2024
32d6156
fix ut
Oct 6, 2024
a22668e
add excludeNodMoules
Oct 6, 2024
40df716
fix ut
Oct 6, 2024
5a2e5c5
fix ut
Oct 6, 2024
9d363a8
fix ut
Oct 6, 2024
ceef74c
fix ut
Oct 6, 2024
861f234
add ut
Oct 6, 2024
e2c7981
fix ut
Oct 6, 2024
e39e6d8
add ut
Oct 6, 2024
127857d
Merge branch 'master' into nodeModulesCollector
Oct 6, 2024
97cdc2d
Merge branch 'excludeNodemoudles' into nodeModulesCollector
Oct 6, 2024
e053855
revert some changes
Oct 6, 2024
2a968f9
delete the obsolete snapshot
Oct 6, 2024
56a9d1e
Merge branch 'master' into nodeModulesCollector
Oct 7, 2024
0a31869
madd node-module-collector
beyondkmp Oct 8, 2024
09cdecd
update lock file
beyondkmp Oct 8, 2024
1227c00
format code
beyondkmp Oct 8, 2024
600958c
format code
beyondkmp Oct 8, 2024
ce21b41
format code
beyondkmp Oct 8, 2024
42bafe1
format code
beyondkmp Oct 8, 2024
f30f7a4
format code
beyondkmp Oct 8, 2024
6956efc
format code
beyondkmp Oct 8, 2024
29c5d01
fix comments
beyondkmp Oct 9, 2024
81db133
fix ut
beyondkmp Oct 9, 2024
fcbe203
update ut
beyondkmp Oct 9, 2024
b6b7540
fix ut
beyondkmp Oct 9, 2024
8715743
fix ut
beyondkmp Oct 9, 2024
94af9fb
format code
beyondkmp Oct 9, 2024
aca36e1
format code
beyondkmp Oct 9, 2024
ce2dfb5
update ignore
beyondkmp Oct 9, 2024
b2b72bf
update ignore
beyondkmp Oct 9, 2024
38ba984
update yarn.lock
beyondkmp Oct 9, 2024
d6377ff
update yarn.lock
beyondkmp Oct 9, 2024
4d42331
update yarn.lock
beyondkmp Oct 9, 2024
6c2469d
fix ut
beyondkmp Oct 9, 2024
34e8f2e
format code
beyondkmp Oct 10, 2024
cb9a8e3
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 10, 2024
d691e60
delete filter
beyondkmp Oct 10, 2024
37e467f
format code
beyondkmp Oct 10, 2024
b9c85e0
add ut
beyondkmp Oct 10, 2024
f3cb216
fix ut
beyondkmp Oct 10, 2024
7bdeb9d
format code
beyondkmp Oct 10, 2024
7b58b83
fix ut
beyondkmp Oct 10, 2024
b0db426
udpate snap
beyondkmp Oct 10, 2024
43e0c96
add ut
beyondkmp Oct 10, 2024
5368fa3
update snapshot
beyondkmp Oct 10, 2024
4d6f786
add ut
beyondkmp Oct 10, 2024
fb5e01e
add comments
beyondkmp Oct 10, 2024
1039ed0
update node version
beyondkmp Oct 10, 2024
9d06f58
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 10, 2024
4804709
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 10, 2024
8f582c1
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 11, 2024
457c2e5
fix ut
beyondkmp Oct 11, 2024
d2e2de7
add ut for hoist
beyondkmp Oct 12, 2024
e6f3b59
add comments
beyondkmp Oct 12, 2024
7c37814
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 12, 2024
b57ffc8
fix ut
beyondkmp Oct 12, 2024
72dc559
format code
beyondkmp Oct 12, 2024
7d37e19
format code
beyondkmp Oct 12, 2024
d50c66d
update readme
beyondkmp Oct 12, 2024
b4d620d
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 14, 2024
6a1ef9b
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 15, 2024
c42b429
fix lint
beyondkmp Oct 15, 2024
e01bc6f
fix npm list error
beyondkmp Oct 15, 2024
875af7c
format code
beyondkmp Oct 15, 2024
61fb295
format code
beyondkmp Oct 15, 2024
f85abe1
format code
beyondkmp Oct 15, 2024
fe15c95
fix ut
beyondkmp Oct 15, 2024
3899607
fix ut
beyondkmp Oct 15, 2024
be11d50
format code
beyondkmp Oct 15, 2024
0dd953f
fix ut
beyondkmp Oct 15, 2024
6d919e9
fix ut
beyondkmp Oct 15, 2024
641eb43
fix yarn error
beyondkmp Oct 16, 2024
f844771
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 16, 2024
1ea244d
fix comments
beyondkmp Oct 24, 2024
2dee313
fix https://github.com/npm/npm/issues/17624
beyondkmp Oct 24, 2024
0595127
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 24, 2024
1f58fd4
delete log.filepath
beyondkmp Oct 29, 2024
d02d442
Merge branch 'master' into nodeModulesCollectorNew
beyondkmp Oct 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix comments
  • Loading branch information
beyondkmp committed Oct 24, 2024
commit 1ea244df8ad00513c2c0412fa2834ac0b13b8a74
6 changes: 3 additions & 3 deletions packages/app-builder-lib/src/node-module-collector/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { NpmNodeModulesCollector } from "./npmNodeModulesCollector"
import { PnpmNodeModulesCollector } from "./pnpmNodeModulesCollector"
import { YarnNodeModulesCollector } from "./yarnNodeModulesCollector"
import { detect, PM, getNpmVersion } from "./packageManager"
import { detect, PM, getPackageManagerVersion } from "./packageManager"
import { NodeModuleInfo } from "./types"
import { log } from "builder-util"

Expand All @@ -15,7 +15,7 @@ async function getCollectorByPackageManager(rootDir: string) {
case "yarn":
return new YarnNodeModulesCollector(rootDir)
default:
log.warn({ rootDir }, `Cannot detect lock file to determine node_modules structure. Assuming plain structure.`)
log.filePath(rootDir)
beyondkmp marked this conversation as resolved.
Show resolved Hide resolved
return new NpmNodeModulesCollector(rootDir)
}
}
Expand All @@ -25,4 +25,4 @@ export async function getNodeModules(rootDir: string): Promise<NodeModuleInfo[]>
return collector.getNodeModules()
}

export { detect, getNpmVersion, PM }
export { detect, getPackageManagerVersion, PM }
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ import { hoist, type HoisterTree, type HoisterResult } from "./hoist"
import * as path from "path"
import * as fs from "fs"
import { NodeModuleInfo, DependencyTree, DependencyGraph } from "./types"
import { log } from "builder-util"
import { exec, log } from "builder-util"

export abstract class NodeModulesCollector {
private nodeModules: NodeModuleInfo[]
protected rootDir: string
protected dependencyPathMap: Map<string, string>

constructor(rootDir: string) {
constructor(private readonly rootDir: string) {
this.dependencyPathMap = new Map()
this.nodeModules = []
this.rootDir = rootDir
}

private transToHoisterTree(obj: DependencyGraph, key: string = `.`, nodes: Map<string, HoisterTree> = new Map()): HoisterTree {
Expand Down Expand Up @@ -43,13 +41,13 @@ export abstract class NodeModulesCollector {
} else {
return filePath
}
} catch (error) {
log.error({ filePath, error }, "Error resolving path")
} catch (error: any) {
log.debug({ message: error.message || error.stack }, "error resolving path")
return filePath
}
}

public TransToDependencyGraph(tree: DependencyTree): DependencyGraph {
public convertToDependencyGraph(tree: DependencyTree): DependencyGraph {
const result: DependencyGraph = { ".": {} }

const flatten = (node: DependencyTree, parentKey = ".") => {
Expand All @@ -75,20 +73,36 @@ export abstract class NodeModulesCollector {
return result
}

abstract getDependenciesTree(): DependencyTree
abstract getPMCommand(): string
abstract getCommand(): string
abstract getArgs(): string[]

protected async getDependenciesTree(): Promise<DependencyTree> {
const command = this.getCommand()
const args = this.getArgs()
const dependencies = await exec(command, args, {
cwd: this.rootDir,
})
const dependencyTree: DependencyTree | DependencyTree[] = JSON.parse(dependencies)
return Array.isArray(dependencyTree) ? dependencyTree[0] : dependencyTree
}

private _getNodeModules(dependencies: Set<HoisterResult>, result: NodeModuleInfo[]) {
if (dependencies.size === 0) return
if (dependencies.size === 0) {
return
}

for (const d of dependencies.values()) {
const reference = [...d.references][0]
const p = this.dependencyPathMap.get(`${d.name}@${reference}`)
const node = {
if (p === undefined) {
log.debug({ name: d.name, reference }, "cannot find path for dependency")
continue
}
const node: NodeModuleInfo = {
name: d.name,
version: reference,
dir: p,
} as NodeModuleInfo
}
result.push(node)
if (d.dependencies.size > 0) {
node["dependencies"] = []
Expand All @@ -109,10 +123,10 @@ export abstract class NodeModulesCollector {
return tree
}

public getNodeModules(): NodeModuleInfo[] {
const tree = this.getDependenciesTree()
public async getNodeModules(): Promise<NodeModuleInfo[]> {
const tree = await this.getDependenciesTree()
const realTree = this.getTreeFromWorkspaces(tree)
const dependencyGraph = this.TransToDependencyGraph(realTree)
const dependencyGraph = this.convertToDependencyGraph(realTree)
const hoisterResult = hoist(this.transToHoisterTree(dependencyGraph), { check: true })
this._getNodeModules(hoisterResult.dependencies, this.nodeModules)
return this.nodeModules
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { execSync } from "child_process"
import { NodeModulesCollector } from "./nodeModulesCollector"
import { DependencyTree } from "./types"

export class NpmNodeModulesCollector extends NodeModulesCollector {
constructor(rootDir: string) {
super(rootDir)
}

getPMCommand(): string {
const cmd = process.platform === "win32" ? "npm.cmd" : "npm"
return `${cmd} list --omit dev -a --json --long`
getCommand(): string {
return process.platform === "win32" ? "npm.cmd" : "npm"
}

getDependenciesTree(): DependencyTree {
const npmListOutput = execSync(this.getPMCommand(), {
cwd: this.rootDir,
encoding: "utf-8",
maxBuffer: 1024 * 1024 * 100,
})

const dependencyTree: DependencyTree = JSON.parse(npmListOutput)
return dependencyTree
getArgs(): string[] {
return ["list", "--omit", "dev", "-a", "--json", "--long"]
}
}
Original file line number Diff line number Diff line change
@@ -1,70 +1,55 @@
// copy from https://github.com/egoist/detect-package-manager/blob/main/src/index.ts
// and merge https://github.com/egoist/detect-package-manager/pull/9 to support Monorepo
import { promises as fs } from "fs"
import { resolve, dirname } from "path"
import { exec } from "child_process"
import { promisify } from "util"

const execa = promisify(exec)
import { exec, exists } from "builder-util"

export type PM = "npm" | "yarn" | "pnpm" | "bun"

/**
* Check if a path exists
*/
async function pathExists(p: string) {
try {
await fs.access(p)
return true
} catch {
return false
}
}

const cache = new Map()
beyondkmp marked this conversation as resolved.
Show resolved Hide resolved
const globalInstallationCache = new Map<string, boolean>()
const lockfileCache = new Map<string, PM>()

/**
* Check if a global pm is available
*/
function hasGlobalInstallation(pm: PM): Promise<boolean> {
const key = `has_global_${pm}`
if (cache.has(key)) {
return Promise.resolve(cache.get(key))
if (globalInstallationCache.has(key)) {
return Promise.resolve(globalInstallationCache.get(key)!)
}
const execa = promisify(exec)

return execa(`${pm} --version`)
return exec(pm, ["--version"])
.then(res => {
return /^\d+.\d+.\d+$/.test(res.stdout)
return /^\d+.\d+.\d+$/.test(res)
})
.then(value => {
cache.set(key, value)
globalInstallationCache.set(key, value)
return value
})
.catch(() => false)
}

function getTypeofLockFile(cwd = "."): Promise<PM | null> {
function getTypeofLockFile(cwd = process.cwd()): Promise<PM> {
const key = `lockfile_${cwd}`
if (cache.has(key)) {
return Promise.resolve(cache.get(key))
if (lockfileCache.has(key)) {
return Promise.resolve(lockfileCache.get(key)!)
}

return Promise.all([
pathExists(resolve(cwd, "yarn.lock")),
pathExists(resolve(cwd, "package-lock.json")),
pathExists(resolve(cwd, "pnpm-lock.yaml")),
pathExists(resolve(cwd, "bun.lockb")),
]).then(([isYarn, isNpm, isPnpm, isBun]) => {
let value: PM | null = null
exists(resolve(cwd, "yarn.lock")),
exists(resolve(cwd, "package-lock.json")),
exists(resolve(cwd, "pnpm-lock.yaml")),
exists(resolve(cwd, "bun.lockb")),
]).then(([isYarn, _, isPnpm, isBun]) => {
let value: PM

if (isYarn) {
value = "yarn"
} else if (isPnpm) {
value = "pnpm"
} else if (isBun) {
value = "bun"
} else if (isNpm) {
} else {
value = "npm"
}
beyondkmp marked this conversation as resolved.
Show resolved Hide resolved

Expand All @@ -73,7 +58,7 @@ function getTypeofLockFile(cwd = "."): Promise<PM | null> {
})
}

const detect = async ({ cwd, includeGlobalBun }: { cwd?: string; includeGlobalBun?: boolean } = {}) => {
export const detect = async ({ cwd, includeGlobalBun }: { cwd?: string; includeGlobalBun?: boolean } = {}) => {
let type = await getTypeofLockFile(cwd)
if (type) {
return type
Expand All @@ -88,23 +73,21 @@ const detect = async ({ cwd, includeGlobalBun }: { cwd?: string; includeGlobalBu
}
}

const [hasYarn, hasPnpm, hasBun] = await Promise.all([hasGlobalInstallation("yarn"), hasGlobalInstallation("pnpm"), includeGlobalBun && hasGlobalInstallation("bun")])
if (hasYarn) {
if (await hasGlobalInstallation("yarn")) {
return "yarn"
}
if (hasPnpm) {
return "pnpm"
if (await hasGlobalInstallation("pnpm")) {
return "yarn"
}
if (hasBun) {

if (includeGlobalBun && (await hasGlobalInstallation("bun"))) {
return "bun"
}
return "npm"
}
beyondkmp marked this conversation as resolved.
Show resolved Hide resolved

export { detect }

export function getNpmVersion(pm: PM) {
return execa(`${pm} --version`).then(res => res.stdout.trim())
export function getPackageManagerVersion(pm: PM) {
return exec(pm, ["--version"]).then(res => res.trim())
}

export function clearCache() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { execSync } from "child_process"
import { NodeModulesCollector } from "./nodeModulesCollector"
import { DependencyTree } from "./types"

export class PnpmNodeModulesCollector extends NodeModulesCollector {
constructor(rootDir: string) {
super(rootDir)
}

getPMCommand(): string {
const cmd = process.platform === "win32" ? "pnpm.cmd" : "pnpm"
return `${cmd} list --prod --json --long --depth Infinity`
getCommand(): string {
return process.platform === "win32" ? "pnpm.cmd" : "pnpm"
}

getDependenciesTree() {
const pnpmListOutput = execSync(this.getPMCommand(), {
cwd: this.rootDir,
encoding: "utf-8",
maxBuffer: 1024 * 1024 * 100,
})

const dependencyTree: DependencyTree = JSON.parse(pnpmListOutput)[0]
return dependencyTree
getArgs(): string[] {
return ["list", "--prod", "--json", "--long", "--depth", "Infinity"]
}
}
Original file line number Diff line number Diff line change
@@ -1,35 +1,15 @@
import { execSync } from "child_process"
import * as path from "path"
import { NodeModulesCollector } from "./nodeModulesCollector"
import { DependencyTree } from "./types"
import { log } from "builder-util"

export class YarnNodeModulesCollector extends NodeModulesCollector {
constructor(rootDir: string) {
super(rootDir)
}

getPMCommand(): string {
const cmd = process.platform === "win32" ? "npm.cmd" : "npm"
return `${cmd} list --omit dev -a --json --long`
getCommand(): string {
return process.platform === "win32" ? "npm.cmd" : "npm"
}

getDependenciesTree(): DependencyTree {
try {
const stdout = execSync(this.getPMCommand(), {
cwd: this.rootDir,
encoding: "utf-8",
maxBuffer: 1024 * 1024 * 100,
})
return JSON.parse(stdout) as DependencyTree
} catch (error) {
log.debug({ error }, "npm list failed in yarn project, but will be ignored")
if ((error as any).stdout) {
const stdout = (error as any).stdout
return JSON.parse(stdout) as DependencyTree
}
}

return require(path.join(this.rootDir, "package.json"))
getArgs(): string[] {
return ["list", "--omit", "dev", "-a", "--json", "--long", "--silent"]
}
}
2 changes: 1 addition & 1 deletion packages/app-builder-lib/src/util/appFileCopier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ function validateFileSet(fileSet: ResolvedFileSet): ResolvedFileSet {

/** @internal */
export async function computeNodeModuleFileSets(platformPackager: PlatformPackager<any>, mainMatcher: FileMatcher): Promise<Array<ResolvedFileSet>> {
const deps = (await getNodeModules(platformPackager.info.appDir)) as NodeModuleInfo[]
const deps = await getNodeModules(platformPackager.info.appDir)
log.debug({ nodeModules: deps }, "collected node modules")

const nodeModuleExcludedExts = getNodeModuleExcludedExts(platformPackager)
Expand Down
9 changes: 3 additions & 6 deletions packages/app-builder-lib/src/util/yarn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { getProjectRootPath } from "@electron/rebuild/lib/search-module"
import { rebuild as remoteRebuild } from "./rebuild/rebuild"
import { executeAppBuilderAndWriteJson } from "./appBuilder"
import { RebuildMode } from "@electron/rebuild/lib/types"
import { PM, detect, getNpmVersion } from "../node-module-collector"
import { PM, detect, getPackageManagerVersion } from "../node-module-collector"

export async function installOrRebuild(config: Configuration, appDir: string, options: RebuildOptions, forceInstall = false) {
const effectiveOptions: RebuildOptions = {
Expand Down Expand Up @@ -83,7 +83,7 @@ async function checkYarnBerry(pm: PM) {
if (pm !== "yarn") {
return false
}
const version = await getNpmVersion(pm)
const version = await getPackageManagerVersion(pm)
if (version == null || version.split(".").length < 1) {
return false
}
Expand Down Expand Up @@ -146,14 +146,11 @@ export async function nodeGypRebuild(platform: NodeJS.Platform, arch: string, fr
}

function getPackageToolPath(pm: PM) {
const suffix = process.platform === "win32" ? ".cmd" : ""
let cmd = pm

if (process.env.FORCE_YARN === "true") {
cmd = "yarn"
}
mmaietta marked this conversation as resolved.
Show resolved Hide resolved

return cmd + suffix
return `${cmd}${process.platform === "win32" ? ".cmd" : ""}`
}

function isRunningYarn(pm: PM) {
Expand Down
Loading