首页
/ Impeccable `/harden` 实战指南:为生产环境加固 AI 生成的界面——错误处理、国际化、文本溢出与边界条件

Impeccable `/harden` 实战指南:为生产环境加固 AI 生成的界面——错误处理、国际化、文本溢出与边界条件

2026-09-07 09:26:42作者:曹令琨Iris

Impeccable 是一套面向 AI 编码代理(Claude、Cursor、Codex、Gemini CLI 等)的设计指南技能(skill),其 harden 命令负责让界面在"不完美数据"下依然可用。本文以仓库中的命令参考文档 skill/reference/harden.md 为骨架,系统讲解如何评估加固需求、沿七个维度实施加固、设计测试策略并最终验收,让前端不再只对理想数据有效。读完你将掌握一套可直接用于生产界面的加固检查表与对应 CSS/JS 实现模式。

为什么需要 harden:真实用户不会提供"完美数据"

设计稿里的一切都恰到好处——文案恰好一行、数据总有值、网络永远在线。但凡是交付给真实用户的产品,都要面对长文本、空数据、断网、报错、慢连接、RTL 语言、超长列表等状况。

.claude/skills/impeccable/reference/harden.md(该文件由 skill/SKILL.src.md 分发,仓库中以 .claude.agent.gemini.cursorplugin/skillsskill 等目录并存多份等价副本)在开篇就给出论断:

Designs that only work with perfect data aren't production-ready. Harden the interface against the inputs, errors, languages, and network conditions that real users will throw at it.

在 Impeccable 的命令体系中,harden 归类于 "Refine"(精修)类别。根据 README.md 的命令表,它负责 错误处理、i18n、文本溢出与边界情况;而在 scripts/lib/skill-categories.js 中,hardenpolishoptimizeonboard 同属更上层的 harden 类别,意思是"把界面打磨到生产可用"。

命令元数据 skill/scripts/command-metadata.json 对其触发场景的界定是:当用户要求"加固(harden)、做到生产可用(make production-ready)、处理边界情况(edge cases)、增加错误态(error states)、修复溢出与 i18n 问题"时使用。典型用法与 README 的示例一致:

/impeccable harden checkout      # Add error handling + edge cases

即:/impeccable harden [target] 对指定目标(如 checkout 流程)做整体加固。

第一步:评估加固需求(Assess Hardening Needs)

动手加固前,先系统性地找出薄弱点。原文档给出三大类评估手段,应逐条对目标界面自问。

1. 极端输入测试

输入类别 具体测试样例
超长文本 很长的名字、描述、标题
超短文本 空字符串、单个字符
特殊字符 emoji、RTL 文本、重音符号
大数字 百万级、十亿级
大量条目 1000+ 条列表项、50+ 个选项
无数据 空状态(empty states)

2. 错误场景测试

  • 网络失败:离线、慢速、超时;
  • API 错误:400、401、403、404、500;
  • 校验错误(validation errors);
  • 权限错误(permission errors);
  • 限流(rate limiting);
  • 并发操作(concurrent operations)。

3. 国际化测试

  • 长翻译文本:德语通常比英语长 30%;
  • RTL 语言:阿拉伯语、希伯来语;
  • 字符集:中文、日文、韩文(CJK)、emoji;
  • 日期/时间格式差异;
  • 数字格式差异(1,0001.000);
  • 货币符号差异。

CRITICAL:Designs that only work with perfect data aren't production-ready. Harden against reality.

值得一提的背景是:Impeccable 不止有 harden 这类 LLM 驱动的指导命令。项目同时内置 61 条确定性检测规则(deterministic detector rules),可由 CLI 与浏览器扩展在不调用 LLM、不需要 API Key的情况下直接运行(见 README.md),并在 UI 文件编辑后由 hook 自动触发,把溢出、遮挡、对比度等问题反馈回来。这意味着"加固"在 Impeccable 里是双通道的:harden 提供方向性指导,检测器规则提供客观回环。仓库测试夹具 tests/fixtures/antipatterns 中就保存着大量待判定样例,例如 text-overflow.htmltext-occlusion.htmlscript-error.htmlbody-text-viewport-edge.html,覆盖了超长文本越界、文本被遮挡、脚本错误引发布局问题等典型反例,可作为加固前后的对照参考。

第二步:沿七个加固维度系统改进

评估完成后,按以下维度逐一加固。每个维度都对应一组可在实际代码中直接落地的模式。

维度一:文本溢出与换行(Text Overflow & Wrapping)

超长文本的三种处理策略——省略号截断、多行截断、允许换行:

