Files
zn-ai/package_mac_diagnosis_report.md
2026-04-11 17:22:29 +08:00

146 lines
5.1 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# package:mac 打包诊断报告
**诊断时间**: 2026-04-11
**项目路径**: `/Users/duanshuwen/Documents/workspace/electron/zn-ai`
**执行命令**: `pnpm run package:mac`
---
## 1. 结论摘要
**本次打包失败不是因为项目源码缺少文件或 `electron-builder.yml` 配置项缺失,而是因为**
1. **网络下载中断**`electron-builder` 在构建 DMG 时需要下载 `dmgbuild-bundle-x86_64`,该请求被服务器中断(`ReadError: The server aborted pending request`)。
2. **并发锁竞争**`mac.target` 同时配置了 `x64``arm64` 两种架构,`electron-builder` 并行打包时两个进程争抢 `proper-lockfile` 的缓存锁,导致下载失败后的清理阶段抛出 `Lock file is already being held` 错误。
3. **(非致命)代码签名证书已过期**:本地唯一的 `Apple Development` 证书状态为 `CSSMERR_TP_CERT_EXPIRED`,因此 `electron-builder` 跳过了正式签名,仅做了 ad-hoc 签名。这不会导致打包中断,但会影响最终 app 在 macOS Gatekeeper 下的可运行性。
---
## 2. 关键错误日志
```text
• downloading release=dmg-builder@1.2.0 file=dmgbuild-bundle-x86_64-75c8a6c.tar.gz
...
ReadError: The server aborted pending request
...
Error: Lock file is already being held
at /Users/duanshuwen/Documents/workspace/electron/zn-ai/node_modules/proper-lockfile/lib/lockfile.js:68:47
...
ELIFECYCLE Command failed with exit code 1.
```
---
## 3. 配置与文件检查结果
| 检查项 | 状态 | 说明 |
|--------|------|------|
| `package.json` | 正常 | 存在且 `package:mac` 脚本定义正确 |
| `electron-builder.yml` | 正常 | 配置完整,`mac` / `dmg` / `win` / `linux` 分平台配置齐全 |
| `resources/icons/icon.icns` | 正常 | `mac.icon` 指向的文件存在 |
| `entitlements.mac.plist` | 正常 | 文件存在并已配置 |
| `dist` / `dist-electron` | 正常 | `vite build` 阶段成功通过,产物已生成 |
| 发布产物 | 部分生成 | `zip`x64 / arm64已成功生成但 DMGx64 / arm64因下载失败未完成 |
---
## 4. 详细原因分析
### 4.1 网络问题导致 dmg-builder 下载中断
`electron-builder` 在首次构建 DMG 时需要拉取预编译的 `dmg-builder` bundle`dmgbuild-bundle-x86_64-75c8a6c.tar.gz`)。由于该资源托管在 GitHub / AWS CDN 上,在国内网络环境下极易出现连接被重置或请求被服务器中断的情况。
### 4.2 并发构建加剧锁竞争
`electron-builder.yml` 中配置了同时打包两种架构:
```yaml
mac:
target:
- target: dmg
arch:
- x64
- arm64
- target: zip
arch:
- x64
- arm64
```
这导致 `electron-builder` 会并行启动多个打包任务。当它们同时尝试下载/解压同一个 `dmg-builder` 缓存时,`proper-lockfile` 产生竞争;一旦其中一个下载失败,另一个在清理阶段也会因无法获取锁而报错,最终整体构建失败。
### 4.3 代码签名证书过期(仅提示,不中断构建)
日志中出现的:
```text
skipped macOS application code signing reason=cannot find valid "Developer ID Application" identity ...
"Apple Development: 562304744@qq.com (Z27TQS657B)" (CSSMERR_TP_CERT_EXPIRED)
```
这说明本地证书已过期,不会影响打包流程本身,但生成的 `.app` 没有有效的开发者签名,分发后用户打开时会遇到 "已损坏,无法打开" 的 Gatekeeper 提示。
---
## 5. 解决方案与建议
### 方案 A分架构单独打包推荐最稳定
先避免并发锁竞争,同时降低单次构建对网络的敏感度:
```bash
# 仅打包 arm64Apple Silicon
cd zn-ai
npx electron-builder --mac --arm64 --publish never
# 仅打包 x64Intel
npx electron-builder --mac --x64 --publish never
```
若网络仍不稳定,可配置代理或手动下载缓存(见方案 B
### 方案 B配置 electron-builder 缓存
如果网络受限,可预先设置缓存目录并手动下载所需 bundle
```bash
export ELECTRON_BUILDER_CACHE="$HOME/.electron-builder-cache"
```
然后手动将 `dmgbuild-bundle-x86_64-75c8a6c.tar.gz` 放置到缓存目录的 `cache/dmg-builder` 子目录下,再执行打包。
### 方案 C修改 `electron-builder.yml` 降低并发
`mac.target` 里先只保留当前常用架构(如 `arm64`),需要时再切换:
```yaml
mac:
target:
- target: dmg
arch:
- arm64
- target: zip
arch:
- arm64
```
### 方案 D修复代码签名分发前必须
若计划将应用分发给其他用户,需要:
1. 在 Apple Developer 后台续期或重新申请 **Developer ID Application** 证书;
2.`notarize` 改为 `true` 并配置正确的 `teamId`
3. 在构建机器上安装新证书后重新打包。
---
## 6. 附录:构建产物现状
截至诊断时,`release/` 目录下已生成:
- `NIANXX-1.0.0-mac-x64.zip` (133 MB)
- `NIANXX-1.0.0-mac-arm64.zip` (129 MB)
- 对应的 `.blockmap` 文件
**未生成**
- `NIANXX-1.0.0-mac-x64.dmg`
- `NIANXX-1.0.0-mac-arm64.dmg`
原因即上述网络下载中断 + 并发锁竞争。
---
*报告结束*