# 开发与构建 面向开发者的源码运行、打包、配置与架构说明。只想使用应用的用户请看 [README](README.md)。 ## 源码运行与打包 源码开发需要 Node.js 22.19+: ```bash npm install npm start ``` 生成 Windows 免安装版到 `dist/`: ```bash npm run portable ``` 输出目录固定为 `dist/PeopleLib-windows-x64/`,不随版本号变化,重复构建会保留其中的 `data/` 目录。构建前需退出该目录下正在运行的 `PeopleLib.exe`,否则会因文件占用而中止。 发布时将完整的 `dist/PeopleLib-windows-x64/` 目录压缩,上传到 GitHub Release,并使用 `v1.3.0` 形式的版本标签。应用根据最新 Release 标签判断是否需要更新。 ### macOS(Apple Silicon) **只能在 macOS 上执行**,且需要 Xcode 命令行工具(`xcode-select --install`): ```bash npm install npm run build:mac ``` 产出 `dist/PeopleLib-macos-arm64/PeopleLib.app` 与 `dist/PeopleLib-macos-arm64.dmg`。 不能在 Windows 或 Linux 上交叉构建,原因有两条,都无法绕开: - DMG 由 `hdiutil` 生成,该工具只存在于 macOS。 - Apple Silicon 内核会拒绝执行未签名的二进制。打包过程要重命名可执行文件、修改 `Info.plist`,Electron 的原始签名必然失效,必须用 macOS 的 `codesign` 重新签名。 脚本使用 ad-hoc 签名(`codesign --sign -`),可以在本机及自行放行的机器上运行,但未经 Apple 公证。首次打开需右键点按图标选择「打开」,或执行: ```bash xattr -dr com.apple.quarantine /Applications/PeopleLib.app ``` 图标 `icons/dist/book-ai-*.icns` 已随仓库提供。源 PNG 变更后用 `npm run icons:icns` 重新生成,该脚本在任意平台都能运行,不依赖 macOS 的 `iconutil`。 ## 配置 ### 代理 在应用内「设置」填写代理地址,例如 `http://127.0.0.1:7897`。留空表示直连。配置会持久化,重启后仍生效,并应用于所有数据源请求与封面加载。 网络受限环境下,多数数据源需要代理才能访问。 ### Z-Library 账号 「设置」中填入邮箱与密码即可登录。登录后可获取下载直链(免费账号有每日下载额度限制)。 > 凭据以 base64 混淆后保存在本地 `zlib-auth.json`,**这只是防止肉眼直读,不是加密**。请勿在不受信任的机器上使用。 ## 数据位置 | 模式 | 路径 | |---|---| | 开发运行(Windows) | `%APPDATA%/PeopleLib` | | 开发运行(macOS) | `~/Library/Application Support/PeopleLib` | | 打包运行(Windows 便携版) | 可执行文件同级的 `data/` 目录 | | 打包运行(macOS) | `~/Library/Application Support/PeopleLib` | macOS 不采用便携布局:`.app` 内部在 DMG 挂载时只读,且覆盖升级会连同用户书库一并删除。 该目录包含: - `library.json` 书库索引 - `settings.json` 应用设置(代理等) - `zlib-auth.json` Z-Library 凭据与会话 - `covers/` 封面缓存 ## 项目结构 ``` main.js 主进程:窗口、IPC、代理与证书处理、文件下载 preload.js 渲染进程 API 桥接 src/ settings.js 设置持久化 library/store.js 书库存储 sources/ index.js 数据源注册表 http.js 统一 HTTP 层:超时、Cookie、代理 mirror.js 镜像故障转移 zlib-auth.js Z-Library 凭据存储 .js 各数据源实现 ui/ 渲染进程界面 ``` ### 数据源接口 每个数据源模块导出以下结构: ```js module.exports = { id: 'example', name: '示例源', supportsSearch: true, async list(page) // 浏览:{ items, maxPage, page } async search(keyword, page) // 搜索:{ items, maxPage, page } async detail(postId) // 详情:{ title, authors, cover, tags, brief, links } async download(postId) // 下载:{ files, links } }; ``` 新增数据源只需实现该接口,并在 `src/sources/index.js` 中注册。 ### 网络层说明 - 主进程使用 Electron 的 `net.fetch`(Chromium 网络栈),代理通过 `session.setProxy` 生效 - 纯 Node 环境回退到 undici `ProxyAgent`(Electron 下不启用,该组合存在兼容问题) - 所有请求默认 15 秒超时,可按调用点覆盖 - 失效镜像进入 5 分钟冷却,之后自动重试,避免站点恢复后被永久跳过 - **应用启动时全局忽略 TLS 证书错误**。这是为了兼容大量使用自签名或过期证书的镜像站点,代价是失去对中间人攻击的防护,请仅在受信任的网络环境中使用。 ## 测试 单元测试: ```bash npm test ``` 数据源联通性检查,对主要数据源依次执行搜索、详情、下载链路,输出每一步耗时与结果: ```bash npx electron test-search.js --proxy http://127.0.0.1:7897 ```