React SSR项目如何实现Sentry在客户端和服务端共用统一接口
React SSR项目跨端统一Sentry接口实现方案
核心思路
你之前方案的问题根源是:Webpack构建阶段会把所有静态import的模块都纳入打包范围,哪怕你写了运行时的环境判断,@sentry/node的Node原生依赖也会被带入客户端构建流程,导致解析失败。
我们只需要在构建阶段就隔离两端的Sentry依赖,同时对外暴露完全一致的调用接口,就可以实现和@sentry/nextjs一样的跨端使用体验。
具体实现步骤
1. 分环境封装Sentry实现
创建两个独立的Sentry封装文件,对外导出完全一致的方法名:
客户端实现 sentry.client.js
import * as Sentry from '@sentry/browser' import { BrowserTracing } from '@sentry/tracing' // 初始化方法 export const init = (options = {}) => { Sentry.init({ dsn: '你的Sentry DSN', integrations: [new BrowserTracing()], tracesSampleRate: 1.0, ...options }) } // 统一导出常用方法,和服务端保持同名 export const captureException = Sentry.captureException export const captureMessage = Sentry.captureMessage export const setUser = Sentry.setUser
服务端实现 sentry.server.js
import * as Sentry from '@sentry/node' // 初始化方法 export const init = (options = {}) => { Sentry.init({ dsn: '你的Sentry DSN', tracesSampleRate: 1.0, ...options }) } // 导出和客户端完全同名的方法 export const captureException = Sentry.captureException export const captureMessage = Sentry.captureMessage export const setUser = Sentry.setUser
2. 配置Webpack环境别名
在你的Webpack客户端、服务端两份构建配置中,分别给Sentry封装路径设置不同的别名,构建时自动替换为对应环境的实现:
客户端Webpack配置
const path = require('path') module.exports = { // 其余配置保持不变 resolve: { alias: { // 替换为你实际的文件路径 '@/utils/sentry': path.resolve(__dirname, './src/utils/sentry.client.js') } } }
服务端Webpack配置
const path = require('path') module.exports = { // 其余配置保持不变 resolve: { alias: { // 和客户端用同一个别名,指向服务端实现 '@/utils/sentry': path.resolve(__dirname, './src/utils/sentry.server.js') } } }
3. 项目中统一使用
之后在项目任意位置导入Sentry时,都统一导入你配置的别名路径即可,不需要再做环境判断:
// 任意业务文件、组件中都可以这么写 import * as Sentry from '@/utils/sentry' // 直接调用方法,两端自动适配 try { // 业务逻辑 } catch (err) { Sentry.captureException(err) }
额外注意事项
- 初始化操作分别在两端入口执行:客户端初始化在hydrate执行前调用,服务端初始化在服务启动时调用即可
- 可以配合React ErrorBoundary统一捕获组件渲染异常,调用
Sentry.captureException上报,两端都能正常运行 - 如果使用TypeScript,可以额外编写一份
.d.ts类型定义,统一约束两端导出的方法类型,避免类型不一致的问题
内容的提问来源于stack exchange,提问作者Gena
相关产品推荐
相关产品推荐

