关于 frontend-layered-architecture
frontend-layered-architecture 是用于新建或现有项目的前端分层与依赖决策技能。它定义抽象层并按任务提供对应指引,不强制采用特定架构方法。
主要功能
- 01按职责和依赖关系划分代码
- 02区分前端数据契约与执行逻辑
- 03指导新建和现有项目的决策
- 04分流文档编写与规则强制任务
- 05明确依赖方向
适用场景
- 01判断新增前端代码的归属
- 02检查导入关系和依赖边界
- 03规划前端架构文档
- 04选择强制架构规则的工具
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ choegyumin/ agent-skills --skill frontend-layered-architecture安装后在 Claude Code 中输入/frontend-layered-architecture确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
best-practices.mdbrownfield-guidelines.mdbrownfield.mdenforcing-rules.mdgreenfield-ask.mdgreenfield-propose.mdgreenfield.mdwriting-docs.mdagents/openai.yaml详细介绍
前端分层架构
概述
前端目录结构不应简化为“页面和其他所有内容”。像 components、hooks、models、utils 和 shared 这样能体现类型却无法明确职责的文件夹,可能会吸纳所有代码。这项技能并非为了强行推行大型架构,而是为了避免在实现过程中,业务规则、API 调用、URL 状态及类似逻辑不知不觉地流入不恰当的文件夹。
代码应根据职责、依赖关系、外部数据边界和编排职责划分为不同层。低层代码不得感知高层上下文。
这项技能不强制采用 Feature-Sliced Design 或 Vertical Slice Architecture 等特定方法。基于类型、功能、领域驱动或其他方式组织的目录结构都可以是合理的。关键在于:所选结构中的职责和依赖方向是否清晰,外部数据契约是否隔离,以及代码职责和由前端负责的领域逻辑是否得到了有效管理。
在现有项目中,只有当架构有文档说明、得到用户认可,或能通过职责、依赖关系和数据边界始终如一地辨识时,才应将其视为有意设计。否则,对新增和修改的代码应用这项技能的基准要求,而不是将重复出现的代码放置方式视为权威。
通用基础
如果项目已经使用分层术语,优先采用项目的术语。仅在没有现有术语,或需要说明结构时,才使用以下术语。这些抽象层名称不是默认目录名称;除非用户明确选择这些名称,否则不要将 End-User、Domain、Shared 或 Data 转换为文件夹。
此技能中的抽象分层分类和依赖方向仅适用于前端,不可原样套用于 API 服务端或其他应用。下图和规则描述的是没有项目特定例外时的默认结构。例如,如果在单体代码仓库中,服务端和客户端直接共享 Entities 代码,而不是由客户端使用服务端生成的架构,那么可以将 Domain 放在 Data 下方,使 Data 引用 Domain 中的 Entities。
flowchart TB
End-User --> Domain
Domain --> Shared
End-User --> Data
Domain -. schemas/types by default .-> Data
| 层 | 含义 |
|---|---|
| End-User | 交付给用户的界面。最高层,例如页面和路由,负责处理 UI 流程、数据获取和编排。 |
| Domain | 可复用的业务规则、验证、计算和功能标志,类似于整洁架构中的 Entities。在此技能推荐的基准架构中,Domain 不包含 API 调用和外部服务访问。 |
| Shared | 不依赖任何外部上下文的纯代码。这是最低层。 |
| Data | 外部数据契约和执行边界。与 API 相关的源代码属于此层,并视为前端使用的、由外部拥有的代码,即使这些代码是由前端开发者编写的。 |
这些抽象层是设计合理前端结构所需的最小单位。实际项目可以进一步拆分,但这意味着至少需要四个概念。因此,它们是抽象层。
最低限度的约束:
- 层名称是抽象概念,不是必需的文件夹名称。
- Shared 取决于代码层面的独立性,而非名称是否通用或是否缺少领域词汇。例如,如果
ProductCard只渲染注入的 props,它可以属于 Shared;而看似通用的buildSearchParams,如果依赖路由器状态、API 请求参数、store 状态或业务规则,就不属于 Shared。 - 浏览器、路由器、表单或其他库原语的通用封装,只要应用特定的状态、策略和操作是通过注入提供的,就可以属于 Shared。判断时应看代码了解的应用上下文,而不是它导入的包。
- Data 表示前端像使用外部拥有的代码一样使用的边界;这不意味着文件必须物理上位于外部,或由其他团队编写。例如,OpenAPI 生成的客户端/架构代码,以及手动编写的 API 端点/架构代码,只要前端将它们作为外部契约使用,就都属于 Data。
- Domain 默认只能访问 Data 中的架构/类型,因为声明式数据获取(例如
useQuery风格的 API)会将 Data 的执行、缓存和同步留在 End-User UI 编排中。不要仅仅因为其他语言或框架通常采用不同方向,就改变这一前端默认规则。只有在已记录或获批的项目规则确立了其他方向、现有架构已持续且明确地采用该方向,或用户明确决定采用该方向时,才遵循其他方向。 - 应根据 Data 的实际实现,判断它可以依赖哪些项目模块,而不是为其指定一条通用的单向依赖规则。
- 即使处于同一抽象层,依赖是否有效仍取决于其角色和职责。例如,如果项目将
entities和widgets都映射到 Domain,仍可以禁止entities导入widgets中的 UI 编排代码。 - 如果项目已有记录或获批的文件夹角色,应优先使用这些角色。仅在检查职责或依赖方向是否被违反时,才将它们映射到抽象层;不要用当前文件名、稀疏文件夹或已被不当使用污染的文件夹来替代获批角色。
Purpose Router
用一句话对用户的目的进行分类,然后阅读第一个匹配的文档。不要用此文件替代路由指定的文档。
| 用户目的 | 阅读 |
|---|---|
| 判断或更改现有项目结构,包括添加、删除、重命名或重组目录、文件放置、文件拆分、导入方向或依赖边界决策 | brownfield.md |
| 尚未确定目录/分层结构的新前端项目 | greenfield.md |
架构文档,例如 docs/architecture.md、目录规则、依赖规则或 Mermaid 概览 | writing-docs.md |
eslint-plugin-boundaries、ESLint、CI、导入边界或其他基于工具的架构规则执行方式 | enforcing-rules.md |
| 按主路由文档处理后,文件放置或导入方向仍未解决,或需要对现有项目进行广泛审查时使用的辅助清单 | best-practices.md |
路由规则:
- 根据用户的实际目的选择文档,而不是根据你首先注意到的架构关键词选择。
- 如果请求包含多个目的,则路由到决定下一步用户可见操作的目的。
- 如果 Agent 即将添加或更改基于工具的前端架构规则执行方式,即使用户未要求执行规则,或架构不是本次会话的主要目的,也要阅读
enforcing-rules.md。 - 阅读路由指定的文档后,检查它是否直接解答了用户的目的。如果没有,说明缺少什么,并转到下一个必需的来源,而不是假装该技能已包含答案。
- 在现有代码库中,对于结构决策和用户要求的结构更改,都要阅读
brownfield.md。不要将添加新目录或分层结构的请求视为 greenfield 工作。 - 对现有项目进行广泛审查或评估时,先阅读
brownfield.md,然后仅将best-practices.md中的“常见错误”表作为辅助清单查看。不要将示例用作模板,也不要用示例覆盖项目特定规则。 - 对于具体的文件放置/导入决策或实现工作,默认不要阅读
best-practices.md。