关于 angular-best-practices
面向现代 Angular 应用开发者的实践指南,涵盖 TypeScript、信号、组件、性能、无障碍、路由和测试,并列出针对特定库的扩展技能。
主要功能
- 01涵盖 Angular 开发的 112 条规则
- 02信号式组件与响应性
- 03模板和渲染优化
- 04SSR、路由与打包建议
- 05测试和无障碍模式
适用场景
- 01检查组件架构
- 02应用现代 Angular 信号模式
- 03改进 SSR 与路由加载
- 04规划无障碍 Angular 测试
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ alfredoperez/ angular-best-practices --skill angular-best-practices安装后在 Claude Code 中输入/angular-best-practices确认已加载。
附带文件AGENTS.mdevals/evals.json
详细介绍
Modern Angular 最佳实践
这套全面的规则共 112 条,涵盖 TypeScript 严格性、基于信号的响应式、组件架构、模板优化、RxJS 模式、SSR 水合、包优化、无障碍、路由、表单、测试和样式,帮助你构建的每个组件、服务、模板和路由都快速、无障碍、经过测试且易于维护。
以下是按工作内容分类的关键模式。对于边缘情况,或需要获取此处未列出的具体代码示例时,请参阅此技能目录中的 AGENTS.md 参考文件。
组件与信号
组件是构建应用的基础模块。现代 Angular 使用信号实现响应式,这改变了从状态到模板的所有编写方式。
- 使用独立组件,并设置
ChangeDetectionStrategy.OnPush - 使用
input()、output()、model()信号函数,而不是装饰器 - 使用
inject(),而不是构造函数注入 - 使用
signal()管理本地状态,使用computed()管理派生状态 - 当状态应在来源变化时重置,使用
linkedSignal() - 使用
resource()/httpResource()获取异步数据,并利用内置的加载状态 - 仅将
effect()用于副作用,绝不要用它同步状态 - 使用
toSignal()将 RxJS 可观察对象接入基于信号的模板 - 使用
viewChild()/contentChild()信号查询,而不是装饰器 - 使用
host属性,而不是@HostBinding/@HostListener
模板与样式
模板和样式相辅相成,无障碍、布局和性能问题都与二者相关。
- 使用
@if、@for、@switch控制流,而不是结构指令 - 对首屏以下的重型内容使用
@defer - 始终为
@for循环提供track - 对首屏图片使用带
priority的NgOptimizedImage - 使用纯管道,而不是在模板中调用方法
- 对大型列表使用
CdkVirtualScrollViewport - 使用
[class.active]绑定,而不是[ngClass] - 将主题值定义为 CSS 自定义属性
- 使用
prefers-reduced-motion尊重用户的动态效果偏好
服务与 RxJS
服务负责数据流、依赖注入和 RxJS 模式。HTTP、缓存和可观察对象生命周期彼此相关。
- 使用
takeUntilDestroyed()或async管道取消订阅 - 将
catchError放在switchMap内部,以保持外层流继续运行 - 最新值优先时使用
switchMap,忙碌期间忽略后续值时使用exhaustMap - 对共享流使用
shareReplay({ bufferSize: 1, refCount: true }) - 使用
inject()配合InjectionToken管理配置 - 使用 HTTP 拦截器处理横切关注点(身份验证、重试、日志记录)
- 在 API 边界映射 DTO,不要将后端数据结构泄漏到组件中
性能与 SSR
性能规则涉及组件、模板和基础设施。SSR 会影响路由、数据获取和水合策略。
- 使用路由解析器预加载关键数据,消除瀑布式请求
- 延迟加载路由和
@defer重型视图 - 通过独立组件导入实现导入项的摇树优化,而不是使用模块
- 批量读取和写入 DOM,避免布局抖动
- 频繁查找时使用
Map/Set,而不是普通对象 / 数组 - 对大型页面使用增量水合(
@defer (hydrate on ...)) - SSR 使用
provideClientHydration(withEventReplay()) - 按路由设置渲染模式:SEO 页面使用 SSR,仪表板使用 CSR
测试
测试模式同时适用于组件、服务和模板。隔离很重要,但集成上下文也不容忽视。
- 使用组件测试工具,而不是直接查询 DOM
- 创建测试对象工厂,确保测试数据一致
- 测试信号状态变化和模板输出,而不是实现细节
- 使用
jasmine.createSpyObj或jest.fn()模拟服务 - 使用
axe-core或jest-axe测试无障碍
架构与路由
架构决策会影响所有文件类型——路由、模块边界和依赖注入都是结构性问题。
- 每个惰性加载路由对应一个功能
- 使用守卫处理身份验证,使用解析器加载数据,使用
canDeactivate处理未保存的更改 - 对可能紧接着访问的路由使用预加载策略(
QuickLinkStrategy) - 使用
withComponentInputBinding()通过input()绑定路由参数 - 避免使用 barrel 文件重新导出——直接从源文件导入
- 使用基于环境的配置——不要硬编码 URL 或 API 密钥
TypeScript 基础
以下规则适用于所有地方——组件、服务、测试和所有 .ts 文件。
- 在 tsconfig 中使用
strict: true启用严格类型检查 - 避免使用
any;类型不确定时使用unknown,并通过泛型缩小类型范围 - 对仅用于类型的导入使用
import type - 为导出的函数添加显式返回类型
- 对不应修改的数据优先使用
readonly - 使用判别联合表示状态变体
- 对可能失败的操作使用 Result 模式
无障碍
无障碍涉及模板、样式和组件,而不仅仅是 HTML 问题。
- 优先使用语义化 HTML 元素(
<nav>、<main>、<button>) - 使用 ARIA 角色和
aria-live区域呈现动态内容 - 确保所有交互元素都可通过键盘访问
- 对话框和覆盖层使用
cdkTrapFocus - 使用屏幕阅读器和
axe-core进行测试
快速参考
| 模式 | 使用 | 避免 |
|---|---|---|
| 信号输入 | input<T>() | @Input() |
| 信号输出 | output<T>() | @Output() |
| 双向绑定 | model<T>() | 输入 + 输出组合 |
| 依赖注入 | inject() | 构造函数注入 |
| 控制流 | @if、@for、@switch | *ngIf、*ngFor |
| 类绑定 | [class.active] | [ngClass] |
| 变更检测 | OnPush | Default |
| 派生状态 | computed() | Getter |
| 视图查询 | viewChild() | @ViewChild() |
关键代码模式
信号输入和输出(替代装饰器):
name = input<string>(); // @Input() replacement
save = output<Data>(); // @Output() replacement
value = model<string>(); // two-way binding
控制流(替代结构型指令):
@if (user()) { <profile [user]="user()" /> }
@for (item of items(); track item.id) { <card [item]="item" /> }
@defer (on viewport) { <heavy-chart /> }
httpResource 和 resource(基于信号的异步处理):
users = httpResource<User[]>(() => `/api/users?role=${this.role()}`);
data = resource({ request: () => this.id(), loader: ({request}) => fetch(request) });
可选库技能
在此核心技能之外,安装特定库的规则:
| 库 | 技能页面 |
|---|---|
| NgRx | angular-best-practices-ngrx |
| SignalStore | angular-best-practices-signalstore |
| TanStack Query | angular-best-practices-tanstack |
| Angular Material | angular-best-practices-material |
| PrimeNG | angular-best-practices-primeng |
| Spartan UI | angular-best-practices-spartan |
| Transloco | angular-best-practices-transloco |
链接
许可证
MIT
评论
支持 Markdown