ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Sentry 前端开发规范与实践指南:基于 static/AGENTS.md 的 React 19 + TypeScript 开发手册

Sentry 前端开发规范与实践指南:基于 static/AGENTS.md 的 React 19 + TypeScript 开发手册 Sentry 前端开发规范与实践指南基于 static/AGENTS.md 的 React 19 TypeScript 开发手册【免费下载链接】sentryDeveloper-first error tracking and performance monitoring项目地址: https://gitcode.com/GitHub_Trending/sen/sentrySentry 的static/目录承载着整个 Web 前端的核心代码。这篇指南以仓库根目录下 static/AGENTS.md 为骨架系统梳理 Sentry 前端的技术栈选型、工程目录结构、代码风格红线、数据请求范式、React 渲染纯度约束、设计系统用法、测试方法论与 SDK 埋点规范并结合package.json、rspack.config.ts、src/sentry/features/temporary.py等源码级证据深入讲解其落地细节。读完这篇指南你将掌握在 Sentry 这样的大型监控产品前端中组织页面、发起 API 请求、使用设计系统原语、编写测试以及埋点打标签的完整实战方案也能直接迁移其中的工程实践到自己的 React 项目中。一、为什么需要这份前端开发指南Sentry 是一个典型的前后端分离的大型单体仓库后端是 DjangoPython前端是位于static/目录下的单页应用。正如 static/AGENTS.md 开头所述这份文档是AI Agent 和前端工程师在static/目录下开发时的唯一事实来源source of truth根目录的 AGENTS.md 则提供了跨前后端的通用命令指引。仓库按职责划分了多个 AGENTS.md覆盖不同开发领域工作范围读取的 AGENTS.md前端static/**/*.{ts,tsx,js,jsx,css,scss}static/AGENTS.md后端src/**/*.pysrc/AGENTS.md测试tests/**/*.py、src/**/tests/**/*.pytests/AGENTS.md全局概览与通用命令AGENTS.md二、前端技术栈全景static/AGENTS.md 明确列出了 Sentry 前端的核心技术栈结合 package.json 中的依赖版本可以进一步确认语言TypeScript。规则第 4 条强制“ALWAYS use TypeScript”项目根目录的 tsconfig.json 定义了严格类型检查配置。框架React 19package.json中react: 19.2.3、react-dom: 19.2.3。构建工具RspackWebpack 的替代品配置在 rspack.config.ts。package.json中的build脚本即rspack --config ./rspack.config.ts。包管理pnpmpackageManager: pnpm10.30.2使用pnpm-lock.yaml锁定依赖。状态管理Reflux React QueryTanStack Query。注意这是 Sentry 的过渡期技术状态——Reflux 是历史遗留新代码明确禁止新增 Reflux store见下文代码风格红线。样式方案EmotionCSS-in-JS Less。CSS-in-JS 用于组件级样式Less 文件位于 static/less 目录。测试Jest React Testing LibraryRTL见 jest.config.ts。值得注意的几个非主流选型Oxlint 取代 ESLintoxlint.config.tsoxlint系列依赖Rspack 取代 Webpackrspack/core2.2.0pnpm 取代 npm/yarn。这些都是在工程化上追求性能与规模化的结果。三、重要文件与目录地图static/AGENTS.md 给出了前端代码的完整目录约定这是理解 Sentry 前端组织方式的关键职责路径约定组件static/app/components/{component}/页面视图static/app/views/{area}/{page}.tsx状态存储static/app/stores/{store}Store.tsxAction 创建器static/app/actionCreators/{resource}.tsx工具函数static/app/utils/{utility}.tsx类型定义static/app/types/{area}.tsxAPI 客户端static/app/api.tsx从仓库结构看见 static/app 目录这套约定被严格执行components下按功能分子目录如components/core、components/badge、components/eventsviews下按业务域组织页面。3.1 路由Routing路由统一在 static/app/routes.tsx 定义遵循 React Router v6 模式package.json中react-router-dom: 6.30.3路由组件尽可能懒加载React.lazy(() import(...))。这与 rspack.config.ts 中SHOULD_LAZY_COMPILATION懒编译入口之外的路由的构建优化策略一脉相承——懒加载同时作用于运行时React.lazy按需拆包与编译期Rspack 懒编译节省内存和启动时间。四、前端 API 请求从 useApiQuery 到 apiOptions 的范式迁移static/AGENTS.md 的 Frontend API Calls 一节规定了一个明确的硬性迁移方向使用useQueryapiOptions发起 API 请求永远不要使用已废弃的useApiQuery/getApiQueryData/setApiQueryDatastaleTime是必填参数。虽然useApiQuery在仓库中仍有使用例如 static/app/components/charts/useSessionsRequest.tsx、static/app/components/events/autofix/useAutofixSetup.tsx但这些都属于存量代码新代码一律走apiOptions范式。详细的完整指南条件请求、调用点泛型、响应头/分页由frontend-data-fetching技能.agents/skills/frontend-data-fetching/SKILL.md承载。4.1 基本用法import {skipToken, useQuery} from tanstack/react-query; import {apiOptions} from sentry/utils/api/apiOptions; // 基本用法 const query useQuery( apiOptions.asResponseType()(/organizations/$organizationIdOrSlug/endpoint/, { path: {organizationIdOrSlug: organization.slug}, staleTime: 30_000, }) ); // 条件请求 —— 将 skipToken 作为 path 传入即可禁用该查询 const query useQuery( apiOptions.asResponseType()(/organizations/$organizationIdOrSlug/items/$itemId/, { path: itemId ? {organizationIdOrSlug: organization.slug, itemId} : skipToken, staleTime: 30_000, }) );4.2 关键规则staleTime必填必须显式选择一个值——0、毫秒数、Infinity或static。围绕apiOptions做抽象而不是围绕useQuery返回 options 对象让调用方自行决定传给useQuery、useQueries还是prefetchQuery。缓存存的是{json, headers}而非裸 bodyapiOptions默认用select提取.json但getQueryData、setQueryData、retry函数与predicate回调收到的都是完整的ApiResponseT结构。不要在 Query 中使用api.requestPromise它会返回错误的结构如需手写queryFn改用apiFetch。4.3 类型推断禁止调用点泛型技能文档强调了一个极易踩坑的点——永远不要在useQuery、useMutation、queryOptions、mutationOptions的调用点传类型参数让 TypeScript 从queryFn/mutationFn推断// ❌ 错误给 useMutation/useQuery 传泛型 useMutationResponseType, RequestError, Variables, Context({...}) // ✅ 正确标注 mutationFn让类型从函数签名推断 useMutation({ mutationFn: (variables: MyVariables) fetchMutationMyResponse({...}), })具体规则类型化mutationFn的参数而不是 hook 泛型用fetchMutationT标注返回值错误类型不要显式写成RequestError这本质上是类型断言用if (error instanceof RequestError)做运行时收窄不要显式声明 context 类型让它从onMutate的返回值推断。五、General Frontend Rules五条红线static/AGENTS.md 定义了五条不可逾越的前端规则它们共同决定了 Sentry 前端代码的形态禁止新增 Reflux storeReflux 属于历史遗留状态管理的新代码一律使用 TanStack Query服务端状态 React 内置状态/其他方案客户端状态。禁止类组件全部使用函数组件 Hooks这也与 React 19 的时代背景一致。禁止 CSS 文件优先使用 core 组件[static/app/components/core](https://link.gitcode.com/i/de705a0aecd4ddedc06911ea0859218e)仅在真正边缘的情况下使用 Emotion。必须使用 TypeScript无类型代码不允许进入代码库。测试必须与源码同目录colocate*.spec.tsx紧邻被测组件例如 static/app/components/core/datetime.spec.tsx 紧挨着datetime.tsx。路由懒加载React.lazy(() import(...))。这些规则的价值在于可预见性任何工程师或 Agent 打开一个不熟悉的目录都能根据目录约定和代码形态快速定位组件、视图、store 与测试。六、Refs 使用纪律渲染必须纯净static/AGENTS.md 的 Refs 一节给出了一个非常具体的 React 陷阱——渲染期间读写ref.current会破坏 React 的渲染纯净性render 必须是纯函数而 ref 是 React 不追踪的可变状态。渲染期读 ref 可能在并发渲染下拿到过期值写 ref 则制造了副作用、让 render 变得不纯。正确姿势只在 effectuseEffect/useLayoutEffect或事件处理器/回调里读写ref.current渲染期需要值就从 props/state 派生const或提升到useState/useMemo只有必须跨渲染持久且不触发重渲染的值DOM 节点、定时器、供 effect 后续读取的 previous-value 跟踪才值得用 ref。// ❌ 渲染期间读写 ref —— 副作用 并发渲染下的过期值 function Component({value}: Props) { renderCountRef.current 1; // 渲染期副作用 const previous prevValueRef.current; // 并发渲染下可能过期 prevValueRef.current value; // 渲染期写入 return div{previous}/div; } // ✅ 在 effect 中改 ref渲染值靠派生 function Component({value}: Props) { const prevValueRef useRef(value); useEffect(() { prevValueRef.current value; // 在 effect 中写入 }, [value]); return div{value}/div; }七、UI Patterns 与 Design System7.1 剪贴板复制模式当需要实现高级复制到剪贴板功能如复制 Markdown、JSON 等不同格式时不要为每种格式各做一个按钮而应使用sentry/components/copyAsDropdown源码位于 static/app/components/copyAsDropdown.tsx在一个下拉菜单中提供不同格式选项。这统一了交互模式避免每个页面自造轮子。7.2 设计系统从 sentry/scraps 取原语Sentry 的设计系统核心是sentry/scraps包——优先使用它的核心原语而不是手写 styled components 来做布局和排版。完整参数/token 参考见design-system技能.agents/skills/design-system/SKILL.md。关键约束如下布局用Flex、Grid、Stack、Container禁止手写display: flex/grid。排版用Text和Heading禁止裸用p、span、div或h1–h6。优先组件 props 而非style属性用gap/padding 而不是margin。用响应式 props 替代媒体查询例如{xs: column, md: row}表示在移动端纵排、中等宽度以上横排。布局与排版分离Flex/Grid负责布局Text/Heading负责排版不要耦合在同一个 styled component 里。优先InfoTip/InfoText而非裸Tooltip。新组件要附带*.stories.mdxstory。优先 core 组件static/app/components/core 下已有alert、button、avatar、badge、checkbox、disclosure、form、input、modal、tabs、table、text、tooltip等数十个原语Emotion 只留给真正的边缘场景。7.3 其他核心组件约定头像用static/app/components/core/avatar下的UserAvatar//TeamAvatar//ProjectAvatar/等列表用AvatarList禁止裸img。折叠/展开用核心Disclosure组件不要自己手写 expand/collapse。图标从sentry/icons导入图标文件放在static/app/icons入口见 static/app/icons/index.tsx禁止内联 SVG用 svgo/svgomg 优化。图片通过sentry-images别名webpack loader导入图片放在static/app/images禁止用静态路径引用。八、React 测试RTL 与 MockApiClient前端测试*.spec.tsx、React Testing Library、MockApiClient、路由/网络测试的完整方法论由react-testing技能承载.agents/skills/react-testing/SKILL.md涵盖查询优先级、禁止 mock hook、fixtures 用法、异步断言、网络请求 mock 等主题。工程层面的测试入口在 package.jsonpnpm test-ci file_path运行指定文件例如pnpm test-ci components/avatar.spec.tsxpnpm test为带--watch的开发模式。测试文件与源码同目录存放这是上面五条红线之一。九、Sentry SDK 埋点遵循 OTel/Sentry 约定命名在Sentry.setTag/setContext或 span 的setAttribute之前先检查sentry/conventions是否已有标准命名。复用约定名能保证属性可查询、且与其他生产者SDK、Relay对同一概念发出的数据一致——自定义名字会把同一份数据割裂到两个 key 上。这条规则与后端技能backend-conventions中的 Python 侧规则保持同步因为前端 span 和后端 span 可能描述同一次请求。注意单个名称常量如USER_AGENT_ORIGINAL位于/attributes子路径下而不是包根路径包根只重新导出元数据表——ATTRIBUTE_METADATA每个属性的完整记录简介、类型、别名、废弃状态和ATTRIBUTE_SEARCH_METADATA搜索字段 UI 渲染的描述见 static/app/utils/fields。import {USER_AGENT_ORIGINAL} from sentry/conventions/attributes; // 错误给一个 conventions 已覆盖的概念发明新名字 span.setAttribute(request_user_agent, navigator.userAgent); // 正确使用既有约定名 span.setAttribute(USER_AGENT_ORIGINAL, navigator.userAgent);新增候选命名前先 grepnode_modules/sentry/conventions/dist/attributes.d.ts确认是否存在。这些约定由 OTel 语义约定加上 Sentry 自身的模型生成。十、前后端联动的两条协作规则10.1 Feature FlagsFlagPoleSentry 用 FlagPole 管理功能开关src/sentry/features 目录配置见 src/sentry/features/temporary.py。新功能必须藏在 flag 后面在temporary.py中注册Python 侧用features.has(...)检查前端用organization.features.includes(...)检查。完整的注册/api_expose/测试/灰度流程见feature-flags技能.agents/skills/feature-flags/SKILL.md。从temporary.py源码可以看到 flag 注册的三种作用域与策略组合作用域策略示例SystemFeatureINTERNALorganizations:create默认开启OrganizationFeatureFLAGPOLEorganizations:ai-issue-detection、organizations:authv2-rolloutProjectFeatureFLAGPOLE项目级灰度功能值得注意的细节temporary.py的 docstring 明确警告这些 flag只用于门控新开发功能且注定要被移除CLEAN UP YOUR FEATURE FLAGS!因为遗留 flag 会引入长期理解的复杂度。删除已完成的 flag 或 option 有固定的 PR 顺序需使用remove-option-or-flag技能。10.2 前后端分离部署前端static/与后端src/、tests/不是原子化部署的CI 会强制检查同时改动前后端时必须拆成两个独立 PR前端依赖新的 API 时先合入后端 PR纯测试新增与src/改动放在同一个 PR 是允许的。十一、常用开发命令速查虽然 static/AGENTS.md 主要聚焦代码规范其引用的根目录 AGENTS.md 给出了前端日常命令整理如下# 开发环境 pnpm run dev # 完整 dev server需要先 devservices up pnpm run dev-ui # 仅前端 热重载API 代理到生产 sentry.io # 类型检查检查整个项目不接受文件路径参数不要直接用 tsc pnpm run typecheck # Lint / 自动修复 pnpm run lint:js # 全部 JS/TS pnpm run lint:js components/avatar.tsx # 指定文件 pnpm run fix # 自动修复 # 测试 pnpm test-ci file_path # 运行测试 pnpm test-ci components/avatar.spec.tsx # 指定文件对应的环境准备SENTRY_DEVENV_FRONTEND_ONLY1 devenv sync跳过迁移推荐用于纯前端/pytest 场景、direnv allow、devservices up。前端构建配置 rspack.config.ts 中还支持SENTRY_UI_HOT_RELOAD、ENABLE_TS_CHECKER类型检查资源开销大需显式开启、LAZY_COMPILATION懒编译节省内存和启动时间、USE_TANSTACK_DEVTOOL等环境开关。十二、总结一份可迁移的前端工程实践回顾 static/AGENTS.md 的全部内容它本质上是 Sentry 前端团队多年工程经验的浓缩其可迁移价值在于显式技术栈 目录约定让千人大仓保持可导航性禁止清单文化禁 Reflux、禁类组件、禁 CSS 文件、禁渲染期读写 ref、禁调用点泛型——每条禁令背后都是一个真实的线上教训把复杂决策委托给技能skills数据请求、测试、设计系统、特性开关等主题都有独立技能文档承载完整方法论AGENTS.md 保持精简、可扫描前后端规范对齐埋点命名约定在前后端保持同步保证同一请求的两端数据可关联查询。对于正在构建大型 React 应用的团队这份文档提供了一个经过生产验证的参照系如何用文档约束 Agent 与工程师、如何用目录和红线维持代码一致性、如何用约定名保持遥测数据的可查询性。【免费下载链接】sentryDeveloper-first error tracking and performance monitoring项目地址: https://gitcode.com/GitHub_Trending/sen/sentry创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表