将 Hexo 升级到 8.1.2,并保留 NexT 原有外观
上一次记录 Hexo 升级已经是很多年前了。这次把博客从 Hexo 7.3.0 升级到了 8.1.2,同时把 Node.js 升级到 24 LTS。NexT 仍然保持 8.21.1,不改主题视觉版本,尽量让升级前后的页面看起来完全一样。
这次最大的变化不是版本号,而是终于不再直接修改 themes/next:主题改为由 npm 管理,配置、头像、图标和页脚运行时间都迁到了站点目录。以后更新依赖时,不用再担心自己的修改被覆盖。
最终版本
- Node.js 24.18.0 LTS
- npm 11.7.0
- Hexo 8.1.2
- NexT 8.21.1
- Gulp 5
Hexo 8 要求 Node.js 20.19.0 或更高版本,具体要求可以查看 Hexo 官方文档。Node.js 各版本的维护状态可以查看 Node.js Releases。
先准备完整回退
博客目录里不只有文章和配置,还有 node_modules、生成后的 public、部署仓库 .deploy_git,以及旧主题目录里的 Git 历史。所以升级前先做了一份完整压缩包,并计算 SHA-256 校验值确认备份可读。
然后在博客根目录建立 Git 基线:
1 | git init |
这样有两层回退:普通配置和源码问题可以直接用 Git 定位;如果依赖、生成结果或部署状态也需要恢复,就使用完整压缩包。
固定依赖和 Node.js 版本
以前升级 Hexo 时用过 npm update,这次没有继续这样做。为了让以后重新安装还能得到同一套环境,在 package.json 中固定主要版本:
1 | { |
同时清理了误列为直接依赖的传递包,只保留真正使用的 Hexo 插件和构建工具。删除旧的 node_modules 后重新安装并提交 package-lock.json,之后可以直接使用:
1 | npm ci |
所有命令都调用项目本地的 Hexo,不再依赖全局安装的 hexo-cli。
NexT 改为 npm 单一来源
旧博客同时保留过多个 themes/next 目录,而且配置和模板里都有手工修改。这样的结构每次升级都要逐个文件比较,很容易漏掉。
这次把 NexT 的设置合并到根目录 _config.next.yml,再删除旧主题目录,让 theme: next 只解析 npm 安装的 NexT。这个方式也是 NexT 官方推荐的安装方式。
头像和 favicon 移到:
1 | source/images/avatar.png |
原来的 URL 没有变化,因此文章和页面不需要修改。
保留“本站已运行”
以前运行时间代码直接写在 NexT 的 footer 模板里,更新主题后很容易丢失。现在通过 NexT 的站点级覆盖文件加载:
1 | custom_file_path: |
footer.njk 只保留显示位置,计时逻辑放进独立的 source/js/running-time.js。这样既不会修改 npm 中的主题文件,也可以继续支持 PJAX 页面切换。
遇到的脚本合并问题
升级完成后,页面一开始出现了三个相关现象:
1 | Cannot read properties of undefined (reading 'ignores') |
最后定位到 hexo-filter-optimize 0.3.1 的 JS 合并功能。它会把 NexT 的 application/json 配置块当成普通 JavaScript,导致 Quicklink 配置和页脚脚本被拼接到一起。
解决办法是关闭这个旧插件的 JS 合并:
1 | filter_optimize: |
CSS 优化仍然保留,HTML 和 CSS 继续由 Gulp 压缩。关闭后 NexT 会按正确顺序加载自己的配置和脚本,运行时间也可以正常显示。
如果看到 busuanzi 或 Google Analytics 的 ERR_ADDRESS_INVALID,可以先检查 DNS。我的本机当时把两个统计域名都解析到了 0.0.0.0,这属于网络拦截,并不是 Hexo 生成失败。
适配 Gulp 5
原来的 Gulp 配置里包含旧的 CommonJS 插件。升级后将 HTML 压缩插件和图片压缩插件改为动态加载,CSS 压缩改用 gulp-clean-css。默认任务只压缩 HTML 和 CSS,图片压缩单独作为可选任务,避免每次发布都重复处理大量图片。
现在常用命令是:
1 | npm run clean |
发布批处理也只组合这些 npm scripts,不再直接调用全局 hexo 或 gulp。
验证结果
最后从空依赖目录执行了完整验证:
1 | npm ci |
结果生成 187 个 HTML,和升级前的路由集合完全一致。首页、文章、归档、标签、关于、404、Atom、站内搜索、百度 sitemap 和普通 sitemap 都存在。
另外还用桌面和移动尺寸检查了首页、文章页、代码块、图片、搜索和 404 页面。NexT Gemini、菜单、头像、favicon、页脚运行时间、阅读进度和返回顶部都正常。升级终于算是完成了。
以后再升级 NexT 时,只需要更新 npm 依赖并检查 _config.next.yml,不需要重新修改主题源码,这应该是这次折腾最有价值的地方。