Skip to content

Commit 98056d2

Browse files
committed
perf: 优化打包大小
1 parent 9cfb16b commit 98056d2

2 files changed

Lines changed: 85 additions & 20 deletions

File tree

electron-builder.config.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const config: Configuration = {
55
productName: "SPlayer-Next",
66
copyright: "Copyright © imsyy 2025",
77
directories: { buildResources: "public" },
8-
// afterPack: "./scripts/after-pack.ts",
8+
afterPack: "./scripts/after-pack.ts",
99
compression: "maximum",
1010
files: [
1111
"public/**",
@@ -23,9 +23,9 @@ const config: Configuration = {
2323
"!{components.d.ts,auto-imports.d.ts}",
2424
"!{.env,.env.*,.npmrc,pnpm-lock.yaml}",
2525
"!{tsconfig.json,tsconfig.node.json,tsconfig.web.json}",
26-
"!**/*.{d.ts,map,md}",
27-
"!**/{CHANGELOG,LICENSE,license,README,readme}*",
28-
"!**/node_modules/better-sqlite3/deps/**",
26+
"!**/*.{d.ts,ts,map,md}",
27+
"!**/{CHANGELOG,README,readme}*",
28+
"!**/node_modules/better-sqlite3/{deps,src}/**",
2929
],
3030
// 保留的语言
3131
electronLanguages: ["zh-CN", "en-US"],

scripts/after-pack.ts

Lines changed: 81 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,91 @@
1-
import type { AfterPackContext } from "electron-builder";
2-
import { readdir, unlink } from "fs/promises";
1+
import { type AfterPackContext, Arch } from "electron-builder";
32
import { join } from "path";
3+
import { rm } from "node:fs/promises";
44

5-
/** 保留的 locale */
6-
const keepLocales = new Set(["en-US.pak", "zh-CN.pak"]);
5+
let hasWarnedCleanupOnce = false;
6+
const printCleanupWarningOnce = () => {
7+
if (!hasWarnedCleanupOnce) {
8+
hasWarnedCleanupOnce = true;
9+
console.warn(
10+
`[AfterPack] 部分文件清理失败。这不会影响 App 构建和运行,但可能导致包体积略大于预期。`,
11+
);
12+
}
13+
};
14+
15+
const tryRm = async (path: string, options?: object): Promise<void> => {
16+
try {
17+
await rm(path, options);
18+
} catch (error: any) {
19+
printCleanupWarningOnce();
20+
console.warn(`[AfterPack] 清理失败 "${path}": ${error.message}`);
21+
}
22+
};
723

8-
/** 打包后清理多余的 Chromium locale 文件 */
924
const afterPack = async (context: AfterPackContext): Promise<void> => {
10-
const localeDir = join(
25+
const resourceDir = join(
1126
context.appOutDir,
1227
context.packager.platform.name === "mac"
13-
? `${context.packager.appInfo.productFilename}.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Resources`
14-
: "locales",
28+
? `${context.packager.appInfo.productFilename}.app/Contents/Resources`
29+
: "resources",
1530
);
16-
try {
17-
const files = await readdir(localeDir);
18-
await Promise.all(
19-
files
20-
.filter((f) => f.endsWith(".pak") && !keepLocales.has(f))
21-
.map((f) => unlink(join(localeDir, f))),
22-
);
23-
} catch {}
31+
32+
await Promise.all([
33+
trimBetterSqlite3(resourceDir, context),
34+
trimFontListLibs(resourceDir, context),
35+
]);
36+
};
37+
38+
const trimBetterSqlite3 = async (resourceDir: string, context: AfterPackContext) => {
39+
const dir = join(resourceDir, "app.asar.unpacked/node_modules/better-sqlite3/");
40+
const allPlatform = ["win32", "darwin", "linux", "linuxmusl"];
41+
const allArch = ["x64", "arm64"];
42+
const keepPlatform = new Set<string>([context.electronPlatformName]); // 暂时不考虑 linuxmusl
43+
const keepArch = new Set<string>();
44+
45+
switch (context.arch) {
46+
case Arch.x64:
47+
keepArch.add("x64");
48+
break;
49+
case Arch.arm64:
50+
keepArch.add("arm64");
51+
break;
52+
case Arch.universal:
53+
keepArch.add("x64");
54+
keepArch.add("arm64");
55+
break;
56+
default:
57+
printCleanupWarningOnce();
58+
console.error("[AfterPack] 未知架构: " + context.arch);
59+
return;
60+
}
61+
62+
const deletePromises: Promise<void>[] = [];
63+
for (const platform of allPlatform) {
64+
for (const arch of allArch) {
65+
if (keepPlatform.has(platform) && keepArch.has(arch)) continue;
66+
const fileName = `${platform}-${arch}`;
67+
deletePromises.push(
68+
tryRm(join(dir, "prebuilds", `${fileName}.node`), { force: true }),
69+
tryRm(join(dir, "lib", `${fileName}.js`), { force: true }),
70+
);
71+
}
72+
}
73+
74+
await Promise.all(deletePromises);
75+
};
76+
77+
const trimFontListLibs = async (resourceDir: string, context: AfterPackContext) => {
78+
const dir = join(resourceDir, "app.asar.unpacked/node_modules/font-list/libs/");
79+
const allPlatform = ["win32", "darwin", "linux"];
80+
const keepPlatform = new Set<string>([context.electronPlatformName]);
81+
82+
const deletePromises: Promise<void>[] = [];
83+
for (const platform of allPlatform) {
84+
if (keepPlatform.has(platform)) continue;
85+
deletePromises.push(tryRm(join(dir, platform), { recursive: true, force: true }));
86+
}
87+
88+
await Promise.all(deletePromises);
2489
};
2590

2691
export default afterPack;

0 commit comments

Comments
 (0)