Hexo + NexT 老主题排障实录:白屏、菜单 404 与兼容性修复
本文记录 2026-07-30 下午对博客的一次连环排障:页面白屏、菜单 404,根因都是 Hexo 6 与 NexT 5.1.4(2019 年的老主题)之间的兼容性缝隙。修复提交 7be4910、83095a8、a745a2f。
一、症状与根因
1. 页面白屏:只有侧栏外壳,正文一片空白
排查路径值得记录:先用 curl 检查,HTML、CSS、JS 全部 200 且内容正确——服务端”看起来”没问题。最后用无头 Chrome 抓取控制台才定位到:
1 | Uncaught SyntaxError: Unexpected token ',' |
根因是 _config.yml 里写了 tabs: true(布尔值),而主题模板期望对象结构(theme.tabs.enable),渲染页首内联脚本时输出 tabs: , 造成语法错误。该脚本负责定义全局 NexT 对象,它一崩,motion 动画框架全部失效——而 NexT 的机制是 CSS 先把内容设为 opacity: 0,再由 JS 动画淡入,JS 死了,内容就永远透明。
教训:curl 只能验证”服务端吐出的字节”,验证不了”浏览器执行后的结果”。排障第一步应该是 F12 控制台。
2. 菜单点击报 Cannot GET /archives/%20
两个叠加问题:
- 菜单重复:自定义菜单用了中文键(
归档: /archives/),与主题默认菜单的英文键(archives:)是合并而非覆盖,渲染出两套菜单。 - URL 被污染:NexT 5.1.4 菜单值是
路径 || 图标格式,模板用split('||')分离。但 Hexo 6 的url_for()会把空格和竖线百分号编码,编码发生在 trim 之前、split 之前(侧栏模板),于是生成/archives/%20、/archives/%7C%7Carchive这类坏链接。
修复:菜单改用标准键 + 紧凑格式(archives: /archives/||archive,无空格),中文标签交给主题语言文件自动翻译;再加一个 after_render:html 过滤器兜底,清掉 href 里残留的编码竖线。
3. 标签页、分类页 404
Hexo 的生成器插件只生成 /tags/某个标签/ 这类明细页;/tags/、/categories/ 索引页需要手工创建带 type 标记的页面:
1 |
|
这是 NexT 的约定,文档不显眼,容易漏。
二、方法论收获
- 分层验证:服务端字节(curl)→ 浏览器执行(F12 / 无头 Chrome)→ 最终视觉(截图)。每一层都可能藏独立的问题,前一层正常不代表后一层正常。
- 在 WSL 里也能做浏览器级验证:直接调用 Windows 的 Chrome(
/mnt/c/Program Files/Google/Chrome/Application/chrome.exe)无头模式,配合--remote-debugging-port和 puppeteer-core 走 DevTools 协议,可以拿到控制台错误、DOM 状态、计算样式和截图,全程无需离开 WSL。 - 老主题 + 新框架 = 兼容性雷区:NexT 5.1.4 生于 Hexo 3 时代,
url_for编码行为、swig 渲染器独立成插件、theme_config合并语义都变了。这次踩的三个坑(swig 未渲染、tabs: ,语法错误、%20坏链接)全是这类缝隙。 - 截图是最小成本的复现:用户一张白屏截图,配合复现(无头 Chrome 截出同样的白屏),直接把”用户环境玄学”变成了可调试的确定性问题。
三、遗留与建议
老主题的兼容补丁会越攒越多(目前已有 rewrite-images.js、fix-menu-links.js 两个渲染过滤器)。中长期值得考虑升级到 NexT 8(hexo-theme-next 新版,支持 Hexo 6+、模板改回 nunjucks),一次升级换掉所有补丁。短期维持现状即可,所有已知问题均已修复并上线。