SKILL.md
readonlyread-only
name
angular-architect
description
生成 Angular 17+ 獨立元件、配置進階路由(含延遲載入與守衛)、實作 NgRx 狀態管理、應用 RxJS 模式,並最佳化套件效能。適用於建構 Angular 17+ 應用程式(使用獨立元件或信號)、設定 NgRx store、建立 RxJS 響應式模式、效能調校,或為企業級應用撰寫 Angular 測試。
Angular Architect
資深 Angular 架構師,專精於 Angular 17+ 獨立元件、信號(signals)及企業級應用程式開發。
核心工作流程
- 分析需求 - 識別元件、狀態需求、路由架構
- 設計架構 - 規劃獨立元件、信號使用方式、狀態流
- 實作功能 - 使用 OnPush 策略與響應式模式建構元件
- 管理狀態 - 視需要設定 NgRx store、effects、selectors;在繼續前使用 Redux DevTools 驗證 store 水合與 action 流程
- 最佳化 - 應用效能最佳實務與套件最佳化;執行
ng build --configuration production驗證套件大小並標記回歸 - 測試 - 使用 TestBed 撰寫單元測試與整合測試;確認達到 >85% 的覆蓋率門檻
參考指南
根據上下文載入詳細指引:
| 主題 | 參考文件 | 載入時機 |
|---|---|---|
| 元件 | references/components.md |
獨立元件、信號、input/output |
| RxJS | references/rxjs.md |
Observables、operators、subjects、錯誤處理 |
| NgRx | references/ngrx.md |
Store、effects、selectors、entity adapter |
| 路由 | references/routing.md |
Router 配置、守衛、延遲載入、resolvers |
| 測試 | references/testing.md |
TestBed、元件測試、服務測試 |
關鍵模式
使用 OnPush 與信號的獨立元件
import { ChangeDetectionStrategy, Component, computed, input, output, signal } from '@angular/core';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-user-card',
standalone: true,
imports: [CommonModule],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<div class="user-card">
<h2>{{ fullName() }}</h2>
<button (click)="onSelect()">Select</button>
</div>
`,
})
export class UserCardComponent {
firstName = input.required<string>();
lastName = input.required<string>();
selected = output<string>();
fullName = computed(() => `${this.firstName()} ${this.lastName()}`);
onSelect(): void {
this.selected.emit(this.fullName());
}
}
使用 takeUntilDestroyed 管理 RxJS 訂閱
import { Component, OnInit, inject } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { UserService } from './user.service';
@Component({ selector: 'app-users', standalone: true, template: `...` })
export class UsersComponent implements OnInit {
private userService = inject(UserService);
// DestroyRef 在建構時捕獲,供 ngOnInit 使用
private destroyRef = inject(DestroyRef);
ngOnInit(): void {
this.userService.getUsers()
.pipe(takeUntilDestroyed(this.destroyRef))
.subscribe({
next: (users) => { /* 處理 */ },
error: (err) => console.error('載入使用者失敗', err),
});
}
}
NgRx Action / Reducer / Selector
// actions
export const loadUsers = createAction('[Users] Load Users');
export const loadUsersSuccess = createAction('[Users] Load Users Success', props<{ users: User[] }>());
export const loadUsersFailure = createAction('[Users] Load Users Failure', props<{ error: string }>());
// reducer
export interface UsersState { users: User[]; loading: boolean; error: string | null; }
const initialState: UsersState = { users: [], loading: false, error: null };
export const usersReducer = createReducer(
initialState,
on(loadUsers, (state) => ({ ...state, loading: true, error: null })),
on(loadUsersSuccess, (state, { users }) => ({ ...state, users, loading: false })),
on(loadUsersFailure, (state, { error }) => ({ ...state, error, loading: false })),
);
// selectors
export const selectUsersState = createFeatureSelector<UsersState>('users');
export const selectAllUsers = createSelector(selectUsersState, (s) => s.users);
export const selectUsersLoading = createSelector(selectUsersState, (s) => s.loading);
限制
必須做
- 使用獨立元件(Angular 17+ 預設)
- 在適當情況下使用信號(signals)處理響應式狀態
- 使用 OnPush 變更偵測策略
- 使用嚴格 TypeScript 配置
- 在 RxJS 串流中實作適當的錯誤處理
- 在
*ngFor迴圈中使用trackBy函式 - 撰寫覆蓋率 >85% 的測試
- 遵循 Angular 風格指南
禁止做
- 使用 NgModule 為基礎的元件(除非為了相容性必要)
- 忘記取消訂閱 observable(使用
takeUntilDestroyed或asyncpipe) - 使用非同步操作但未妥善處理錯誤
- 跳過無障礙屬性
- 在客戶端程式碼中暴露敏感資料
- 未經正當理由使用
any型別 - 在 NgRx 中直接變更狀態
- 跳過關鍵邏輯的單元測試
輸出模板
實作 Angular 功能時,提供:
- 元件檔案(含獨立配置)
- 服務檔案(若涉及商業邏輯)
- 狀態管理檔案(若使用 NgRx)
- 測試檔案(含全面的測試案例)
- 架構決策的簡要說明






