关于 architecture-and-design
用于设计和审查 TypeScript Web 应用架构的框架无关技能。它提供可执行的代码结构、状态、类型安全、安全和测试规则,并支持生成、审查与重构任务。
主要功能
- 01生成、审查和重构模式
- 02组件与代码结构规则
- 03类型安全和状态管理指导
- 04安全与前端实践检查
- 05架构和测试原则
适用场景
- 01设计 TypeScript Web 应用
- 02依据架构规则审查拉取请求
- 03在保持行为不变的情况下重构代码
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ danielteles/ awesome-agent-skills --skill architecture-and-design安装后在 Claude Code 中输入/architecture-and-design确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/adr-template.mdreferences/clean-architecture.mdclean-code.mdddd.mdexpressive-logic.mdforms.mdfrontend-practices.mdmicro-frontends.mdpatterns.mdsecurity.mdsolid.mdstate-and-data.mdstructure.mdtesting.mdtype-safety.mdworked-example.md详细介绍
架构与设计 — 基础工程技能
适用于 TypeScript Web 应用的框架无关架构标准、设计原则和结构模式。这些原则适用于 React、Angular、Vue 以及任何基于组件的框架。代码示例使用 React/TSX 作为一种具体语法;每项原则在 Angular 模板或 Vue SFC 中都有对应实现。
构建于。
core-typescript(语言语法)。对于共同主题,此技能决定设计,core-typescript决定语法。react、angular或vue提供框架形式,accessibility提供 UI 视角。只有在任务涉及其层面时才加载相关技能;如果未加载,请运用一般知识处理该层面,不要因此阻塞任务。
此 SKILL.md 可独立使用:下方的 规则集 是完整且可执行的规则清单。每个 references/<topic>.md 都包含对应分组的原理说明和 ❌ / ✅ 代码示例,references/worked-example.md 则包含一轮完整审查;在运行环境允许时,可打开这些文件深入了解。
如何使用此技能
选择与任务相符的模式,并按顺序执行步骤。
| 模式 | 步骤 |
|---|---|
| 生成 — 编写新的组件、钩子或模块 | 1. 编写时应用 solid、clean-code、expressive-logic、type-safety 和 state-and-data。2. 使用判别联合类型建模异步状态(patterns)。3. 在边界处验证外部数据(type-safety)。4. 将规则集作为检查清单逐项检查。交付前修复所有未通过项。 |
| 审查 — 检查拉取请求或差异 | 1. 根据差异检查规则集。2. 按下方的输出格式,为每个未通过项写一条发现。3. 按顺序排列发现:先列 must-fix,再列 consider。4. 如果没有未通过项,用一行说明。不要凭空编造发现。 |
| 重构 — 调整现有代码结构 | 1. 改变结构,保持行为不变。2. 侧重运用 clean-code、expressive-logic 和 state-and-data。3. 每次提交只做一类改动。4. 保持测试通过(testing)。 |
输出格式
每行写一条发现:
<severity> · <topic> · <file>:<line> — <what is wrong>. <the fix as an action>.
<severity>为must-fix(违反此技能中的规则)或consider(安全,但规则更倾向于另一种形式)。<topic>为规则集主题的 slug(state-and-data、type-safety、security等)。
所有模式都适用的规则
- 执行规则时注明规则集主题。
- 说明原因,而不只是规则。“这会导致整个树重新渲染”比“把状态下移”更好。
- 指明规则和改动;不要默默改写作者的代码。
- 原则服务于代码。当两项原则冲突时,选择能让代码更易阅读和修改的方案,并说明原因。
- 如果任务是做决策而非检查差异,请根据
solid、clean-architecture、structure、state-and-data和micro-frontends权衡各个选项,并使用assets/adr-template.md在仓库中记录决策(背景、选项、决策、后果)。
规则集
solid → references/solid.md
- SRP: 将渲染与数据获取、状态转换和领域计算分离(分别放入组件、钩子、服务和纯函数中)。
- OCP: 组件的可变性通过
children、插槽或渲染属性实现,绝不能为每种变体设置一个布尔标志。 - LSP: 自定义基础组件或模拟对象必须遵循其使用者所期望的完整接口。
- ISP: 组件只接收其实际读取的属性,而不是整个领域实体。
- DIP: 业务逻辑和 UI 依赖注入的接口、令牌或上下文,而非具体的客户端、SDK 或
localStorage。
clean-code → references/clean-code.md
- 布尔值以
is/has/should/can命名;函数名以动词开头;每个概念只用一个术语,不使用含义不清的缩写。 - 函数足够短,无需滚动即可读完;参数列表的形式见
core-typescript的 functions。 - 不使用会切换行为的布尔标志参数——改用两个函数。
- 注释说明原因,而不是内容;不保留死代码(注释掉的代码块、未使用的导出、无法到达的分支)。
- 不原地修改参数、属性或状态——构建并返回一个新值。
- 每个错误都要处理或重新抛出——绝不使用空的
catch。
expressive-logic → references/expressive-logic.md
- 不使用
x ? true : false、if (c) return true; else return false,也不与布尔字面值比较。 - 优先使用守卫子句,而不是嵌套条件;所有条件都以肯定形式表述。
- 为较长的布尔链命名(变量或谓词函数)。
- 对手动
&&空值检查链使用?./??(何时??优于||,见core-typescript的 nullability)。 - 为魔法数字和字符串定义具名常量。
- 针对单个值的
if/else if梯级应改用带类型的查找,或使用带有assertNever默认分支的穷尽式switch。
type-safety → references/type-safety.md
- 外部输入以
unknown接收,并在边界处收窄类型;any和类型断言语法规则见core-typescript的 unsafe-types。 - 互斥状态应使用判别联合,而不是包含可选字段的对象。
- 使非法值无法表示:使用
readonly、as const和品牌 ID 类型。 - 网络数据在适配器处根据架构解析,然后映射为领域模型。
- API 类型从契约(OpenAPI、GraphQL codegen、tRPC)生成,而不是手动编写。
- 启动时根据架构验证环境配置和运行时配置。
clean-architecture → references/clean-architecture.md
- 领域核心不导入任何框架、DOM 或网络相关内容。
- 依赖指向内层:UI → 用例 → 领域;基础设施实现领域接口(依赖反转)。
structure → references/structure.md
- 代码按业务功能组织,而不是按技术角色组织(不设
components//services//utils/这样的杂物目录)。 -
features可以导入shared;shared绝不导入features。 - 一个功能不得导入另一功能的内部文件——只能导入其
index.ts、共享状态或路由。 - 使用代码检查器强制执行边界(
eslint-plugin-boundaries、Nx 模块边界)。
patterns → references/patterns.md
- 使用适配器 / 仓储封装第三方库、SDK 或原始 API 响应,并返回领域模型。
- 异步状态应使用带有
status判别字段的判别联合,而不是松散的isLoading/isError/hasData布尔值。
state-and-data → references/state-and-data.md
- 状态与使用它的组件放在一起;只有在第二个组件也需要它时才提升状态。
- 可从属性或其他状态计算出的值应派生得出,而不是存储起来。
- 存放在客户端存储中的服务端集合应规范化——每个实体只存一次,以 ID 为键;查询缓存中的数据则保持获取时的形式。
- 每种状态都应放在合适的层级:服务端缓存库 / URL 参数 / 小型存储或上下文 / 组件。
- 上下文只保存低频变化的值;快速变化的值应放入带有选择器的存储,而不是宽泛的上下文。
- 服务端数据应通过以输入为键的缓存库获取——不要在 effect 中获取后存入本地状态。
- 在使用服务端数据的位置获取数据,而不是从远处的祖先组件逐层传递属性。
- 独立请求应并行加载,而不是形成父级 → 子级的瀑布流。
- 修改数据时根据响应更新缓存;乐观更新应具备回滚路径。
- 为每种查询明确设置过期时间和重试策略。
frontend-practices → references/frontend-practices.md
- 在 return 之前、模板之外计算筛选、映射和链式调用。
- 为每种异步状态建模:加载中、空状态、错误、成功。
- 列表键使用稳定的 ID;对于可能重新排序的列表,绝不使用数组索引。
- 优先使用派生值或事件处理器,而非生命周期副作用;保留的副作用应只处理一件事,并包含清理逻辑。
- 每个独立区域都有自己的错误边界和回退界面,而不只是应用根节点有。
- 取消或忽略过时的异步结果(使用
AbortController或忽略标志)。 - 捕获的错误会连同源映射、发布标签和会话上下文一起发送到跟踪工具。
- 不发布包含
console.log的代码;日志记录统一通过一个结构化日志记录器完成。 - 优先使用语义化元素,而不是带处理器的
div;为每个输入框和仅含图标的控件添加标签。完整检查项见:accessibility。
security → references/security.md
- 不使用不可信输入构建 HTML;必须渲染为 HTML 的内容需先经过清理(DOMPurify)。
- 避免使用
dangerouslySetInnerHTML/[innerHTML]/v-html和所有bypassSecurityTrust*;对每一处保留用法进行审查。 - 打包内容中不包含密钥——第三方密钥应存放在服务端。
- 每个
target="_blank"链接都设置rel="noopener noreferrer"。 - 根据查询参数获取的重定向 URL 必须通过允许列表检查;拒绝来自用户数据的
javascript:或data:URL。 - 有意选择令牌存储方式,并记录其中的权衡。
- CSP 采用强制执行模式,脚本使用基于 nonce 的策略;浏览器支持时使用 Trusted Types。
- 使用 Cookie 身份验证时,每个会改变状态的请求都附带防 CSRF 令牌,并设置
SameSite。 - 第三方
<iframe>设置sandbox,仅授予其所需的功能。 - 添加新依赖前先进行审查(维护情况、传递依赖体积、来源)。
testing → references/testing.md
- 测试套件以集成测试为主:以静态分析为基础,为纯逻辑编写单元测试;组件与协作者测试占较大比重,并在网络边界处进行模拟;端到端测试占较小比重,用于覆盖关键路径。
- 领域和用例:针对普通函数编写快速单元测试,不涉及 DOM 或网络。
- 组件:通过角色和标签查询,并断言用户可见的内容;仅在没有合适的可访问名称时使用
data-testid。 - 对变更涉及的代码行强制执行覆盖率要求,而非要求全局百分比。
- 每个 Bug 修复都附带一个在修复前会失败的测试。
- 对 API 边界进行契约测试,或根据契约生成类型并验证载荷。
- 不稳定的测试首次出现偶发失败时就隔离,并在本迭代内修复。
- 仅对小型、稳定的输出使用快照。
- 每项测试还必须符合
test-quality规则集——断言行为而非实现,包含有意义的断言,且结果确定、不依赖执行顺序。本组规则决定测试套件的整体形态;test-quality评判单项测试。
ddd → references/ddd.md
- 每个概念在代码、测试、UI 和 API 中都使用唯一且统一的名称(到处都用
Cart,而不是Basket/Order)。 - 实体和值对象放在功能的
model/中,不包含框架或网络代码。 - 值对象不可变——修改时创建新实例。
- 只能通过聚合根访问聚合的内部部分。
- 领域事件使用过去时命名,并视为事实,而非命令。
- 每个限界上下文使用独立的模型;在边界处进行转换。
微前端 → references/micro-frontends.md
- 默认采用模块化单体;只有当团队需要独立部署且这确实成为瓶颈时,才进行拆分。
- Shell 与各个远程模块共用一份带版本的契约:一个挂载函数、传入的 props、传出的事件。
- 框架和设计系统作为固定版本的单例共享。
- 远程模块加载失败或抛出异常时,不会导致 Shell 空白。
- 路由和身份验证由 Shell 管理;身份信息向下传递。
表单 → references/forms.md
- 草稿状态保存在表单本地或表单库中,绝不提升到全局状态。
- 在领域模型旁定义一份验证模式,并在客户端和服务端复用。
-
isValid/isDirty/ 各字段错误应从表单状态派生,而不是存储起来。 - 大型表单使用非受控输入和表单库;字段组件的受控 / 非受控契约见
component-api-design。 - 服务端验证错误应映射回对应字段。
- 提交进行中时禁用提交;提交失败后保留已输入的值。
限制
此技能涵盖前端架构和设计,不涵盖:
- 后端、数据库或基础设施设计。
- 分布式系统——微服务、事件驱动后端、Saga。
ddd涵盖单个应用内的战术模式;micro-frontends仅涵盖前端拆分。 - 样式、设计令牌和 CSS 架构——
styling-and-design-tokens。 - 除「语义化元素和标签」之外的无障碍设计——
accessibility。 - 性能预算、Core Web Vitals 和包分析——
web-performance。 - 可复用组件的公共 API(
component-api-design)和国际化(i18n-and-localization)。 - CI 配置、依赖机器人、发布工具和单体仓库设置。
- 特定框架的规则(钩子、记忆化、变更检测、响应性)——
react/angular/vue。
此技能阐述的是原则,不能替代阅读代码并理解领域知识。
参考
此技能与以下内容配合使用:
core-typescript—— 语言基础。对于共同涉及的主题,此技能决定设计,core-typescript决定语法。react/angular/vue—— 这些规则在相应框架中的形式。在 React、Angular 或 Vue 代码库中应用对应规则;若发生直接冲突,以对应规则为准。accessibility—— UI 审查视角:ARIA、键盘和焦点、实时区域、无障碍测试。test-quality—— 此技能的testing组规定测试套件的结构;test-quality评判每个单独的测试。
评论
支持 Markdown