## toSentrySetup 使用规则

### 🎯 核心原则

- **按框架按需引入**：根据项目框架选择对应的子路径入口，不要从主入口引入
- **初始化时机**：在应用启动最早阶段调用（`main.ts` / `index.tsx`），确保异常能被捕获
- **DSN 走环境变量**：不要在代码中硬编码 DSN，应从 `import.meta.env` 读取
- **非生产环境禁用**：通过 `enabled` 参数控制，避免开发阶段产生噪音数据

### 📁 推荐项目结构

```
src/
├── utils/
│   └── sentry.ts    # Sentry 初始化封装（推荐）
└── main.ts          # 应用入口，调用 sentry.ts
```

### 🔧 初始化配置

#### Vue 3 推荐配置

```typescript
// src/utils/sentry.ts
import { toVue3SentrySetup } from 'xn-fe-tools/sentry/vue3'
import type { App } from 'vue'
import type { Router } from 'vue-router'

export function initSentry(app: App, router: Router) {
  return toVue3SentrySetup({
    dsn: import.meta.env.VITE_SENTRY_DSN,
    app,
    router,
    environment: import.meta.env.MODE,
    enabled: import.meta.env.PROD,
    // 简化配置（推荐方式，无需导入任何 Sentry 包）
    enableTracing: true,
    enableReplay: true,
    breadcrumbs: { console: false },
  })
}
```

```typescript
// src/main.ts
import { createApp } from 'vue'
import { createRouter } from 'vue-router'
import { initSentry } from './utils/sentry'
import App from './App.vue'

const app = createApp(App)
const router = createRouter({ ... })

// Sentry 必须在 app.mount 前初始化
initSentry(app, router)

app.use(router).mount('#app')
```

#### Vue 2 推荐配置

```typescript
// src/utils/sentry.ts
import Vue from 'vue'
import Router from 'vue-router'
import { toVue2SentrySetup } from 'xn-fe-tools/sentry/vue2'

export function initSentry(router: Router) {
  return toVue2SentrySetup({
    dsn: process.env.VUE_APP_SENTRY_DSN,
    Vue,
    router,
    environment: process.env.NODE_ENV,
    enabled: process.env.NODE_ENV === 'production',
  })
}
```

#### React 推荐配置

```typescript
// src/utils/sentry.ts
import { toReactSentrySetup } from 'xn-fe-tools/sentry/react'

export const sentry = toReactSentrySetup({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  environment: import.meta.env.MODE,
  enabled: import.meta.env.PROD,
})
```

### 📝 使用规范

#### 1. 返回值的使用

```typescript
const { isInitialized, captureException, captureMessage, setUser } = initSentry(app, router)

// 登录后设置用户信息
function onLogin(user: User) {
  setUser({ id: String(user.id), email: user.email })
}

// 登出时清除用户信息
function onLogout() {
  setUser(null)
}

// 手动上报（通常不需要，Sentry 自动捕获未处理异常）
try {
  riskyOperation()
} catch (err) {
  captureException(err)
}
```

#### 2. 高级集成（需要精细控制时）

```typescript
// 使用重新导出的集成函数，无需单独安装 @sentry/vue
import { toVue3SentrySetup, replayIntegration, breadcrumbsIntegration } from 'xn-fe-tools/sentry/vue3'

toVue3SentrySetup({
  dsn: import.meta.env.VITE_SENTRY_DSN,
  app,
  router,
  // 关闭简化配置中的 replay，改用自定义配置
  enableReplay: false,
  integrations: [
    replayIntegration({ maskAllText: false, blockAllMedia: false }),
    breadcrumbsIntegration({ console: false, dom: true }),
  ],
})
```

#### 3. Source Map 上传（vite.config.ts）

```typescript
import { defineConfig } from 'vite'
import { sentryVitePlugin } from '@sentry/vite-plugin' // 需单独安装为 devDependency
import { getSentryViteConfig } from 'xn-fe-tools/sentry/browser'

export default defineConfig({
  plugins: [
    sentryVitePlugin(getSentryViteConfig({
      org: 'my-org',
      project: 'my-project',
      authToken: process.env.SENTRY_AUTH_TOKEN,
    })),
  ],
  build: { sourcemap: true },
})
```

### 🚨 常见错误

| 错误场景 | 错误写法 | 正确写法 |
|---------|---------|---------|
| 从主入口引入 | `import { toVue3SentrySetup } from 'xn-fe-tools'` | `import { toVue3SentrySetup } from 'xn-fe-tools/sentry/vue3'` |
| 硬编码 DSN | `dsn: 'https://abc@sentry.io/123'` | `dsn: import.meta.env.VITE_SENTRY_DSN` |
| 初始化时机过晚 | 在路由守卫中初始化 | 在 `main.ts` 最早位置初始化 |
| 非生产环境上报 | 未设置 `enabled` | `enabled: import.meta.env.PROD` |

### 📋 检查清单

#### 项目初始化时

- [ ] 创建 `src/utils/sentry.ts` 统一封装初始化逻辑
- [ ] DSN 配置在 `.env.production` 中，不提交到代码库
- [ ] `enabled` 设置为仅生产环境启用
- [ ] `main.ts` 中在 `app.mount` 前调用

#### 上线前

- [ ] `vite.config.ts` 配置 Source Map 上传（需安装 `@sentry/vite-plugin`）
- [ ] 验证 Sentry 控制台能收到测试异常
- [ ] 确认 `isInitialized` 为 `true`（生产构建验证）
