import 'normalize.css/normalize.css'; import { createApp } from 'vue'; import { createPinia } from 'pinia'; import GlobalComponents from '@/components'; import GlobalDirectives from '@/directives'; import App from './App.vue'; import { router, injectRouter } from '@/router'; import 'vue-devui/style.css'; import '@devui-design/icons/icomoon/devui-icon.css'; import '@/assets/css/main.scss'; import { ThemeServiceInit, infinityTheme } from 'devui-theme'; import { useAccountStore } from '@/stores/user'; import setFurionConfig from '@/utils/setFurionConfig'; import { SkeletonItem } from 'vue-devui/skeleton'; import { ModalHeader } from 'vue-devui/modal'; import Icon from 'vue-devui/icon'; import dInput from 'vue-devui/input'; import { FormOperation } from 'vue-devui/form'; import { Option } from 'vue-devui/select'; import { BreadcrumbItem } from 'vue-devui/breadcrumb'; import { useReport } from '@/utils/hooks/useReport'; import { savePageRef } from '@/utils'; import qs from 'qs'; import * as Sentry from '@sentry/vue'; import { storageApis } from './api/storage-apis'; import { storageService } from './utils/apiStorage'; import { gitCodeTheme } from './utils/theme/gitcodeTheme'; const themeService = ThemeServiceInit({ 'gitcode-theme': gitCodeTheme }, 'gitcode-theme'); themeService?.applyTheme(gitCodeTheme); declare global { interface Window { microApp: any; } } /** * micro-app 微前端 */ import microApp from '@micro-zoe/micro-app'; microApp.start({ 'disable-memory-router': true, // 关闭虚拟路由系统 'disable-patch-request': true, // 关闭对子应用请求的拦截 lifeCycles: { created() { // console.log('created'); }, beforemount() { // console.log('beforemount'); }, mounted() { console.log('fst', performance.now().toFixed()); // 首屏时间 // console.log('mounted'); }, unmount() { console.log('unmount'); }, error(e) { Sentry.captureException(new Error('主站Error:生命周期错误'), { level: 'error', extra: { ...e } }); } } }); microApp.router.setBaseAppRouter(router); microApp.router.beforeEach({ 'micoro-app-homeweb-app': (to, from) => { const toQuery = qs.parse(to.search, { ignoreQueryPrefix: true }); const fromQuery = qs.parse(from.search, { ignoreQueryPrefix: true }); if ( toQuery.type !== fromQuery.type || (from.pathname === '/search' && fromQuery.threadId && !toQuery.threadId && toQuery.type === 'chat') ) { // 设置全局ref savePageRef(to.fullPath); } else if (to.pathname === '/search' && toQuery.type === 'chat' && toQuery.threadId) { const BASE_URL = (import.meta as any).env.VITE_HOST; sessionStorage.setItem('ref', BASE_URL + to.fullPath); } else { savePageRef(to.fullPath); } } }); microApp.router.afterEach({ 'micoro-app-homeweb-app': (to, from) => { const names = { '/': '首页', '/search': '搜索', '/g-star': 'g-star', '/g-star/apply': 'g-star 申请', '/explore': '搜索开源' }; const toQuery = qs.parse(to.search, { ignoreQueryPrefix: true }); if (to.pathname === '/search' && toQuery.type !== 'repo') { // 对话有threadid后上报 if (toQuery.threadId) useReport('pageview', {}, { 'homeweb-page-title': names[to.pathname] }); } else { useReport('pageview', {}, { 'homeweb-page-title': names[to.pathname] }); } } }); storageService.setInstanceName('gitcode'); // 缓存策略表 storageService.setRequestCacheList(storageApis); const app = createApp(App); /** * Sentry 监控系统 */ // const envUrl = (import.meta as any).env.VITE_API_HOST; // const regStr = `/^${envUrl}\/api/`; // const regx = new RegExp(regStr); Sentry.init({ app, dsn: 'https://781b2885e6f66eaca3f260d89ec7bc9b@sentryapp.csdn.net/5', integrations: [ Sentry.browserTracingIntegration({ router }), Sentry.replayIntegration() ], ignoreErrors: [ 'ResizeObserver loop limit exceeded', /^ResizeObserver loop completed with undelivered notifications/ ], // enabled: false, // 禁用全局错误上报 environment: (import.meta as any).env.VITE_ENV, beforeBreadcrumb(breadcrumb, hint) { if (breadcrumb.category === 'fetch' && breadcrumb.data) { if (breadcrumb.data.status_code !== 200) { Sentry.captureException(new Error('主站Fetch错误'), { level: 'error', extra: { ...breadcrumb } }); } } if (breadcrumb.category === 'xhr' && breadcrumb.data) { breadcrumb.data.response = hint?.xhr.response; breadcrumb.data.responseHeaders = hint?.xhr.getAllResponseHeaders(); if (![200, 401, 403].includes(breadcrumb.data.status_code) && !breadcrumb.data.url.includes('https://furiondata')) { Sentry.captureException(new Error('主站Http错误'), { level: 'error', extra: { ...breadcrumb } }); } } return breadcrumb; }, // 采样率 // tracesSampleRate: 0.2, tracesSampler: (trace) => { if (['/', 'home'].includes(trace.transactionContext.name)) { return true; } return false; }, normalizeDepth: 10, // // 错误采样率 sampleRate: 0.5, // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled // tracePropagationTargets: [], // // Capture Replay for 10% of all sessions, // // plus for 100% of sessions with an error replaysSessionSampleRate: 0, replaysOnErrorSampleRate: 0 }); app.use(Icon); app.use(dInput); app.component('gc-option', Option); app.component('gc-skeleton-item', SkeletonItem); app.component('gc-modal-header', ModalHeader); app.component('gc-form-operation', FormOperation); app.component('gc-breadcrumb-item', BreadcrumbItem); app.use(GlobalComponents); app.use(GlobalDirectives); app.use(createPinia()); /* 权限验证 */ const account = useAccountStore(); setFurionConfig({ uid: account?.accountInfo?.id }); // router注入拦截逻辑 injectRouter(router); app.use(router); // 屏蔽警告信息 app.config.warnHandler = () => null; app.mount('#app'); const user_center_url = (import.meta as any).env.VITE_USER_CENTER_HOST; // microApp.preFetch( // [ // { // name: 'user-center', // url: user_center_url, // iframe: true, // level: 2 // } // ], // 5000 // ); console.log('buildTime', BUILD_TIME); // 环境变量-最后一次打包时间,用于知晓正式是否更新