背景
在调试过程中,某些 JavaScript 错误信息容易被忽视。例如,控制台有报错信息,但由于日志量大,可能被迅速刷掉,未能留意;或页面表现正常,误以为自测已完成,而未注意到 JavaScript 报错,从而导致潜在的隐藏 Bug。这会对项目质量产生负面影响。这类报错信息希望能主动展示在一个显眼的位置,以引起开发的重视并及时修复,同时也希望能被动发现这些错误信息。
解决方案
为了解决开发时主动与被动查看错误日志的问题,考虑了以下机制:
- 当控制台出现报错信息时,会将其写入错误日志,并直接在页面上显示,以便开发关注。
- 在提交代码时,使用 Git hook 检查错误日志是否包含内容。如果存在错误日志,将不允许提交代码,必须先检查并处理错误日志后,才能进行提交。
改进效果
在本地开发环境中,若代码出现错误,将直接在页面上直观展示错误信息,并支持跳转编辑器,便于快速定位修复。示意图如下:
同时,系统会将这些报错信息自动保存至项目的根目录,以便后续查阅与分析。
此外,在执行 Git 提交操作时,若检测到日志中存在错误,将禁止提交。
实现细节
实现一个 Vite 插件,向页面注入一段代码,以监听错误信息。当发生错误时,将错误信息发送至 Vite 服务器自定义插件。
function sendErrorToServer(body: { msg: string; host: string; stack: string }) {
fetch('/plugin-capture-error', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
});
}
const HOST = `${window.location.protocol}//${window.location.host}`;
// 捕获全局错误
window.addEventListener('error', event => {
sendErrorToServer({
msg: event.message,
stack: event.error.stack,
host: HOST,
});
});
// 捕获promise未处理拒绝错误
window.addEventListener('unhandledrejection', event => {
sendErrorToServer({
msg: event.reason.message,
stack: event.reason.stack || '',
host: HOST,
});
});
利用 Vite 本身的 WebSocket 通信机制和全局遮罩报错机制,Vite 服务器的自定义插件将这些错误信息推送至浏览器client。client会监听服务端发送的消息,并根据需求进行不同处理;在这里,使用默认的错误遮罩显示,点击路径可以直接通过编辑器打开对应错误的文件和行号。
export default function viteCaptureErrorsPlugin () {
return {
name: 'plugin-capture-error',
enforce: 'pre',
apply: 'serve',
configureServer(server) {
// ...省略处理文件代码
// 发送到vite client,显示到页面上
server.ws.send({
type: 'error',
err: {
message: errorData.msg,
stack: errorData.stack,
plugin: PLUGIN_NAME,
},
});
// ...省略代码
},
};
}
修改 husky 的 pre-commit 提交检查脚本,提交代码时会检查错误日志中是否存在内容,如果存在,则需确认该错误是否影响项目。
# 检查 .log/error.log 是否有内容
if [ -s ".logs/error.log" ]; then
echo ".logs/error.log 文件中包含错误信息,请仔细检查是否已解决所有问题。确认无误后,请清空该文件内容再提交。"
exit 1
fi