fix(electron): ship loginManager.js in the packaged app (#3292 regression) (#3334)

#3292 added electron/loginManager.js and a require("./loginManager") in
main.js but did not add it to electron-builder's build.files allowlist, so
the packaged app crashed at startup with "Cannot find module './loginManager'"
on the Linux/macOS smoke tests (v3.8.13 Electron release fragment).

Add loginManager.js to build.files, plus a regression test that asserts every
local require("./x") in the Electron entry points is shipped.
This commit is contained in:
Diego Rodrigues de Sa e Souza
2026-06-06 20:50:02 -03:00
committed by GitHub
parent a25d5f1ef6
commit cd89ce3cfa
2 changed files with 40 additions and 1 deletions

View File

@@ -51,6 +51,7 @@
"files": [
"main.js",
"preload.js",
"loginManager.js",
"sqlite-inspection.js",
"package.json",
"node_modules/**/*"

View File

@@ -13,7 +13,7 @@
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { mkdtempSync, rmSync } from "node:fs";
import { mkdtempSync, rmSync, readFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { createRequire } from "node:module";
@@ -38,6 +38,44 @@ function raceDelays(firstMs, secondMs) {
});
}
// ─── Packaging manifest completeness (#3292 regression) ──────
//
// The packaged Electron app (electron-builder asar) only ships the files
// listed in `build.files`. When #3292 added `electron/loginManager.js` and a
// `require("./loginManager")` in main.js without adding it to `build.files`,
// the packaged app crashed at startup with "Cannot find module './loginManager'"
// — caught only by the CI smoke test on Linux/macOS. This guard asserts that
// every local `require("./x")` in the Electron entry points is shipped.
describe("Electron packaging manifest completeness (#3292)", () => {
const electronDir = join(import.meta.dirname, "../../electron");
const pkg = JSON.parse(readFileSync(join(electronDir, "package.json"), "utf8"));
const files: string[] = pkg.build?.files ?? [];
function localRequires(entry: string): string[] {
const src = readFileSync(join(electronDir, entry), "utf8");
const out = new Set<string>();
for (const m of src.matchAll(/require\(["'](\.\/[A-Za-z0-9_./-]+)["']\)/g)) {
// normalize "./loginManager" -> "loginManager.js" (entry points require sibling .js)
let rel = m[1].replace(/^\.\//, "");
if (!/\.[a-z]+$/.test(rel)) rel += ".js";
out.add(rel);
}
return [...out];
}
for (const entry of ["main.js", "preload.js"]) {
it(`ships every local require() of ${entry} in build.files`, () => {
for (const dep of localRequires(entry)) {
assert.ok(
files.includes(dep),
`electron/${dep} is require()d by ${entry} but missing from package.json build.files — the packaged app will crash with "Cannot find module"`
);
}
});
}
});
// ─── URL Validation Tests ────────────────────────────────────
describe("Electron URL Validation", () => {