feat(devtools): 添加生产环境调试工具系统

新增调试工具目录 src/devtools/,提供完整的生产环境调试能力:

- apiDebugger: 拦截所有 API 请求/响应,记录日志
- notificationDebugger: 测试浏览器通知,检查权限
- socketDebugger: 监听所有 Socket 事件,诊断连接状态
- 全局 API: window.__DEBUG__ 提供便捷的控制台调试命令

功能特性:
- 环境变量控制:REACT_APP_ENABLE_DEBUG=true 开启
- 动态导入:不影响生产环境性能
- 完整诊断:diagnose()、performance()、exportAll()
- 易于移除:所有代码集中在 src/devtools/ 目录

Webpack 配置:
- 添加 'debug' alias 强制解析到 node_modules/debug
- 添加 @devtools alias 简化导入路径
- 避免与 npm debug 包的命名冲突

🔧 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-11-10 17:26:14 +08:00
parent e555d22499
commit c593582006
7 changed files with 935 additions and 0 deletions

View File

@@ -0,0 +1,166 @@
// src/debug/notificationDebugger.js
/**
* 通知系统调试工具
* 扩展现有的 window.__NOTIFY_DEBUG__添加更多生产环境调试能力
*/
import { browserNotificationService } from '@services/browserNotificationService';
class NotificationDebugger {
constructor() {
this.eventLog = [];
this.maxLogSize = 100;
}
/**
* 初始化调试工具
*/
init() {
console.log('%c[Notification Debugger] Initialized', 'color: #FF9800; font-weight: bold;');
}
/**
* 记录通知事件
*/
logEvent(eventType, data) {
const logEntry = {
type: eventType,
timestamp: new Date().toISOString(),
data,
};
this.eventLog.unshift(logEntry);
if (this.eventLog.length > this.maxLogSize) {
this.eventLog = this.eventLog.slice(0, this.maxLogSize);
}
console.log(
`%c[Notification Event] ${eventType}`,
'color: #9C27B0; font-weight: bold;',
data
);
}
/**
* 获取所有事件日志
*/
getLogs() {
return this.eventLog;
}
/**
* 清空日志
*/
clearLogs() {
this.eventLog = [];
console.log('[Notification Debugger] Logs cleared');
}
/**
* 导出日志
*/
exportLogs() {
const blob = new Blob([JSON.stringify(this.eventLog, null, 2)], {
type: 'application/json',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `notification-logs-${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
console.log('[Notification Debugger] Logs exported');
}
/**
* 强制发送浏览器通知(测试用)
*/
forceNotification(options = {}) {
const defaultOptions = {
title: '🧪 测试通知',
body: `测试时间: ${new Date().toLocaleString()}`,
tag: `test_${Date.now()}`,
requireInteraction: false,
autoClose: 5000,
};
const finalOptions = { ...defaultOptions, ...options };
console.log('[Notification Debugger] Sending test notification:', finalOptions);
const notification = browserNotificationService.sendNotification(finalOptions);
if (notification) {
console.log('[Notification Debugger] ✅ Notification sent successfully');
} else {
console.error('[Notification Debugger] ❌ Failed to send notification');
}
return notification;
}
/**
* 检查通知权限状态
*/
checkPermission() {
const permission = browserNotificationService.getPermissionStatus();
const isSupported = browserNotificationService.isSupported();
const status = {
supported: isSupported,
permission,
canSend: isSupported && permission === 'granted',
};
console.table(status);
return status;
}
/**
* 请求通知权限
*/
async requestPermission() {
console.log('[Notification Debugger] Requesting notification permission...');
const result = await browserNotificationService.requestPermission();
console.log(`[Notification Debugger] Permission result: ${result}`);
return result;
}
/**
* 打印事件统计
*/
printStats() {
const stats = {
total: this.eventLog.length,
byType: {},
};
this.eventLog.forEach((log) => {
stats.byType[log.type] = (stats.byType[log.type] || 0) + 1;
});
console.log('=== Notification Stats ===');
console.table(stats.byType);
console.log(`Total events: ${stats.total}`);
return stats;
}
/**
* 按类型过滤日志
*/
getLogsByType(eventType) {
return this.eventLog.filter((log) => log.type === eventType);
}
/**
* 获取最近的事件
*/
getRecentEvents(count = 10) {
return this.eventLog.slice(0, count);
}
}
// 导出单例
export const notificationDebugger = new NotificationDebugger();
export default notificationDebugger;