diff --git a/package.json b/package.json index 37cd607..5d6d279 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "ExamAware-docs-next", + "name": "ExamAware-docs", "description": "A project of vuepress-theme-hope", "version": "2.0.0", - "license": "MIT", + "license": "GPL-3.0-only", "type": "module", "scripts": { - "docs:build": "vuepress-vite build src", + "docs:build": "cross-env NODE_ENV=production vuepress-vite build src", "docs:clean-dev": "vuepress-vite dev src --clean-cache", "docs:dev": "vuepress-vite dev src", "docs:update-package": "pnpm dlx vp-update", diff --git a/src/.vuepress/enhanceApp.js b/src/.vuepress/enhanceApp.js new file mode 100644 index 0000000..054bad2 --- /dev/null +++ b/src/.vuepress/enhanceApp.js @@ -0,0 +1,94 @@ +// .vuepress/enhanceApp.js +import * as Sentry from '@sentry/browser'; +import { Vue as VueIntegration } from '@sentry/integrations'; +import { Integrations } from '@sentry/tracing'; + +export default ({ Vue, router }) => { + // 仅在生产环境启用 Sentry + if (process.env.NODE_ENV === 'production') { + // 初始化 Sentry + Sentry.init({ + dsn: 'https://f8ab1b11ab45f86bd6c4237ba16cb5fe@o4508946125619200.ingest.de.sentry.io/4509058673606736', + integrations: [ + // 自动捕获 Vue 组件错误 + new VueIntegration({ + Vue, + attachProps: true, // 记录组件 props + logErrors: false // 关闭控制台错误重复输出 + }), + // 启用性能监控 + new Integrations.BrowserTracing({ + routingInstrumentation: Sentry.vueRouterInstrumentation(router), + tracingOrigins: ['localhost', /^\//] + }) + ], + environment: 'production', + release: 'vuepress-docs@1.0.0', // 需与构建版本一致 + tracesSampleRate: 0.3, // 30%的性能数据采样 + autoSessionTracking: true, // 自动会话跟踪 + beforeSend(event) { + // 过滤敏感信息(示例) + if (event.request?.url) { + event.request.url = event.request.url.replace(/password=[^&]*/, 'password=[REDACTED]'); + } + return event; + } + }); + + // ================= 手动用户行为记录 ================= + + // 1. 路由导航追踪 + router.beforeEach((to, from, next) => { + // 记录面包屑导航 + Sentry.addBreadcrumb({ + category: 'navigation', + message: `Route change: ${from.path} → ${to.path}`, + level: 'info' + }); + next(); + }); + + // 2. 页面访问事件记录 + router.afterEach((to) => { + Sentry.captureEvent({ + message: 'Page View', + level: 'info', + tags: { + route: to.path, + referrer: document.referrer || 'direct' + }, + extra: { + fullPath: to.fullPath, + userAgent: navigator.userAgent + } + }); + }); + + // 3. 全局错误处理器(补充) + window.addEventListener('unhandledrejection', (event) => { + Sentry.captureException(event.reason, { + contexts: { + promise: { + rejection: event.reason?.stack || String(event.reason) + } + } + }); + }); + } else { + console.log('[Sentry] 开发模式已禁用监控'); + } + + // ================= 扩展方法示例 ================= + // 可在 Vue 原型上添加方法供组件调用 + Vue.prototype.$trackEvent = (eventName, payload) => { + if (process.env.NODE_ENV === 'production') { + Sentry.captureEvent({ + message: eventName, + level: 'info', + contexts: { + custom: payload + } + }); + } + }; + }; \ No newline at end of file