logger.js 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. const isElectron = () =>
  2. typeof window !== 'undefined' &&
  3. window.require &&
  4. window.require('electron')?.ipcRenderer;
  5. // 检测是否在 Cypress 测试环境中
  6. const isTestEnvironment = () =>
  7. typeof window !== 'undefined' && window.Cypress;
  8. let ipcRenderer = null;
  9. if (isElectron()) {
  10. try { ipcRenderer = window.require('electron').ipcRenderer; } catch {}
  11. }
  12. //避免obj是递归引用导致崩溃
  13. function safeStringify(obj) {
  14. const cache = new Set();
  15. return JSON.stringify(obj, (key, value) => {
  16. if (typeof value === 'object' && value !== null) {
  17. if (cache.has(value)) {
  18. return '[Circular]';
  19. }
  20. cache.add(value);
  21. }
  22. return value;
  23. });
  24. }
  25. function proxyLog(level) {
  26. const original = console[level];
  27. return (...args) => {
  28. const msg = args.map(v => typeof v === 'object' ? safeStringify(v) : String(v)).join(' ');
  29. original(...args); // ① 控制台始终打印
  30. // 如果在测试环境中,直接返回,不发送任何网络请求
  31. if (isTestEnvironment()) {
  32. return;
  33. }
  34. if (ipcRenderer) { // ② Electron 环境
  35. ipcRenderer.invoke('write-log', level, msg).catch(() => {});
  36. } else if (typeof fetch !== 'undefined') {
  37. // ③ 纯 Web 或 pkg-static:发一条异步 POST /log,不阻塞、不报错
  38. fetch('/log', {
  39. method: 'POST',
  40. headers: { 'Content-Type': 'application/json' },
  41. body: safeStringify({ level, msg })
  42. }).catch(() => {}); // 404 也不抛错
  43. }
  44. };
  45. }
  46. export const logger = {
  47. log: proxyLog('log'),
  48. warn: proxyLog('warn'),
  49. error: proxyLog('error')
  50. };