Files
peoplelib/BUILD.md
T
lofyer 7ca023023e
构建与发布 / 单测与集成测试 (push) Waiting to run
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (arm64, linux, ubuntu-24.04-arm) (push) Blocked by required conditions
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (arm64, macos, macos-15) (push) Blocked by required conditions
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (x64, linux, ubuntu-24.04) (push) Blocked by required conditions
构建与发布 / 打包 ${{ matrix.platform }} ${{ matrix.arch }} (x64, windows, windows-2025) (push) Blocked by required conditions
构建与发布 / 发布 GitHub Release (push) Blocked by required conditions
feat: 增加 Linux 打包与 GitHub 构建发布链
新增 build-linux.js,直接从官方 zip 转写 tar 保住可执行位,
Windows 上也能构建 Linux 包。新增 build-release.js 作为发布件
唯一出口,排除便携版 data/、回读产物校验内容、生成校验和。
GitHub Actions 分测试、四目标打包、标签发布三段。
2026-08-05 19:07:11 +08:00

10 KiB
Raw Permalink Blame History

开发与构建

面向开发者的源码运行、打包、配置与架构说明。只想使用应用的用户请看 README

源码运行与打包

源码开发需要 Node.js 22.19+

npm install
npm start

生成 Windows 免安装版到 dist/

npm run portable

输出目录固定为 dist/PeopleLib-windows-x64/,不随版本号变化,重复构建会保留其中的 data/ 目录。构建前需退出该目录下正在运行的 PeopleLib.exe,否则会因文件占用而中止。

发布件不要手工压缩目录上传,用下面的发布打包入口生成,它会排除 data/ 并附带校验和。

Linuxx64 / arm64

npm run build:linux -- --arch x64
npm run build:linux -- --arch arm64

产出 dist/PeopleLib-linux-<arch>.tar.gz,解压后运行其中的 PeopleLib.sh

脚本直接把官方 Electron zip 里的条目转写进 tar,不落地中间目录,因此在 Windows 上也能构建出可用的 Linux 包。可执行位存在 zip 的 external attributes 里,先解压到 NTFS 再打包会把这些位全部丢掉,产物解压后 PeopleLibchrome-sandbox 都不可执行。

多数发行版开启了非特权用户命名空间,无需额外配置。内核禁用该特性时(kernel.unprivileged_userns_clone=0),需给沙箱补 setuid

sudo chown root:root PeopleLib-linux-x64/chrome-sandbox
sudo chmod 4755 PeopleLib-linux-x64/chrome-sandbox

macOSApple Silicon

只能在 macOS 上执行,且需要 Xcode 命令行工具(xcode-select --install):

npm install
npm run build:mac

产出 dist/PeopleLib-macos-arm64/PeopleLib.appdist/PeopleLib-macos-arm64.dmg

不能在 Windows 或 Linux 上交叉构建,原因有两条,都无法绕开:

  • DMG 由 hdiutil 生成,该工具只存在于 macOS。
  • Apple Silicon 内核会拒绝执行未签名的二进制。打包过程要重命名可执行文件、修改 Info.plist,Electron 的原始签名必然失效,必须用 macOS 的 codesign 重新签名。

脚本使用 ad-hoc 签名(codesign --sign -),可以在本机及自行放行的机器上运行,但未经 Apple 公证。首次打开需右键点按图标选择「打开」,或执行:

xattr -dr com.apple.quarantine /Applications/PeopleLib.app

图标 icons/dist/book-ai-*.icns 已随仓库提供。源 PNG 变更后用 npm run icons:icns 重新生成,该脚本在任意平台都能运行,不依赖 macOS 的 iconutil

发布打包

build-release.js 是发布件的唯一出口,负责调用平台构建脚本、校验产物内容、生成校验和:

npm run release -- --platform windows --arch x64
npm run release -- --platform macos   --arch arm64
npm run release -- --platform linux   --arch x64
npm run release -- --platform linux   --arch arm64

--skip-build 可复用已有的构建产物。输出落在 dist/release/<platform>-<arch>/,含发布件、SHA256SUMS.txtrelease-manifest.json

发布前的校验是硬要求,不要跳过直接压缩目录上传:

  • Windows 便携版把用户书库放在程序同级 data/,本机构建目录里通常有内容,手工压缩会把整个书库连同笔记打进公开发布件。脚本按前缀排除 data/,并在打包后回读压缩包确认。
  • Linux 产物必须回读 tar 确认 PeopleLibPeopleLib.shchrome-sandbox 带可执行位,丢了就是解压后点不开。
  • 三个平台都会检查有没有混入 _test

