Skip to content

Commit fcecbf0

Browse files
committed
fix: Build fails due to peer dependency errors
Closes #611
1 parent ddfa6fc commit fcecbf0

File tree

5 files changed

+64
-37
lines changed

5 files changed

+64
-37
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"pretty-ms": "^2.1.0",
8585
"progress": "^1.1.8",
8686
"progress-stream": "^1.2.0",
87+
"read-installed": "^4.0.3",
8788
"sanitize-filename": "^1.6.0",
8889
"semver": "^5.3.0",
8990
"source-map-support": "^0.4.2",

src/platformPackager.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { Minimatch } from "minimatch"
1111
import { checkFileInArchive, createAsarArchive } from "./asarUtil"
1212
import { warn, log, task } from "./util/log"
1313
import { AppInfo } from "./appInfo"
14-
import { listDependencies, createFilter, copyFiltered, hasMagic } from "./util/filter"
14+
import { createFilter, copyFiltered, hasMagic, devDependencies } from "./util/filter"
1515
import { ElectronPackagerOptions, pack } from "./packager/dirPackager"
1616

1717
//noinspection JSUnusedLocalSymbols
@@ -169,22 +169,17 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
169169
const p = pack(options, appOutDir, platformName, Arch[arch], this.info.electronVersion, async() => {
170170
const ignoreFiles = new Set([path.relative(this.info.appDir, outDir), path.relative(this.info.appDir, this.buildResourcesDir)])
171171
if (!this.info.isTwoPackageJsonProjectLayoutUsed) {
172-
const result = await BluebirdPromise.all([listDependencies(this.info.appDir, false), listDependencies(this.info.appDir, true)])
173-
const productionDepsSet = new Set(result[1])
174-
172+
const result = await devDependencies(this.info.appDir)
175173
// npm returns real path, so, we should use relative path to avoid any mismatch
176174
const realAppDirPath = await realpath(this.info.appDir)
177-
178-
for (let it of result[0]) {
179-
if (!productionDepsSet.has(it)) {
180-
if (it.startsWith(realAppDirPath)) {
181-
it = it.substring(realAppDirPath.length + 1)
182-
}
183-
else if (it.startsWith(this.info.appDir)) {
184-
it = it.substring(this.info.appDir.length + 1)
185-
}
186-
ignoreFiles.add(it)
175+
for (let it of result) {
176+
if (it.startsWith(realAppDirPath)) {
177+
it = it.substring(realAppDirPath.length + 1)
178+
}
179+
else if (it.startsWith(this.info.appDir)) {
180+
it = it.substring(this.info.appDir.length + 1)
187181
}
182+
ignoreFiles.add(it)
188183
}
189184
}
190185

src/util/filter.ts

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { copy } from "fs-extra-p"
22
import { Minimatch } from "minimatch"
3-
import { exec } from "./util"
43
import * as path from "path"
4+
import { Promise as BluebirdPromise } from "bluebird"
55

66
//noinspection JSUnusedLocalSymbols
77
const __awaiter = require("./awaiter")
8+
const readInstalled = require("read-installed")
89

910
// we use relative path to avoid canonical path issue - e.g. /tmp vs /private/tmp
1011
export function copyFiltered(src: string, destination: string, filter: (file: string) => boolean, dereference: boolean): Promise<any> {
@@ -54,29 +55,43 @@ export function createFilter(src: string, patterns: Array<Minimatch>, ignoreFile
5455
}
5556
}
5657

57-
export async function listDependencies(appDir: string, production: boolean): Promise<Array<string>> {
58-
let npmExecPath = process.env.npm_execpath || process.env.NPM_CLI_JS
59-
const npmExecArgs = ["ls", production ? "--production" : "--dev", "--parseable"]
60-
if (npmExecPath == null) {
61-
npmExecPath = process.platform === "win32" ? "npm.cmd" : "npm"
62-
}
63-
else {
64-
npmExecArgs.unshift(npmExecPath)
65-
npmExecPath = process.env.npm_node_execpath || process.env.NODE_EXE || "node"
66-
}
58+
export function devDependencies(dir: string): Promise<Array<string>> {
59+
return new BluebirdPromise((resolve, reject) => {
60+
readInstalled(dir, (error: Error, data: any) => {
61+
if (error) {
62+
reject(error)
63+
}
64+
else {
65+
resolve(flatDependencies(data, new Set()))
66+
}
67+
})
68+
})
69+
}
6770

68-
const result = (await exec(npmExecPath, npmExecArgs, {
69-
cwd: appDir,
70-
stdio: "inherit",
71-
maxBuffer: 1024 * 1024,
72-
})).trim().split("\n")
73-
if (result.length > 0 && !result[0].includes("/node_modules/")) {
74-
// first line is a project dir
75-
const lastIndex = result.length - 1
76-
result[0] = result[lastIndex]
77-
result.length = result.length - 1
71+
function flatDependencies(data: any, seen: Set<string>): any {
72+
const deps = data.dependencies
73+
if (deps == null) {
74+
return []
7875
}
79-
return result
76+
77+
return Object.keys(deps).map(function (d) {
78+
if (typeof deps[d] !== "object" || seen.has(deps[d])) {
79+
return null
80+
}
81+
82+
seen.add(deps[d])
83+
if (deps[d].extraneous) {
84+
const extra = deps[d]
85+
delete deps[d]
86+
return extra.path
87+
}
88+
return flatDependencies(deps[d], seen)
89+
})
90+
.filter(it => it !== null)
91+
.reduce(function FLAT(l, r) {
92+
return l.concat(Array.isArray(r) ? r.reduce(FLAT, []) : r)
93+
}, [])
94+
8095
}
8196

8297
// https://github.com/joshwnj/minimatch-all/blob/master/index.js

src/util/util.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export interface ExecOptions extends BaseExecOptions {
6161
}
6262

6363
export function removePassword(input: string): string {
64-
return input.replace(/(-P |pass:)([^ ]+)/, function (match, p1, p2) {
64+
return input.replace(/(-P |pass:|\/p|-pass )([^ ]+)/, function (match, p1, p2) {
6565
return `${p1}${createHash("sha256").update(p2).digest("hex")} (sha256 hash)`
6666
})
6767
}

test/src/globTest.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,22 @@ test.ifNotCiOsx("ignore node_modules known dev dep", () => {
135135
})
136136
})
137137

138+
// https://github.com/electron-userland/electron-builder/issues/611
139+
test.ifDevOrLinuxCi("failed peer dep", () => {
140+
return assertPack("test-app-one", {
141+
targets: Platform.LINUX.createTarget(DIR_TARGET),
142+
}, {
143+
npmInstallBefore: true,
144+
tempDirCreated: projectDir => modifyPackageJson(projectDir, data => {
145+
data.dependencies = {
146+
"rc-datepicker": "4.0.0",
147+
"react": "15.2.1",
148+
"react-dom": "15.2.1"
149+
}
150+
}),
151+
})
152+
})
153+
138154
test("extraResources", async () => {
139155
for (let platform of getPossiblePlatforms().keys()) {
140156
const osName = platform.buildConfigurationKey

0 commit comments

Comments
 (0)