故障排查
本页按症状组织。找到你的现象,按步骤排查。
第一步永远是它
1 | hexo clean && hexo g && hexo s |
hexo clean 能解决大约一半的问题,原因有三:
- 主题的档位样式是构建期生成的,配置改动不会自动重建
- 站点的
public/会残留上次构建的旧文件 - Hexo 的模板缓存会保留已删除的 partial
改完之后在浏览器里用 Ctrl/Cmd + Shift + R 强制刷新,或打开开发者工具勾选”禁用缓存”。CSS/JS 的文件名不含 hash,普通刷新可能仍拿旧文件。
症状索引
| 症状 | 跳到 |
|---|---|
| 页面完全没样式,像纯文本 | 样式完全失效 |
| 主题没生效,还是默认主题的样子 | 主题未生效 |
| 改了配置没变化 | 配置改动不生效 |
| 文档模式左侧栏空的 | 文档侧边栏为空 |
| 点侧栏链接跳到首页 / 不高亮 | 侧栏链接点击异常 |
| 搜索打不开或没结果 | 搜索异常 |
| 手机上布局不对 | 档位与响应异常 |
| 构建报错 | 构建报错 |
| 评论不显示 | 评论不显示 |
| 数学公式 / 图表没渲染 | 公式与图表 |
样式完全失效
现象:页面能打开,但没有任何样式,像一份纯文本文件。
排查顺序:
站点 _config.yml 里 theme: 的值必须与 themes/ 下的目录名完全一致。
1 | ls themes/ # 应看到 xfm 或你自定义的名字 |
1 | theme: xfm # 必须与目录名一致 |
1 | ls themes/xfm/source/css/ # 应有 variables.css、base.css 等 7 个文件 |
若为空或报错”目录不存在”,说明主题被放到了错误的层级——常见错误是 themes/xfm/xfm/... 多套了一层目录。
1 | ls public/css/ # 应有主题的 CSS 文件 |
若 public/css/ 里没有主题文件,说明 Hexo 没识别到主题目录,回到第 1 步。
部署在子目录时,root 必须配套:
1 | url: https://example.com/docs |
本地预览子目录场景:hexo s --root /docs/
主题未生效
现象:站点能构建,但看起来是 Hexo 默认主题(landscape)的样式。
大概率是 theme 配置指向了不存在的目录,Hexo 静默回退到了默认主题。
1 | # 站点 _config.yml |
同时检查:站点根目录下是否还有 _config.landscape.yml 之类的旧配置残留、themes/ 下是否有多个目录但名字不匹配。
配置改动不生效
这是最常见的一类。 档位样式在构建期由 layout/_partials/adaptive-style.ejs 按配置生成,因此:
1 | hexo clean # 必须执行 |
只在 hexo s 下热改配置是不会重建档位样式的。
配置优先级:
1 | 主题默认值 < themes/xfm/_config.yml < 站点 _config.yml 的 theme_config |
检查站点 _config.yml 里是否已有 theme_config 块,它可能覆盖了你改的项。
1 | # 站点 _config.yml |
YAML 里 false 加引号会变成非空字符串,在 JS 里是真值:
1 | toc: "false" # ❌ 实际被当作 true |
主题内部的 bool() 归一化对 'false' 字符串做了特殊处理,但并非所有配置项都走了这条路径。稳妥起见:布尔值不加引号。
1 | primary: #4f6bed # ❌ "#" 是 YAML 注释符,值变成 null |
文档侧边栏为空
现象:mode: docs 下,左侧栏显示”暂无文档目录”或完全空白。
正确的路径是站点的 source/_data/docs.yml:
1 | ls source/_data/docs.yml |
常见错误:
| 错误位置 | 问题 |
|---|---|
themes/xfm/source/_data/docs.yml |
放在了主题里,不会被读取 |
source/_data/docs.yaml |
扩展名必须是 .yml |
source/data/docs.yml |
少了 _ 前缀 |
用一个 YAML 校验器检查,或直接看 hexo g 的输出有没有解析警告。最常见的三个错误:
1 | # ❌ 用了 Tab 缩进 |
侧边栏有内容但点击后跳到首页,说明 path 与实际 URL 不一致。
1 | # 确认页面的真实 URL |
1 | # docs.yml 里必须一致 |
尾部的 / 会被归一化(有无均可),但目录名拼写、前缀缺失会导致失配。
当 docs.yml 不存在、主题自动生成侧边栏时,没有 title 的页面不会出现。给每篇文档补上:
1 |
|
侧栏链接点击异常
现象:侧边栏能显示,但点击后跳到首页,或当前项不高亮。
根因:docs.yml 的 path 与页面的实际 URL 归一化后不相等。
定位方法:
- 打开一个文档页,在控制台执行:
1 | document.body.className |
若包含 side-nav-sticky / side-nav-offcanvas,说明文档模式已识别。
- 在 Elements 面板找到侧栏链接,看它的
href:
1 | <a class="xfm-nav-link" href="/docs/xfm/intro/">主题简介</a> |
- 对比浏览器地址栏的路径。两者去掉
index.html与首尾斜杠后应完全一致。
路径归一化规则(normalizePath):
1 | /docs/xfm/intro/index.html → /docs/xfm/intro/ |
因此尾斜杠与 index.html 都不影响匹配,但拼写错误不行。
搜索异常
/search.json 请求 404。确认索引已生成:
1 | hexo clean && hexo g |
若文件不存在,检查:
1 | search: |
以及站点根目录 package.json 是否包含 hexo 字段——没有这个字段,Hexo 不会加载主题的生成器:
1 | { |
按顺序检查:
- 索引里有你搜的内容吗?
1 | # 直接在索引文件里搜关键词 |
- 没有 → 内容可能落在
search.content_length之外(正文后半段不索引),或该页面没有title - 有 → 前端脚本未加载,检查
search.js是否 404
快捷键由 core.js 全局监听。可能原因:
- 当前档位下搜索被
disable: [search]之类配置隐藏(搜索没有单独的 disable 键,但search.enable: false会移除入口) - 浏览器扩展占用了
Ctrl+K(某些浏览器把Ctrl+K绑定为地址栏搜索) - 焦点在输入框内——主题的监听仍然有效,但部分扩展会拦截
试试直接用导航栏的 🔍 按钮。
档位与响应异常
浏览器曾在 localStorage 里写下 xfm-tier,会覆盖自动探测。在控制台执行:
1 | localStorage.removeItem('xfm-tier'); |
或者:
1 | XFM.adaptive.clearTier(); |
1 | adaptive: |
三种方式:
1 | ① URL 参数(临时,不改任何状态) |
推荐用 ① URL 参数——不留下持久状态,适合截图与调试。
这是预期行为。strategy: adaptive 时,UA 判定优先于宽度:桌面浏览器即使窗口缩到 400px,UA 仍非移动设备,会按宽度降档;但手机浏览器无论窗口多宽都会被 UA 判定为 mobile。
想让它像传统响应式一样只看宽度:
1 | adaptive: |
1 | adaptive: |
giscus 的三个前置条件缺一不可:
- 仓库公开
- 已安装 giscus GitHub App
- 已在仓库创建对应的 Discussions 分类
到 giscus.app 重新生成配置,核对 repo_id 与 category_id 是否复制完整(这两串较长,容易漏字符)。
公式与图表
- 确认
vendors.math不是none - 确认
vendors.math_auto_render: true - 确认 CDN 可访问——公式库从 jsDelivr 加载,网络受限时不会渲染
- 检查语法:Markdown 里下划线
_可能被当作斜体标记
1 | 风险写法:$a_1 + a_2$ |
- 查看控制台是否有 KaTeX 的
ParseError
- 确认
vendors.mermaid: true - 打开控制台,看是否有动态
import()失败(同样是 CDN 可达性问题) - 检查语法:第一行必须直接是声明语句,不能有空行
1 | graph LR ← 第一行必须是这个 |
- 节点文字含
:(),时用引号包裹:A["标签: 说明"] - 主题的 Mermaid 渲染在
DOMContentLoaded时触发,若你的内容由 JS 动态插入,图表不会被自动渲染——需手动调用:
1 | await window.__xfmLoadMermaid(); |
还是不行?
收集以下信息后到仓库提 issue:
- 现象:期望什么、实际什么
- 复现步骤:从
hexo clean开始的最小复现路径 - 环境:
node -v、npx hexo version的输出 - 配置:相关的
_config.yml片段(隐去敏感信息) - 控制台输出:浏览器控制台的完整报错(含堆栈)
- 构建日志:
hexo g的完整输出
评论