/* Single line with ellipsis */
.truncate {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Multi-line with clamp */
.line-clamp {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Allow wrapping */
.wrap {
  word-wrap: break-word;
  overflow-wrap: break-word;
  hyphens: auto;
}

Flex/Grid 容器溢出:flex/grid 子项的默认 min-width: auto 会阻止内容收缩,导致长内容把布局撑破;需要显式放行收缩:

/* Prevent flex items from overflowing */
.flex-item {
  min-width: 0; /* Allow shrinking below content size */
  overflow: hidden;
}

/* Prevent grid items from overflowing */
.grid-item {
  min-width: 0;
  min-height: 0;
}

响应式字号:原文档给出的三条原则值得注意,尤其是与 16px 移动端底线的关系——这是整份技能在 skill/reference/typeset.md(排版指南)中反复强调的可读性下限在加固阶段的延续:

  • 使用 clamp() 实现流式排版(fluid typography);
  • 设定最小可读字号:移动端正文 16px,与排版指南的底线一致;只有真正次要的文本才允许 14px。原因:iOS Safari 会对小于 16px 的聚焦输入框强制放大(force-zoom),从而破坏表单布局;
  • 测试文本缩放(放大到 200%);
  • 确保容器能随文本扩张。

维度二:国际化(i18n)

文本膨胀预算

  • 为翻译文本预留 30%–40% 的空间余量;
  • 用能自适应内容的 flexbox/grid 布局;
  • 用最长的语言(通常是德语)测试;
  • 避免在文本容器上使用固定宽度。
// ❌ Bad: Assumes short English text
<button className="w-24">Submit</button>

// ✅ Good: Adapts to content
<button className="px-4 py-2">Submit</button>

RTL(从右到左)支持:优先使用 CSS 逻辑属性(logical properties)而非物理属性,这样同一份样式在 LTR 与 RTL 下都会自动正确:

/* Use logical properties */
margin-inline-start: 1rem; /* Not margin-left */
padding-inline: 1rem; /* Not padding-left/right */
border-inline-end: 1px solid; /* Not border-right */

/* Or use dir attribute */
[dir="rtl"] .arrow { transform: scaleX(-1); }

字符集支持

  • 全站使用 UTF-8 编码;
  • 用中文/日文/韩文(CJK)字符测试;
  • 用 emoji 测试(单个 emoji 可达 2–4 字节);
  • 覆盖不同书写系统:拉丁、西里尔、阿拉伯文等。

日期/时间与数字格式化:不要手拼格式字符串,交给 Intl API——同一日期在不同 locale 下输出完全不同(1/15/202415.1.2024):

// ✅ Use Intl API for proper formatting
new Intl.DateTimeFormat('en-US').format(date); // 1/15/2024
new Intl.DateTimeFormat('de-DE').format(date); // 15.1.2024

new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
}).format(1234.56); // $1,234.56

复数(pluralization)规则:英语只有单/复数两种形态,而很多语言(如俄语、阿拉伯语)的复数规则复杂得多,靠 count !== 1 ? 's' : '' 拼接必然出错:

// ❌ Bad: Assumes English pluralization
`${count} item${count !== 1 ? 's' : ''}`

// ✅ Good: Use proper i18n library
t('items', { count }) // Handles complex plural rules

维度三:错误处理(Error Handling)

网络错误:展示清晰的错误信息、提供重试按钮、说明发生了什么、如适用则提供离线模式、处理超时场景。错误状态必须带恢复路径,而不是死路:

// Error states with recovery
{error && (
  <ErrorMessage>
    <p>Failed to load data. {error.message}</p>
    <button onClick={retry}>Try again</button>
  </ErrorMessage>
)}

表单校验错误:错误内联显示在字段旁;消息要具体、明确;给出修正建议;不必要地阻断提交;出错时保留用户已输入的内容(不要整表清空)。

API 错误:每个状态码都要有恰当响应:

状态码 界面响应
400 展示校验错误
401 跳转登录
403 展示权限错误
404 展示"未找到"状态
429 展示限流提示
500 展示通用错误并提供支持入口

优雅降级(graceful degradation)

  • 核心功能在无 JavaScript 时也可用;
  • 图片带有 alt 文本;
  • 渐进增强(progressive enhancement);
  • 为不支持的特性提供回退方案。

维度四:边界情况与临界条件(Edge Cases & Boundary Conditions)

空状态(empty states):覆盖"列表无条目 / 搜索无结果 / 无通知 / 无数据可展示"四类空态,并给出清晰的下一步动作。这与 Impeccable 的 onboard 命令(first-run flows、empty states、activation paths,见 README.md)形成互补:onboard 负责设计空态与激活路径的体验,harden 负责确保这些状态在任意缺失数据下都不会崩溃。

加载状态(loading states):覆盖初次加载、分页加载、刷新;说明正在加载什么(如 "Loading your projects...");长操作为用户提供时间预期。

大数据集

  • 分页或虚拟滚动(virtual scrolling);
  • 提供搜索/过滤能力;
  • 做性能优化;
  • 不要一次性加载全部 10000 条数据

并发操作

  • 防止重复提交(加载期间禁用按钮);
  • 处理竞态条件(race conditions);
  • 乐观更新并带回滚(optimistic updates with rollback);
  • 冲突解决(conflict resolution)。

权限状态

  • 无查看权限、无编辑权限、只读模式都要有清晰表现;
  • 明确解释"为什么"。

