frontend-bugfix
npx skills add https://github.com/penkzhou/swiss-army-knife-plugin --skill frontend-bugfix
Agent 安装分布
Skill 文档
Frontend Bugfix Workflow Skill
æ¬ skill æä¾å端æµè¯ bugfix ç宿´å·¥ä½æµç¥è¯ï¼å æ¬é误åç±»ä½ç³»ã置信度è¯åç³»ç»å TDD æä½³å®è·µã
é误åç±»ä½ç³»
å端æµè¯å¤±è´¥ä¸»è¦å为以ä¸ç±»åï¼æé¢çæåºï¼ï¼
1. Mock 屿¬¡å²çªï¼71%ï¼
çç¶ï¼Mock ä¸çæï¼ç»ä»¶è¡ä¸ºå¼å¸¸
è¯å«ç¹å¾ï¼
- åæ¶åå¨
vi.mockåserver.use - Hook è¿åå¼ä¸é¢æä¸ç¬¦
- API è°ç¨æªè¢«æ¦æª
è§£å³çç¥ï¼éæ©åä¸ Mock å±
// é项 Aï¼HTTP Mockï¼æ¨èç¨äºéææµè¯ï¼
server.use(
http.get('/api/data', () => HttpResponse.json({ data: 'test' }))
);
// é项 Bï¼Hook Mockï¼ç¨äºåå
æµè¯ï¼
vi.mock('@/hooks/useData', () => ({
useData: () => ({ data: 'test', isLoading: false })
}));
2. TypeScript ç±»åä¸å¹é ï¼15%ï¼
çç¶ï¼ç±»åé误ãMock æ°æ®ä¸å®æ´
è¯å«ç¹å¾ï¼
as anyæç±»åæè¨- 缺å°å¿ éåæ®µ
- ç±»åå®ä¹è¿æ¶
è§£å³çç¥ï¼ä½¿ç¨å·¥å彿°
const createMockData = (overrides?: Partial<DataType>): DataType => ({
id: 1,
name: 'default',
...overrides
});
3. 弿¥æ¶åºé®é¢ï¼8%ï¼
çç¶ï¼æµè¯é´ææ§å¤±è´¥
è¯å«ç¹å¾ï¼
- 缺å°
await - 使ç¨
getByèéfindBy - setTimeout åç«å³æè¨
è§£å³çç¥ï¼æ£ç¡®çå¾
// Before
render(<Component />);
expect(screen.getByText('Loaded')).toBeInTheDocument();
// After
render(<Component />);
expect(await screen.findByText('Loaded')).toBeInTheDocument();
4. ç»ä»¶æ¸²æé®é¢ï¼4%ï¼
çç¶ï¼ç»ä»¶æªæé¢ææ¸²æ
è¯å«ç¹å¾ï¼
- æ¡ä»¶æ¸²æä¸è§¦å
- ç¶ææ´æ°æªåæ
- Props ä¼ éé误
è§£å³çç¥ï¼éªè¯æ¸²ææ¡ä»¶åç¶æ
5. Hook ç¼åä¾èµé®é¢ï¼2%ï¼
çç¶ï¼Hook è¿åè¿æ¶æ°æ®
è¯å«ç¹å¾ï¼
useEffectä¾èµæ°ç»ä¸å®æ´useMemo/useCallbackç¼åé®é¢- éå é·é±
è§£å³çç¥ï¼æ£æ¥å¹¶ä¿®å¤ä¾èµæ°ç»
置信度è¯åç³»ç»
è¯åæ åï¼0-100ï¼
| åæ° | çº§å« | è¡ä¸º |
|---|---|---|
| 80+ | é« | èªå¨æ§è¡ |
| 60-79 | ä¸ | æ è®°éªè¯åç»§ç» |
| 40-59 | ä½ | æå询é®ç¨æ· |
| <40 | ä¸ç¡®å® | 忢æ¶éä¿¡æ¯ |
置信度计ç®
置信度 = è¯æ®è´¨é(40%) + 模å¼å¹é
(30%) + ä¸ä¸æå®æ´æ§(20%) + å¯å¤ç°æ§(10%)
è¯æ®è´¨éï¼
- é«ï¼æä»£ç è¡å·ãå æ ãå¯å¤ç°
- ä¸ï¼æé误信æ¯ä½ç¼ºä¸ä¸æ
- ä½ï¼ä» ææ¨¡ç³æè¿°
模å¼å¹é ï¼
- é«ï¼å®å ¨å¹é å·²ç¥æ¨¡å¼
- ä¸ï¼é¨åå¹é
- ä½ï¼æªç¥é误类å
ä¸ä¸æå®æ´æ§ï¼
- é«ï¼æµè¯ä»£ç + æºä»£ç + é ç½®
- ä¸ï¼åªææµè¯ææºä»£ç
- ä½ï¼åªæé误信æ¯
å¯å¤ç°æ§ï¼
- é«ï¼ç¨³å®å¤ç°
- ä¸ï¼å¶å
- ä½ï¼ç¯å¢ç¸å ³
TDD æµç¨
RED Phaseï¼å失败æµè¯ï¼
// 1. æç¡®ææè¡ä¸º
it('should display error when API fails', async () => {
// 2. è®¾ç½®å¤±è´¥åºæ¯
server.use(
http.get('/api/data', () => HttpResponse.error())
);
// 3. 渲æç»ä»¶
render(<DataComponent />);
// 4. æè¨ææç»æ
expect(await screen.findByText('Error loading data')).toBeInTheDocument();
});
GREEN Phaseï¼æå°å®ç°ï¼
// åªå让æµè¯éè¿çæå°ä»£ç
// ä¸è¦ä¼åï¼ä¸è¦æ·»å é¢å¤åè½
REFACTOR Phaseï¼éæï¼
// æ¹å代ç ç»æ
// ä¿ææµè¯éè¿
// æ¶é¤éå¤
è´¨éé¨ç¦
| æ£æ¥é¡¹ | æ å |
|---|---|
| æµè¯éè¿ç | 100% |
| 代ç è¦çç | >= 90% |
| æ°ä»£ç è¦çç | 100% |
| Lint | æ é误 |
| TypeCheck | æ é误 |
常ç¨å½ä»¤
# è¿è¡å端æµè¯
make test TARGET=frontend
# è¿è¡ç¹å®æµè¯
make test TARGET=frontend FILTER=ComponentName
# è¦ççæ£æ¥
make test TARGET=frontend MODE=coverage
# 宿´ QA
make qa
ç¸å ³ææ¡£
ææ¡£è·¯å¾ç±é
ç½®æå®ï¼best_practices_dirï¼ï¼ä½¿ç¨ä»¥ä¸å
³é®è¯æç´¢ï¼
- æµè¯æä½³å®è·µï¼å ³é®è¯ “testing”, “best-practices”
- Mock çç¥ï¼å ³é®è¯ “mock”, “msw”, “vi.mock”
- é®é¢è¯æï¼å ³é®è¯ “troubleshooting”, “debugging”
- å®ç°æåï¼å ³é®è¯ “implementation”, “guide”