汇总多平台产物时用回验模式,它逐个比对哈希、体积与版本,再汇总到 dist/release-upload/

npm run release -- --verify dist/release-downloads

持续集成

.github/workflows/build.yml 在推送 main、提交 PR、打 v* 标签和手动触发时运行,分三个阶段:

  1. validatenpm ci 后跑单测与全部 Electron 集成套件。集成测试要开真实窗口,无头 runner 上用 xvfb-run 提供 X server。
  2. package:四个目标并行打包(windows-2025macos-15ubuntu-24.04ubuntu-24.04-arm),各自调用 npm run release,产物作为 artifact 保留 30 天。
  3. release:仅在推送 v* 标签时执行,回验各平台校验和后创建 GitHub Release 并上传。

两个容易踩的点:

  • 仓库 .npmrc 指向 npmmirrorGitHub runner 在境外拉不动,工作流用 npm_config_registryELECTRON_MIRROR 覆盖回官方源。
  • 标签名必须与 package.jsonversion 一致(v2.0.0 对应 2.0.0),且标签要指向被构建的那个提交,两处校验不过直接中止发布。

Release 先建草稿、上传完再转正式,上传中途失败不会在页面上留下一个资产不全的版本。应用根据最新 Release 标签判断是否需要更新。

固定构建变体

PeopleLib 采用固定构建变体,不使用远程开关在应用发布后改变功能范围:

构建 定位 功能范围
桌面完整版 Windows、macOS 多源检索、下载与任务中心、数据源账号、代理、本地书库、阅读和笔记
移动阅读版 iPadOS、Android 本地导入、书库、阅读、笔记、书签和批注

移动阅读版固定关闭以下能力:

{
  remoteSearch: false,
  remoteDownload: false,
  sourceAccounts: false,
  proxy: false
}

这些能力必须在构建时确定。移动端不展示相关入口、不注册对应桥接 API、不发起数据源请求,也不能通过服务端配置重新开启。桌面端继续保留完整功能。

移动端不能直接复用 Electron 包,需要使用独立的移动端外壳。下载、文件系统、安全存储和阅读文件访问均应通过 iPadOS/Android 原生桥接实现。首个移动版本只提供本地阅读能力;从系统文件选择器、分享面板或用户自行管理的云盘导入文件,不提供应用内在线检索和下载。

移动阅读版必须由专用脚本生成,不能依赖开发者手工删除页面或模块。计划提供以下固定入口:

npm run build:android
npm run build:ios

两个命令应调用同一套移动构建脚本,并把平台与固定变体显式传入,例如:

node build-mobile.js --platform android --variant reader-only
node build-mobile.js --platform ios --variant reader-only

build-mobile.js 必须完成:

  1. 校验变体只能是 reader-only,拒绝从环境变量或远程配置开启受限能力。
  2. 生成移动端能力清单,并在编译前固定关闭检索、下载、数据源账号和代理。
  3. 使用移动端入口组装资源,不注册桌面端 IPC,不复制在线数据源模块。
  4. 调用 Android 或 iOS 原生工程构建工具,并把产物输出到固定的 dist/PeopleLib-android/dist/PeopleLib-ios/
  5. 对最终产物运行自动化检查,确认不存在检索、下载、数据源账号和代理入口。

Android 构建可以在 Windows、macOS 或 Linux 上执行;iOS/iPadOS 构建依赖 Xcode、签名与 Apple SDK,只能在 macOS 上执行。

当前仓库尚未包含 build-mobile.js 与移动端原生工程,所以上述命令是必须补齐的目标构建入口,目前不能生成移动安装包。

配置

代理

在应用内「设置」填写代理地址,例如 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 凭据存储
    <source>.js      各数据源实现
  ui/                渲染进程界面

数据源接口

每个数据源模块导出以下结构:

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 证书错误。这是为了兼容大量使用自签名或过期证书的镜像站点,代价是失去对中间人攻击的防护,请仅在受信任的网络环境中使用。

测试

单元测试:

npm test

数据源联通性检查,对主要数据源依次执行搜索、详情、下载链路,输出每一步耗时与结果:

npx electron test-search.js --proxy http://127.0.0.1:7897