Better

Ethan的博客,欢迎访问交流

为什么浏览器标题显示成了一个丑陋的 URL

突然发现之前用 umi 创建的一个管理端项目,在多次点击左侧菜单后,浏览器标题显示成了一个丑陋的 URL,让强迫症的我十分难受,于是开始了坑爹的找错过程。

为什么会显示成 URL

经测试发现,并不是有代码将 document.title 设置成了 url,而是设置成了空字符串,这时候浏览器就自动显示成当前的浏览器 url 了。

排错过程

因为 ant design pro 中使用了 pro-layout 组件,在该组件内部,使用了 react-helmet 的方式去渲染 title(后面的版本好像是自己写了个 useDocumentTitle 的 hook),于是怀疑是不是 pro-layout 里面计算 title 的方式是不是出了问题。

于是定位 pro-layout 源代码,断点调试后,发现计算结果是对的,查看 ant-design-pro 以及 pro-components 社区也并没有找到相关的讨论(其实挺神奇的……)。

既然 pro-layout 没有问题,那么难道是 react-helmet 的问题,后来直觉告诉我,应该不是的,因为这功能都出问题,那 react-helmet issue 肯定早就讨论了,然后并没有。

因此一定还有什么地方对 document.title 进行了修改。因此想到通过劫持的方式,看看是不是被意外修改了,于是使用了 defineProperty,设置如下

Object.defineProperty(document, 'title', {
    set(val) {
        console.log(val);
    }
});

通过打印发现,确实 document.title 会被意外修改为空,那如何定位到具体是那里修改的呢,于是想到了 console.trace() 打印堆栈信息看看,于是设置如下

Object.defineProperty(document, 'title', {
    set(val) {
        console.trace();
        console.log(val);
    }
});

打印出整个的调用链路后,于是定位到是 umi 的问题,问题找到后,就好解决了

问题解决

出现的原因在于 umi 动态生成一段代码,监听路由的改变,找到当前匹配的路由,然后将 title 设置为 route 的 title 属性,如果没有就使用 defaultTitle,如果都没有则设置为空串。

可是我从没配置过 route 的 title 属性的,至于 defaultTitle 更是无从谈起,于是查看了一下 umi 的 issue 和 doc,找到一段关于 title 的描述

  • 你可以通过 config.title 设置 defaultTitle
  • 还可以针对路由设置标题
  • 如果需要自行通过 react-helmet 等方式渲染 title,配 title: false 可禁用内置的 title 渲染机制

于是我配置 title: false,竟然 ts 的类型检测不过,查看他的最新版 ant-design-pro,竟然是通过 @ts-ignore 避过的。

但其实并没有效果,在 issue 中找到一个 feat 是用于修复这个问题,最终更新 umi 后解决。

真的想吐槽下 umi 的 doc 以及 changeLog 的维护



留言