【无标题】
纯前端零框架实现 34 万首古诗词阅读器:诗海 The Poetry Ocean 开源项目分享
当代码遇见诗歌,当数据承载文明,那些被吟诵千年的文字依然可以在今天闪耀。
一、项目背景
在信息快速流动的今天,我们每天接触大量文字,却越来越少停下来读一读跨越千年的诗句。杜甫的沉吟、李白的豪情、苏轼的旷达——它们躺在数据库里,与现代读者之间隔着一层。
诗海(The Poetry Ocean) 是一个开源的古诗词数字化展示项目:
- 收录 344,240 首 古诗词
- 纯前端静态网站,无服务器、无后端、无框架、无构建
- 单文件
index.html包含全部 CSS/JS - 同步提供 微信小程序 版本,功能完全对等
🔗 在线体验:https://ethanthr-dotcom.github.io/poetry-site/
📦 源码仓库:https://github.com/ethanthr-dotcom/shihai-the_poetry_ocean
二、技术架构
整体设计
网页端 浏览器 ──► 单文件 index.html ──► data/*.json(jsDelivr CDN) 小程序端 页面 ──► wx.cloud.callFunction ──► poemData(gzip 打包)
核心思路:按需加载 + 两级索引。34 万首诗切分为 345 个分块(每块 1000 首,约 90MB),配合两级索引实现懒加载。
两级索引设计
| 文件 | 大小 | 内容 |
|---|---|---|
index.json |
18KB | file / count / dynasties |
index-full.json |
324KB | + authors / types |
001.json ~ 345.json |
~260KB/块 | 1000 首/块 |
首次访问只加载 18KB,后续按需加载分块。这种设计的关键在于:
- 精简索引首屏必需,包含朝代信息(朝代搜索可用)
- 全索引懒加载,额外包含作者和体裁(作者/体裁筛选时才加载)
- 字符摘要索引
search-index.json:每块标题的字符集,标题模糊检索先收窄数据块
网页端:单文件架构
整个网站就是一个 HTML 文件,所有 CSS、JS 全部内联:
- 零框架:原生 HTML/CSS/JS
- 零构建:无 Webpack / Vite / Babel
- 零依赖:不引入任何 npm 包
- 本地调试:
python3 -m http.server 8080即可
站点会自动识别本地环境(IS_LOCAL),从相对路径 data/ 加载;部署到 GitHub Pages 等静态托管时自动切换 jsDelivr CDN,无需改代码。
小程序端:微信云开发
小程序与网页端功能完全对等,数据经微信云开发云函数分发:
// 数据云函数路由:分块号 > 140 走第二个函数 function fnForFile(file) { const m = /^(\d{3}).json$/.exec(file); return m && parseInt(m[1], 10) > 140 ? "poemData2" : "poemData"; }
先按诗词数量加权随机选一个数据块,再块内随机抽一首。带关键词/体裁约束时,先用全索引收窄候选块,再流式扫描。
2. 智能搜索
单一搜索框 + 方式切换(按作者 / 按朝代 / 按标题):
- 作者 / 朝代:精确匹配,先用全索引
authors/dynasties字段收窄数据块 - 标题:模糊匹配(包含),先用
search-index.json字符摘要收窄 - 体裁:支持多选,1479 项体裁全量内嵌代码
- 与体裁任意组合
搜索过程实时显示进度(已扫描数据块 / 命中数量),命中关键词加粗高亮,数据块并行加载提速。
3. 分页加载策略
首次加载 20 首,滚动触底自动续载 20 首:
// 单次严格上限 20 条,命中先进缓冲,再按剩余额度上屏 const TARGET = 20; while (added < TARGET && (pendingHits.length || cursor < chunks.length)) { // 先上屏缓冲 → 再并行拉取 6 块 → 溢出进缓冲 }
并行拉取 6 个数据块,命中先进 pendingHits 缓冲,按剩余额度上屏,避免单次超载。
4. Canvas 手绘分享卡片
纯 Canvas 2D 逐字手绘排版:
- 支持 1:1 / 3:4 / 9:16 / 自动比例
- 横排 / 竖排双布局
- 高分辨率输出
- 同一套绘制逻辑网页端和小程序端共用
5. 主题系统
CSS 自定义属性(变量)动态注入:
- 16 种主题配色 × 3 种排版(居中 / 宽屏 / 紧凑)
- 即时切换,无需刷新
- 设置面板分组可折叠
6. 字体加载
思源宋体(Noto Serif SC) 双端生效:
- 网页端:
@fontsource/noto-serif-sc+SerifFallback本地回退 - 小程序端:
wx.loadFontFace全局加载,scopes: ["native", "webview"]让页面和分享图都能用 - jsDelivr → unpkg 双 CDN 降级
四、数据管线
诗词数据来源于开源项目 chinese-poetry/chinese-poetry (MIT License),涵盖全唐诗、全宋诗、宋词、元曲、五代诗词、楚辞、诗经等。
用 Python 重新整理:
pip3 install zhconv python3 tools/convert_chinese_poetry.py
处理步骤:
- 繁体统一转简体(zhconv)
- 清理 PUA 码位与乱码字符
- 切分为 345 个分块(每块 1000 首)
- 生成两级索引
每个分块的诗词对象使用短键名节省体积:
| 键 | 含义 | 键 | 含义 |
|---|---|---|---|
t |
标题 | d |
朝代 |
a |
作者 | y |
体裁 |
c |
正文 |
五、项目数据
- 344,240 首诗词
- 345 个数据分块
- 1,479 种体裁
- 18KB 首次加载(网页端)
- 16 主题 × 3 排版
- 1 个 HTML 文件 = 整个网站
六、本地部署
网页版(30 秒)
git clone https://github.com/ethanthr-dotcom/shihai-the_poetry_ocean.git cd shihai-the_poetry_ocean python3 -m http.server 8080
浏览器打开 http://localhost:8080/ 即可。
微信小程序
- 微信开发者工具导入仓库根目录
- 填入自己的 AppID
- 开通云开发,记下环境 ID 填入
config.js - 右键
poemData/poemData2→ 上传并部署 - 编译运行
七、技术栈总结
| 部分 | 技术 |
|---|---|
| 网页端 | 单文件 HTML(原生 HTML/CSS/JS) |
| 主题系统 | CSS 变量动态注入 |
| 分享图 | Canvas 2D 手绘排版 |
| 字体 | Noto Serif SC + 双 CDN 降级 |
| 数据分发 | jsDelivr CDN / 微信云函数 |
| 小程序 | 原生小程序 + 云开发 |
| 数据管线 | Python(zhconv + 切片 + 索引) |
八、开源协议
- 源代码:MIT License
- 诗词数据:来自 chinese-poetry/chinese-poetry(MIT License)
- 非营利项目,仅供阅读、学习与研究参考
掬古人之诗,养今时之心。
如果这个项目对你有帮助,欢迎 Star ⭐ 支持!
🔗 仓库:https://github.com/ethanthr-dotcom/shihai-the_poetry_ocean
🌐 在线:https://ethanthr-dotcom.github.io/poetry-site/
更多推荐



所有评论(0)