浏览器兼容性

  • 为新特性提供 polyfill;
  • 为不支持的 CSS 提供回退;
  • 用特性检测(feature detection)而不是浏览器检测(browser detection);
  • 在目标浏览器中实测。

维度五:输入校验与净化(Input Validation & Sanitization)

客户端校验:必填字段、格式校验(email、phone、URL)、长度限制、模式匹配、自定义校验规则。

服务端校验(永远要做):绝不只信任客户端;所有输入都要校验并净化;防范注入攻击;实施限流。

约束处理示例:给输入框明确约束,并用 aria-describedby 关联帮助文本,让约束对辅助技术同样可见:

<!-- Set clear constraints -->
<input
  type="text"
  maxlength="100"
  pattern="[A-Za-z0-9]+"
  required
  aria-describedby="username-hint"
/>
<small id="username-hint">
  Letters and numbers only, up to 100 characters
</small>

维度六:无障碍韧性(Accessibility Resilience)

键盘导航

  • 所有功能都可键盘访问;
  • 逻辑化的 Tab 顺序;
  • 弹窗(modal)中的焦点管理;
  • 长内容提供跳转链接(skip links)。

读屏器支持

  • 恰当的 ARIA 标签;
  • 用 live regions 播报动态变化;
  • 描述性的 alt 文本;
  • 语义化 HTML。

高对比模式

  • 在 Windows 高对比模式下测试;
  • 不只依赖颜色传达信息;
  • 提供替代的视觉线索。

无障碍与性能、响应式一样,同属 Impeccable 中 audit 命令(technical quality checks: a11y, performance, responsive,见 README.md)的检查范围;harden 关注的是让这些能力在异常条件下依然成立——例如错误播报、焦点在异步失败后的去向。

维度七:性能韧性(Performance Resilience)

慢连接

  • 渐进式图片加载(progressive image loading);
  • 骨架屏(skeleton screens);
  • 乐观 UI 更新;
  • Service Worker 提供离线支持。

内存泄漏:卸载时清理事件监听器、取消订阅、清掉定时器/interval、中止未完成的请求(abort pending requests on unmount)——React/Vue 组件卸载后仍然 setState 的报错多源于此。

节流与防抖

// Debounce search input
const debouncedSearch = debounce(handleSearch, 300);

// Throttle scroll handler
const throttledScroll = throttle(handleScroll, 100);

测试策略(Testing Strategies)

加固必须可验证,原文档给出手动与自动化两条路径。

手动测试

  • 用极端数据测试(超长、超短、空);
  • 用不同语言测试;
  • 离线测试;
  • 限速到 3G 模拟慢连接;
  • 用读屏器测试;
  • 纯键盘导航测试;
  • 在旧浏览器上测试。

自动化测试

  • 针对边界情况的单元测试;
  • 针对错误场景的集成测试;
  • 覆盖关键路径的 E2E 测试;
  • 视觉回归测试(visual regression tests);
  • 无障碍测试(axe、WAVE)。

IMPORTANT:Hardening is about expecting the unexpected. Real users will do things you never imagined.

NEVER 清单(加固期间绝对禁止的事项,值得逐条对照自查):

  • 假设输入完美(一切都要校验);
  • 忽视国际化(要为全球用户设计);
  • 错误信息留空泛文案(如 "Error occurred");
  • 忘记离线场景;
  • 只信客户端校验;
  • 文本容器用固定宽度;
  • 假设文本是英文长度;
  • 单个组件出错就阻塞整个界面。

最终验收:Verify Hardening

用真实边界条件做最后一轮地毯式测试:

  • 长文本:用 100+ 字符的名字测试;
  • emoji:在所有文本字段里输入 emoji;
  • RTL:用阿拉伯语或希伯来语测试;
  • CJK:用中文/日文/韩文测试;
  • 网络问题:断开网络、限速连接;
  • 大数据集:用 1000+ 条数据测试;
  • 并发操作:快速连点提交按钮 10 次;
  • 错误:强制触发 API 错误,遍历所有错误状态;
  • 空数据:移除全部数据,测试空状态。

当上述边界情况全部覆盖后,原文档给出的流程收尾是:把成果移交给 /impeccable polish 做最后一遍整体打磨(polish 对应命令参考见 skill/reference/polish.md,负责 final pass、设计系统对齐与发布就绪检查)。

小结:把"加固"沉淀为工作习惯

结合 Impeccable 的整体设计可以看出,harden 不是孤立的一次性操作,而是与 init(沉淀产品事实)、audit(技术质量检测)、onboard(空态与激活路径)、polish(发布前终审)共同构成的产线环节。它解决的是 AI 生成界面最容易暴露的一类缺陷——"只在演示数据下好看"。评估加固需求、沿七维度逐项加固、分层测试、按验收清单放行,四步走完,界面才算真正具备生产资格。建议将这些模式沉淀到团队的通用样式与组件库中(如 .truncate.line-clampmin-width: 0 约定、逻辑属性规范),让每一次新界面生成都默认带上加固基因。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.81 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
920
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.79 K
1.02 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
390