feat: 支持 macOS arm64 打包,修复图标未入库

新增 build-mac.js,产出 ad-hoc 签名的 .app 与 DMG。只能在 macOS 上
构建:DMG 依赖 hdiutil,且 Apple Silicon 拒绝执行未签名二进制,改名
与改 plist 后必须用 codesign 重签。

按官方 darwin-arm64 运行时的真实结构处理四处易错点:用 ditto 解压以
保留 framework 符号链接、删除重打包后失效的 ElectronAsarIntegrity、
为改名后的 helper 补上 CFBundleExecutable、签名由内向外且单独签
Squirrel 的 ShipIt。

打包版数据目录改为按平台决定:macOS 走 appData,避免写进 DMG 挂载后
只读的 .app 内部并在升级覆盖时丢失书库;Windows 便携版行为不变。
窗口图标在非 Windows 平台改用 PNG。

.gitignore 的 dist 规则补上前导斜杠。此前它同时匹配 icons/dist/,
导致构建与单测依赖的图标从未入库,新克隆的仓库无法构建。
This commit is contained in:
lofyer
2026-08-03 16:18:47 +08:00
parent 2c5c7b1828
commit 381c07733a
28 changed files with 597 additions and 10 deletions
+13 -4
View File
@@ -80,12 +80,21 @@ app.setAppUserModelId('com.peoplelib.client');
const APP_ICON_DIR = path.join(__dirname, 'icons', 'dist');
function iconForTheme(theme) {
return path.join(APP_ICON_DIR, theme === 'light' ? 'book-ai-light.ico' : 'book-ai-dark.ico');
const name = theme === 'light' ? 'light' : 'dark';
// .ico 只有 Windows 认;macOS/Linux 用 PNG,窗口图标不需要 icns
return process.platform === 'win32'
? path.join(APP_ICON_DIR, `book-ai-${name}.ico`)
: path.join(APP_ICON_DIR, name, 'icon-256.png');
}
const userDataDir = app.isPackaged
? path.join(path.dirname(app.getPath('exe')), 'data')
: path.join(app.getPath('appData'), 'PeopleLib');
// macOS 的 .app 内部不可写(DMG 只读,且升级覆盖会连用户数据一起删),
// 只有 Windows 便携版才把 data/ 放在可执行文件旁边。
function resolveUserDataDir() {
if (!app.isPackaged) return path.join(app.getPath('appData'), 'PeopleLib');
if (process.platform === 'win32') return path.join(path.dirname(app.getPath('exe')), 'data');
return path.join(app.getPath('appData'), 'PeopleLib');
}
const userDataDir = resolveUserDataDir();
app.setPath('userData', userDataDir);
const sources = require('./src/sources');