把仓库里的 PDF、EPUB、TXT 和 Markdown 自动整理成可在浏览器阅读的私人数字书架。项目是纯静态 React 应用,不需要后端、数据库或付费服务,适合部署到 GitHub Pages。
- 构建时递归扫描书库,自动生成分类树和
public/catalog.json - 即时搜索书名、文件名、分类、格式和标签,并支持格式/最近阅读筛选
- PDF:分页、页码跳转、缩放、适应宽度、全屏、全文搜索
- EPUB:章节目录、前后翻章、字号与主题、全书搜索、CFI 位置恢复
- TXT:UTF-8、UTF-16、GB18030 解码、排版设置、文本搜索、滚动恢复
- Markdown:标题目录、表格、引用、列表、代码、图片、搜索和滚动恢复
- 最近阅读、继续阅读、单书/全部进度清理
- 浅色、深色、跟随系统,以及纸白、护眼、夜读阅读背景
- 响应式书架、移动端分类抽屉和触摸友好的阅读工具栏
- 可选前端访问密码,支持登录有效期与退出
- Hash Router 和统一资源 URL,兼容中文、空格与 GitHub Pages 子路径
要求 Node.js 22 或更高版本。推荐使用仓库锁定的 pnpm:
corepack enable
pnpm install
pnpm dev也可以使用:
npm install
npm run dev开发服务器会直接从 ebooks/ 读取书籍,不会移动或复制原文件。
pnpm build构建会依次读取 Pages 排除配置、生成目录、打包前端,并把保留的电子书与封面复制到 dist/books/。静态产物位于 dist/;若最终站点仍超过 1 GB,构建会失败并提示继续调整配置。
如果需要模拟仓库子路径:
VITE_BASE_PATH=/ebooks-library/ pnpm buildWindows PowerShell:
$env:VITE_BASE_PATH='/ebooks-library/'
pnpm buildpages-exclude.json 是相对于逻辑书库根目录的字符串数组,支持目录和单个文件:
[
"轻小说/Re0",
"轻小说/SAO",
"轻小说/Fate/Fate-Prototype 苍银的碎片 04 Dear My Hero.epub"
]- 目录会连同全部后代一起排除。
- 文件规则只排除完全匹配的文件。
- 可使用
/或\\,但不能使用绝对路径或..。 - 规则同时作用于 Pages 书目、封面生成和静态文件复制,不会产生无法打开的书籍卡片。
pnpm dev不应用该配置,仍展示完整本地书库;pnpm build和 GitHub Actions 才应用。
当前默认规则排除 66 本书,使生产书目保留 365 本。修改数组后重新运行 pnpm build 即可看到实际站点大小。
项目只扫描仓库根目录下的 ebooks/,避免把应用代码或工具目录误当成书库分类。
ebooks/
└── 科幻/
└── 银河帝国/
└── 基地.epub
支持 .pdf、.epub、.txt、.md、.markdown。新增、删除或移动文件后,运行 pnpm generate:catalog;开发和构建命令也会自动执行扫描。
隐藏文件、应用目录、封面图片和元数据文件不会被当作书籍。
封面查找顺序为同名图片、目录中的 cover 图片、EPUB 内置封面、PDF 首页缩略图、格式默认书脊。支持 JPG、JPEG、PNG、WebP:
基地.epub
基地.jpg
可选元数据文件与书籍同名:
{
"title": "基地",
"author": "艾萨克·阿西莫夫",
"description": "银河帝国系列",
"tags": ["科幻", "太空歌剧"],
"cover": "基地.jpg"
}文件名为 基地.meta.json。损坏的元数据会被忽略并在构建日志中提示。
pnpm build 会增量生成内置封面与 PDF 缩略图到被忽略的 public/generated-covers/。损坏或无法识别的文件会记录警告并回退到按格式生成的书脊封面。也可单独运行 pnpm generate:covers。
复制 .env.example 为 .env.local,设置:
ACCESS_PASSWORD=your-password
ACCESS_SESSION_HOURS=168构建配置只把密码的 SHA-256 摘要注入前端。也可以省略明文,直接设置 ACCESS_PASSWORD_HASH。GitHub Actions 部署时,在仓库 Settings → Secrets and variables → Actions 中添加同名 Secret;有效期可通过变量 ACCESS_SESSION_HOURS 设置。
当前工作流的构建任务绑定 GithubPage 环境,因此环境 Secret 应创建在 GithubPage 下。若改用 Repository secret,也可直接使用同名 ACCESS_PASSWORD,但不要同时在两个作用域维护不同密码。Secret 只在重新运行部署后生效。
不配置密码或摘要时,访问页自动停用。
该密码功能仅用于简单访问限制,无法阻止懂技术的用户获取静态资源地址,也无法真正保护仓库中的电子书。GitHub Pages 发布的网站可被公网访问,即使源仓库是私有仓库也不应把它当作安全存储。
- 推送到
main分支。 - 在仓库
Settings → Pages → Build and deployment中选择GitHub Actions。 - 可选:配置上面的访问密码 Secret。
- 工作流会自动识别项目 Pages 的
/<repository>/基础路径;用户/组织主页仓库则使用/。 - 也可以在 Actions 页面手动运行
Deploy ebook shelf to Pages。
工作流位于 .github/workflows/pages.yml,包含 Git LFS 拉取、目录生成、构建、Pages artifact 上传和部署。
所有数据保存在浏览器 localStorage 中。更换设备/浏览器、无痕模式结束或清理站点数据后记录会丢失,不支持跨设备同步。
- 单本记录:阅读页右上角菜单 →
清除阅读记录 - 全部记录:首页右上角设置 →
清除全部记录 - 退出访问:首页右上角设置 →
退出访问
GitHub 官方说明:已发布的 Pages 站点最大为 1 GB,软带宽限制为每月 100 GB;Pages artifact 的压缩包上限另为 10 GB。请以 GitHub Pages limits 和 Custom workflows 的最新说明为准。
本仓库完整书库超过 Pages 限制,因此生产构建默认通过 pages-exclude.json 排除部分大目录/文件,并在复制完成后执行 1 GB 硬门禁。若希望发布其他组合,可调整该数组;如果无法通过删减满足限制,应把大文件迁移到允许跨域访问的外部静态存储。Git LFS 本身不等于 Pages 文件托管方案。
其他限制:
- 前端密码、文件地址和内容都无法防下载、防抓取或提供 DRM。
- 阅读进度无法云同步。
- 大型 EPUB 全书搜索与 PDF 全文搜索会按需读取全书,首次搜索可能较慢。
- 大型 TXT 仍需在当前页面加载完整文本;浏览器内存有限时建议拆分文件。
- EPUB/PDF 的复杂排版、损坏文件或浏览器兼容问题可能导致渲染差异,可从阅读页查看或下载原文件。
scripts/ 目录生成与构建资源复制
ebooks/ 原始电子书与分类目录
pages-exclude.json Pages 构建排除规则
public/catalog.json 自动生成的书目
src/components/ 通用界面组件
src/pages/ 书架、阅读器入口、设置页
src/readers/ PDF、EPUB、TXT、Markdown 阅读器
src/services/ 目录、认证、设置与进度存储
.github/workflows/ GitHub Pages 自动部署
pnpm test
pnpm build