--- name: frontend-safe-development description: Use before creating, modifying, adjusting, debugging, or refactoring browser-based web frontend code, including components, pages, styles, client state, browser interactions, and accessibility, even for small UI fixes. Preserve the project's stack and deliver the smallest safe change with proportionate verification. Not required for read-only lookup, explanation, analysis, or static code review; use if that work turns into browser frontend debugging or edits. Do not use for mobile, desktop, or cross-platform app projects. --- # 前端安全开发 沿用项目技术栈,交付可访问、可恢复且不泄露秘密的最小完整改动。以下是按任务选用的约束,不是每次都要执行的全量整改清单。 ## 先确定影响范围 - 读取适用的项目规则、相关实现和已有改动;先理解用户要求与当前行为,不覆盖他人修改。 - 沿相关调用方和数据流确认影响到的组件、样式、状态、接口契约与测试;只读取和修改完成任务需要的部分。 - 复用项目现有框架、语言、包管理器、目录、组件、hooks、工具、类型、设计令牌和依赖。优先使用已有组件,其次选语义化 HTML、CSS 与浏览器原生能力。 - 选择最小完整方案;不顺带迁移技术栈、升级依赖、重构无关代码或修复无关历史问题。仅当缺失信息会改变行为、接口或安全边界且无法从项目确认时询问,其他部分继续推进。 ## 实现时按改动选择约束 ### 组件、类型与状态 - 延续项目组件模式和错误处理,保持单一职责和最少 props、状态;不重复保存可推导状态,不直接修改 props 或共享数据。 - 使用 TypeScript 时保持类型安全,不用 `any`、类型断言或关闭规则掩盖可建模的问题;在实际信任边界按现有机制校验输入与外部数据,避免逐层重复校验。 - effect、订阅、计时器和事件监听器有对应清理;异步回调避免使用陈旧状态或更新已失效页面。 - 列表使用稳定且真实唯一的 key;会重排、插入或删除的列表不使用数组索引。只在真实复用或复杂度已经出现时提取抽象。 ### HTML、交互与无障碍 - 交互使用原生 `button`、`a`、`input` 或项目中具有相应语义的组件;按钮明确 `type` 和名称,表单控件具有关联标签,仅图标按钮具有可访问名称。 - 保证目标功能可用键盘操作,保留可见焦点。涉及弹层时按项目组件模式处理初始焦点、关闭和焦点返回;模态弹层还需约束焦点,避免进入背景。 - 图片提供合适的 `alt`,装饰图片用空 `alt`;ARIA 只补充原生语义。状态不能只靠颜色表达,文本与背景保持可读;动态错误和状态变化让辅助技术能感知。 ### 布局与视觉 - 使用现有设计令牌、间距、字体和断点;延续项目样式方案,避免无依据的魔法值和全局覆盖,不因使用内联样式而改写项目既有的动态样式模式。 - 在项目目标视口内保持内容可读、控件可操作;关注窄屏、长文本和溢出。纯桌面 Web 项目按既定支持范围验证,不擅自新增移动版布局。 - 优先用 CSS 实现布局、响应式和视觉状态,只有需要运行时信息时才增加 JavaScript。动画尊重 `prefers-reduced-motion`。 ### 异步、表单与恢复 - 覆盖改动涉及的加载、空数据、错误、成功、禁用和提交中状态,不给无关组件补齐全部状态。 - 按场景防重复提交;对搜索、切换筛选等可重叠请求,使用项目已有的取消或响应有效性检查,防止旧响应覆盖新结果。取消请求不能保证服务端写入未发生。 - 可恢复错误保留用户输入并允许安全重试;对结果未知或有副作用的写入,不盲目自动重试,沿用项目的幂等或结果确认机制。结果未确认且没有幂等保障时,阻止再次写入;仅显示警告但仍可直接重复提交不算安全恢复。 - 错误按现有方式反馈,保留非敏感诊断信息;不把原始响应、凭据或用户隐私直接展示或写入日志。 ### 信任边界与性能 - 将用户输入、URL 参数和外部数据视为不可信;前端校验用于交互反馈,权限、身份与关键业务校验由服务端保障,不能用隐藏按钮替代授权。 - 默认以文本渲染内容;必须渲染富文本时复用已有可靠清洗机制,不用正则自制 HTML 清洗。外部数据进入链接、跳转等 URL 接收点时,按用途限制协议与目标,防止可执行 URL 或开放重定向。 - 凭据、服务端秘密和不应公开的数据不得进入客户端代码、公开环境变量、构建产物或日志;需要秘密的调用沿用服务端通道。 - 避免重复请求、无意义渲染和超大资源。图片尺寸合理,适用时原生懒加载;不将首屏关键图片一律懒加载。只在有证据时增加缓存、记忆化或复杂状态管理。 - 先确认所依赖的清洗、服务端通道、幂等或结果查询机制确实存在。缺失时采用满足需求的安全最小方案,例如将不可信内容按文本渲染;不能以客户端代码替代服务端秘密或授权保障。若需求确实依赖新增接口或依赖,说明必要范围并按已有授权推进;缺失前提只阻断受影响部分,不虚构机制或盲目重试。 ## 用最小充分证据验证 先查看项目脚本与相关测试,按实际影响选择检查;文案或 CSS 若影响可访问名称、内容隐藏、焦点或交互命中区域,也要验证相应行为。项目规则明确要求的检查照常执行。验证通过后,没有新改动、失败或未决风险就结束,不重复扩大检查。 | 改动 | 优先验证 | | --- | --- | | 文案、颜色、间距等局部展示 | 相关格式或 lint 检查(若已有),目标页面外观、可读性和必要视口;不为纯样式变更新建逻辑测试 | | 组件行为、表单、状态或异步逻辑 | 现有设施中的最小回归测试、相关 lint 与类型检查;检查受影响的键盘、焦点、状态和恢复路径 | | 共享组件、路由、依赖、构建配置或跨模块契约 | 扩大到受影响调用方的测试和类型检查,按影响运行构建;遵循仓库必跑检查 | | 仅调试、尚未修改 | 先复现并收集证据,区分观察与推断;按任务需要运行诊断,不把调试自动变成重构 | - 逻辑修复的回归测试应能在旧行为下失败,并在修复后通过;断言用户可观察行为,不绑定内部函数、变量或调用次数等实现细节(重复写入等次数本身属于业务约束时除外);没有测试设施时不擅自搭建,使用可复现步骤或现有工具验证并说明缺口。 - 有可用浏览器时检查实际目标交互;涉及响应式才覆盖相应视口。不能运行浏览器或命令时,明确未验证范围,不把静态阅读说成运行通过。 - 遇到失败,区分本次引入、既有失败与环境阻塞;不为消除无关失败扩大修改,也不绕过检查。 - 交付时简述改动、原因、实际执行的检查及结果;有失败时列出命令、原因和未验证范围。只报告适用的内容,不输出整份清单。