用 MCP 定位并修复 Fluid 的 MathJax startup.document 报错

最近在本地预览(http://localhost:4000)时,进入文章页会在控制台看到一条红色报错:

  • Cannot read properties of undefined (reading 'document')

这次用 Codex CLI + MCP chrome-devtools 复现并定位,最后确认是 Fluid 主题的 MathJax 插件逻辑 与我在 _config.fluid.yml提前注入 window.MathJax 配置 发生冲突导致。

复现步骤(MCP)

  1. 本地已启动 hexo server(默认 http://localhost:4000)。
  2. 使用 MCP chrome-devtools 打开首页 http://localhost:4000/
  3. 点击首页的第一篇文章进入详情页。
  4. 读取控制台消息,出现报错:
1
Cannot read properties of undefined (reading 'document')

定位过程

1) 从报错关键词判断方向

报错是“读取 xxx.documentxxxundefined”。结合页面开启了 MathJax(文章 front-matter math: true),优先怀疑 MathJax 的 startup.document 相关逻辑。

2) 在主题中找到访问点

在主题代码里搜索 startup.document,定位到:

  • node_modules/hexo-theme-fluid/layout/_partials/plugins/math.ejs:29

该文件里有一段逻辑(节选):

1
2
3
4
5
6
7
8
if (!window.MathJax) {
window.MathJax = { /* 默认配置 */ };
} else {
MathJax.startup.document.state(0);
MathJax.texReset();
MathJax.typeset();
MathJax.typesetPromise();
}

也就是说:只要 window.MathJax 在此时“已经存在”,就会走到 else 分支并立即访问 MathJax.startup.document

根因分析

我在 _config.fluid.ymlcustom_head 中写了类似下面的配置(旧写法):

1
2
3
4
5
6
<script>
window.MathJax = {
loader: { load: ['[tex]/physics'] },
tex: { packages: { '[+]': ['physics'] }, tags: 'ams' }
};
</script>

这段“只是想提前塞配置”,但副作用是:

  • math.ejs 看到 window.MathJax 已经有值,误判为“MathJax 已加载”。
  • 于是直接执行 MathJax.startup.document.state(0)
  • 但此时真正的 MathJax 库(tex-mml-chtml.js)还没加载完成,startup 还不存在,最终报错。

修复方案

目标:不要在 MathJax 库加载前,把 window.MathJax 变成一个“真值对象”,但仍然能把自定义配置合并进去。

我采用的做法是:在 custom_head 里用 Object.defineProperty 拦截主题对 window.MathJax 的赋值,然后在 setter 里合并 physicstex.tags = 'ams' 等配置。

  • 代码位置:_config.fluid.ymlcustom_head 段落)
  • 关键点:getter 返回 undefined,确保主题走 if (!window.MathJax) 分支;真正赋值发生在主题设置默认配置时,由 setter 接管并合并。

验证方式

  1. 重启本地服务(例如 npm run serverhexo server)。
  2. 再次进入任意 math: true 的文章页。
  3. 控制台不再出现 startup.document 相关报错;MathJax 自动编号与 physics 扩展正常。

备选方案(不推荐但可用)

也可以直接修改主题文件 node_modules/hexo-theme-fluid/layout/_partials/plugins/math.ejs,把 else 分支改成更严格的判断(例如判断 MathJax.startup && MathJax.startup.document)。

但这属于直接改 node_modules

  • 版本升级/重装依赖后会被覆盖
  • 不利于长期维护

因此更推荐通过 _config.fluid.yml / source/custom/ 这类“可控注入点”解决。


用 MCP 定位并修复 Fluid 的 MathJax startup.document 报错
http://sakura.lsk.icu/2025/12/19/优化日记/2.使用MCP定位并修复MathJax-startup-document报错/
作者
Sakura
发布于
2025年12月19日
许可协议