Hexo 博客工程化实践——从静态站点到三位一体内容平台

项目背景

个人博客最常见的形态是:选一个静态站点生成器(Hexo/Hugo/Jekyll),套一个主题,写 Markdown,部署。这条路能解决 80% 的需求,但当你的博客需要同时承载技术笔记、小说连载、求职项目展示三种不同属性的内容时,标准主题就显得力不从心了。

本文将记录我把 Hexo + 安知鱼主题从一个”能用的博客”改造为”三位一体内容平台”的过程。

技术栈

层面 选型 理由
静态站点引擎 Hexo 7.3 Node.js 生态,插件丰富,主题可定制性强
主题 安知鱼 (AnZhiYu) 设计精良,Pug 模板可扩展,数据驱动架构
评论 Twikoo 自托管,无后端成本,支持 Vercel 部署
部署 GitHub Pages + Actions 零成本,自动部署
内容数据 YAML + JSON (hexo-generator-json-content) 主题数据文件 + API 化访问
自定义 JS Vanilla JS (ES5) 兼容 Pjax,无框架依赖

核心亮点

1. 首页自适应网格布局引擎

标准 Hexo 博客首页是简单的垂直卡片流。我实现了一个六列 CSS Grid 布局,通过动态规划(DP)算法自动计算行分割和排列方案,使横图(3 列宽)和竖图(2 列宽)的卡片能够自动排列成视觉效果最优的布局。

核心算法:

  • 加载每张封面的真实宽高比,通过临时 Image 对象异步获取 naturalWidth/naturalHeight
  • 宽高比 < 1.3 判定为竖图(占 2 列),否则为横图(占 3 列)
  • DP 计算所有可能的行分割方案,以间隙惩罚函数评估优度
  • 对”非置顶”卡片的连续组进行宽度排列搜索,最大化”混合行”减少间隙
  • 未被填满的列用透明 grid-filler 占位,供粒子系统渲染

详见源码:source/js/cover-adaptive.js

2. Canvas 粒子背景系统

在主页网格的空隙中填充动态粒子效果,鼠标靠近时粒子形成环形排列,快速移动时散射。核心特点:

  • 88 个自由漂移粒子,正弦波运动轨迹
  • 鼠标吸引半径 160px,被吸引粒子围绕鼠标形成环形
  • 散射条件:鼠标速度 > 阈值,或鼠标悬浮在内容元素上
  • 粒子间距离 < 130px 时绘制连线,带透明度衰减

详见源码:source/js/particle-filler.js

3. 小说纯净阅读器

为小说阅读设计了一套完全独立的 UI 系统,与博客排版彻底隔离。

功能矩阵:

  • 字体切换(宋体/黑体/楷体)、字号调节(14-26px)、行距(紧凑/标准/宽松)、版心宽度(窄/中/宽)、背景色(跟随主题/护眼黄/护眼绿/纯白)
  • 顶部导航栏:显示章节标题和系列名,随滚动隐藏/显示
  • 右侧章节目录:从 content.json 动态加载,高亮当前章节
  • 底部设置栏:所有阅读参数可调,自动保存到 localStorage
  • 上下章导航按钮:章节间快速跳转
  • 键盘快捷键:ESC 关闭面板,←→ 箭头键切换章节
  • 阅读位置记忆:自动保存和恢复每个章节的阅读进度
  • Pjax 兼容:通过 anzhiyu.addGlobalFn 注册回调

详见源码:source/js/novel-reader.js / source/css/novel-reader.css

4. 数据驱动的页面架构

利用安知鱼主题的 _data 目录和 hexo-generator-json-content 插件,实现了前后端数据分离:

  • _data/*.yml:主题原生格式,驱动关于页、项目集、音乐馆、相册集、朋友圈、友情链接
  • content.json:通过 json_content 配置生成,小说书阁的 JS 组件通过 fetch 获取章节列表
  • 自定义 Helperscripts/novel-helper.js 提供 is_novel_chapter()novel_toc_path() 方法

5. 脚手架定制

创建了专用脚手架模板:

  • scaffolds/novel-chapter.md:小说章节专用,预设 categories: 小说正文index: falseaside: false、版权信息
  • scaffolds/project-post.md:项目文章专用,预设 categories: [技术笔记, 求职项目]、含背景/技术栈/亮点/仓库段落模板

仓库与演示