关于 angular-architect
Angular Architect 是面向 Angular 团队的开发技能,帮助设计和维护大型应用,涵盖现代架构、状态管理、迁移与性能实践。
主要功能
- 01大型 Angular 应用架构
- 02Signals 与 Standalone Components
- 03NgRx 状态管理
- 04RxJS 模式与指导
- 05性能优化
适用场景
- 01规划 Nx Monorepo 或微前端
- 02将 NgModules 迁移到 Standalone Components
- 03为 Angular 功能选择状态管理方案
- 04检查性能与变更检测
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ 404kidwiz/ claude-supercode-skills --skill angular-architect安装后在 Claude Code 中输入/angular-architect确认已加载。
详细介绍
Angular 架构师
用途
提供企业级 Angular 开发专业知识,专注于 Angular 16+ 特性(Signals、独立组件)、RxJS 响应式编程,以及大规模 NgRx 状态管理。使用性能优化和现代架构模式设计大型 Angular 应用。
适用场景
- 规划大型 Angular 应用(Monorepo、微前端)
- 使用 Signals 实现细粒度响应式(Angular 16+)
- 将旧版模块(NgModule)迁移到独立组件
- 使用 NgRx 或 NgRx Signal Store 设计复杂的状态管理
- 优化性能(无 Zone、OnPush、水合)
- 使用 Nx 或 Turborepo 搭建企业级 CI/CD
2. 决策框架
状态管理策略
What is the complexity level?
│
├─ **Local State (Component)**
│ ├─ Simple? → **Signals (`signal`, `computed`)**
│ └─ Complex streams? → **RxJS (`BehaviorSubject`)**
│
├─ **Global Shared State**
│ ├─ Lightweight? → **NgRx Signal Store** (Modern, functional)
│ ├─ Enterprise/Complex? → **NgRx Store (Redux)** (Strict actions/reducers)
│ └─ Entity Collections? → **NgRx Entity**
│
└─ **Server State**
└─ Caching/Deduplication? → **TanStack Query (Angular)** or **RxJS + Cache Operator**
架构模式
| 模式 | 用例 | 优点 | 缺点 |
|---|---|---|---|
| Standalone | 15+ 的默认选择 | 样板代码更少,可摇树优化 | 旧版开发者需要经历学习曲线 |
| Nx Monorepo | 多应用企业项目 | 共享库、受影响构建 | 工具链复杂 |
| Micro-Frontends | 不同团队/技术栈 | 独立部署 | 运行时复杂,共享依赖问题严重 |
| Zoneless | 高性能 | 无 Zone.js 开销 | 需要显式变更检测 |
警示信号 → 升级给 performance-engineer:
- 频繁出现 “ExpressionChangedAfterItHasBeenCheckedError”
- 初始加载包体积 > 5MB
- 变更检测周期持续运行(Zone.js 反复触发)
- RxJS 订阅中存在内存泄漏(忘记使用
takeUntilDestroyed)
工作流 2:NgRx Signal Store(现代状态管理)
目标: 以比 Redux 更少的样板代码管理功能状态。
步骤:
-
定义 Store
import { signalStore, withState, withMethods, patchState } from '@ngrx/signals'; export const UserStore = signalStore( { providedIn: 'root' }, withState({ users: [], loading: false, query: '' }), withMethods((store) => ({ setQuery(query: string) { patchState(store, { query }); }, async loadUsers() { patchState(store, { loading: true }); const users = await fetchUsers(store.query()); patchState(store, { users, loading: false }); } })) ); -
在组件中使用
export class UserListComponent { readonly store = inject(UserStore); constructor() { // 查询发生变化时自动加载(Effect) effect(() => { this.store.loadUsers(); }); } }
工作流 4:无 Zone 应用(Angular 18+)
目标: 移除 Zone.js,以缩小包体积并改善调试体验。
步骤:
-
引导配置
// main.ts bootstrapApplication(AppComponent, { providers: [ provideExperimentalZonelessChangeDetection() ] }); -
状态管理(仅使用 Signals)
- 不要手动调用
ApplicationRef.tick()。 - 所有状态都使用
signal()。 - 事件会自动触发变更检测。
- 不要手动调用
-
集成
- RxJS: 使用
AsyncPipe(仍然有效)或toSignal。 - 计时器:
setInterval不会自动触发 CD。请在计时器中更新signal。
- RxJS: 使用
核心能力
企业级 Angular 架构
- 设计大型 Angular 应用架构
- 实现模块化设计模式(Nx monorepo、微前端)
- 为团队制定编码标准和最佳实践
- 创建可扩展的文件夹结构和模块组织方式
现代 Angular 开发
- 使用 Signals 实现细粒度响应式(Angular 16+)
- 将基于旧版 NgModule 的代码迁移到独立组件
- 使用 OnPush 和无 Zone 策略优化变更检测
- 利用 Angular 新特性(可延迟视图、水合)
状态管理
- 为企业应用设计 NgRx Store 架构
- 实现 NgRx Signal Store,进行轻量级状态管理
- 针对复杂需求创建自定义状态管理方案
- 使用 TanStack Query 或 RxJS 模式集成服务端状态
性能工程
- 使用 tree-shaking 和延迟加载优化包大小
- 实现代码拆分和差分加载
- 创建性能监控和指标收集机制
- 为大型 Angular 应用制定优化策略
5. 反模式与注意事项
❌ 反模式 1:嵌套订阅(“回调地狱”)
表现形式:
this.route.params.subscribe(params => {
this.service.getData(params.id).subscribe(data => {
this.data = data; // Manual assignment
});
});
问题所在:
- 存在竞态条件(如果参数快速变化)。
- 存在内存泄漏(如果未取消订阅)。
正确做法:
- SwitchMap:
this.data$ = this.route.params.pipe( switchMap(params => this.service.getData(params.id)) ); - 在模板中使用
AsyncPipe或toSignal。
❌ 反模式 2:在模板中编写逻辑
表现形式:
<div *ngIf="user.roles.includes('ADMIN') && user.active && !isLoading">
问题所在:
- 难以测试。
- 每个变更检测周期都会运行。
正确做法:
- 计算信号 / Getter:
isAdmin = computed(() => this.user().roles.includes('ADMIN'));<div *ngIf="isAdmin()">
❌ 反模式 3:SharedModule 臃肿
表现形式:
- 一个庞大的
SharedModule,导入所有内容(Material、Utils、Components)。
问题所在:
- 会破坏 tree-shaking。
- 会增大初始包的体积。
正确做法:
- 独立组件: 在组件的
imports: []数组中仅导入所需内容。
7. 质量检查清单
架构:
- 独立组件: 新功能不使用
NgModules。 - 延迟加载: 所有功能路由均采用延迟加载(
loadComponent)。 - 状态: 局部状态使用 Signals,共享状态使用 Store。
性能:
- 变更检测: 所有位置均启用
OnPush。 - 包: 初始包 < 200KB。
- 延迟渲染: 对首屏以下的重型组件使用
@defer。
代码质量:
- 严格模式: 在 tsconfig 中设置
strict: true。 - 无订阅: 使用
AsyncPipe或toSignal,而非.subscribe()。 - 安全: 验证输入,未经清理不得使用
innerHTML。
示例
示例 1:企业级电商平台架构
场景: 一家零售公司需要设计一个大型电商平台,以处理 100K+ 并发用户,并为商品目录、购物车、结账和用户管理设置独立模块。
架构决策:
- Nx 单体仓库结构:拆分为应用(storefront、admin、api)和共享库(ui、utilities、data-access)
- 状态管理:使用 NgRx Signal Store 管理购物车/用户状态,使用 TanStack Query 管理服务端状态
- 性能策略:对首屏以下内容使用可延迟视图,全局使用 OnPush,为功能模块启用延迟加载
- 支持微前端:配置 Module Federation,以便将来进行拆分
关键实现细节:
- 使用 Signals 实现购物车服务,包含计算得出的总计和持久化状态
- 使用 TanStack Query 缓存并对商品目录进行乐观更新
- 使用多步骤向导和表单验证实现结账流程
- 管理面板采用独立的构建和部署流水线
示例 2:从旧版 NgModule 迁移到 Standalone
场景: 一家金融服务公司拥有一个使用 NgModules 的 Angular 应用,已有 5 年历史,希望将其升级到 Angular 18 并使用 Standalone Components。
迁移策略:
- 渐进式方法:一次迁移一个功能模块,绝不让应用无法运行
- 依赖分析:使用
ng-dompurify查找所有模块依赖项 - 组件转换:将组件转换为 standalone,并正确导入依赖项
- 服务重构:移除模块级的 providedIn,使用根级或功能级注入
迁移结果:
- 通过摇树优化,将初始包大小减少了 40%
- 消除了 200 多行样板 NgModule 代码
- 将变更检测性能提升了 60%
- 支持采用新的 Angular 功能(defer blocks、zoneless)
示例 3:使用 Signals 构建实时仪表板
场景: 一家 SaaS 公司需要一个监控仪表板,以 1 秒为间隔显示实时指标,并要求实现细粒度响应式,同时不受 Zone.js 的开销影响。
实现方法:
- 无 Zone 启动:启用实验性的无 Zone 变更检测
- 基于 Signal 的状态:通过 Signals 管理所有仪表板状态
- RxJS 互操作:使用 toSignal 将 Observables 转换为 Signals
- WebSocket 集成:将更新直接推送到 Signals
性能结果:
- 包大小减少了 30%(无需 Zone.js)
- 变更检测周期的性能提升了 50%
- 复杂数据可视化场景下可流畅实现 60 fps 更新
- 变更检测日志更清晰,调试体验更佳
最佳实践
架构设计
- 为扩展而设计:编写代码前规划文件夹结构和模块边界
- 采用 Standalone:所有新开发默认使用 Standalone Components
- 全部延迟加载:功能模块、路由和大型组件
- 职责分离:智能容器与简单展示组件分开
- 定义边界:明确各层(数据、领域、展示)之间的接口
状态管理
- 局部状态 = Signals:使用 signal() 和 computed() 管理组件级状态
- 全局状态 = Signal Store:使用 NgRx Signal Store 管理共享的功能状态
- 服务端状态 = TanStack Query:切勿手动管理服务端状态缓存
- 避免订阅:使用 AsyncPipe、toSignal 或 takeUntilDestroyed 模式
- 不可变更新:状态变更时始终创建新的引用
性能工程
- 全面使用 OnPush:所有组件默认使用 ChangeDetectionStrategy.OnPush
- 延迟加载:对大型组件和依赖项使用 @defer blocks
- 优化图片:延迟加载图片,并使用现代格式(WebP、AVIF)
- 分析包大小:定期分析 webpack 包,找出冗余内容
- 有策略地预加载:预加载关键路由,其余内容全部延迟加载
代码质量
- 严格模式:启用并保持 TypeScript 严格模式
- 严格空值检查:未经显式处理,绝不允许 undefined/null
- 记录 API 文档:为公共方法和接口编写清晰的 JSDoc
- 集中配置:将功能开关和环境配置集中在一处
- 自动化代码检查:使用包含 Angular 专属规则和自动修复功能的 ESLint
测试策略
- 单元测试:使用 Jest 或 Vitest 测试组件和服务
- 集成测试:使用 Cypress 或 Playwright 测试关键用户流程
- 测试覆盖率:业务逻辑覆盖率目标为 80% 以上
- 组件测试:使用 Angular Testing Library 进行行为测试
- 端到端冒烟测试:每次部署都运行自动化冒烟测试
评论
支持 Markdown