skillstore-cli 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -0
- package/data/bundles/devflow-complete.json +19 -0
- package/data/free-skills/devflow-agile/manifest.json +19 -0
- package/data/free-skills/devflow-agile/plugin/commands/agile/retro.md +23 -0
- package/data/free-skills/devflow-agile/plugin/commands/agile/review.md +21 -0
- package/data/free-skills/devflow-agile/plugin/commands/agile/sprint.md +30 -0
- package/data/free-skills/devflow-agile/plugin/commands/agile/standup.md +20 -0
- package/data/free-skills/devflow-agile/plugin/commands/agile.md +35 -0
- package/data/free-skills/devflow-agile/plugin/commands/devflow.md +42 -0
- package/data/free-skills/devflow-agile/plugin/skills/developer/SKILL.md +93 -0
- package/data/free-skills/devflow-agile/plugin/skills/developer/assets/sample-output.md +182 -0
- package/data/free-skills/devflow-agile/plugin/skills/developer/references/clean-architecture.md +361 -0
- package/data/free-skills/devflow-agile/plugin/skills/developer/references/clean-code-guide.md +207 -0
- package/data/free-skills/devflow-agile/plugin/skills/developer/references/debugging-methodology.md +191 -0
- package/data/free-skills/devflow-agile/template/agents/agile-coach.md +76 -0
- package/data/free-skills/devflow-agile/template/workflows/agile-sprint-workflow.md +81 -0
- package/data/free-skills/devflow-bootstrap/manifest.json +8 -0
- package/data/free-skills/devflow-bootstrap/plugin/commands/bootstrap/auto.md +31 -0
- package/data/free-skills/devflow-bootstrap/plugin/commands/bootstrap.md +38 -0
- package/data/free-skills/devflow-bootstrap/plugin/commands/devflow.md +20 -0
- package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/SKILL.md +56 -0
- package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/assets/sample-output.md +216 -0
- package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/references/architecture-decisions.md +254 -0
- package/data/free-skills/devflow-bootstrap/plugin/skills/project-scaffold/references/stack-templates.md +400 -0
- package/data/free-skills/devflow-bootstrap/template/agents/bootstrap-specialist.md +56 -0
- package/data/free-skills/devflow-bootstrap/template/workflows/bootstrap-workflow.md +70 -0
- package/data/free-skills/devflow-docs/manifest.json +8 -0
- package/data/free-skills/devflow-docs/plugin/commands/devflow.md +20 -0
- package/data/free-skills/devflow-docs/plugin/commands/docs/generate.md +17 -0
- package/data/free-skills/devflow-docs/plugin/commands/docs/parse.md +19 -0
- package/data/free-skills/devflow-docs/plugin/commands/docs.md +26 -0
- package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/SKILL.md +59 -0
- package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/assets/sample-output.md +114 -0
- package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/references/extraction-techniques.md +115 -0
- package/data/free-skills/devflow-docs/plugin/skills/pdf-processor/references/ocr-strategies.md +167 -0
- package/data/free-skills/devflow-docs/template/agents/docs-specialist.md +35 -0
- package/data/free-skills/devflow-docs/template/workflows/docs-workflow.md +70 -0
- package/data/free-skills/devflow-postproject/manifest.json +13 -0
- package/data/free-skills/devflow-postproject/plugin/commands/devflow.md +34 -0
- package/data/free-skills/devflow-postproject/plugin/commands/postproject/handover.md +21 -0
- package/data/free-skills/devflow-postproject/plugin/commands/postproject/retro.md +21 -0
- package/data/free-skills/devflow-postproject/plugin/commands/postproject/support.md +21 -0
- package/data/free-skills/devflow-postproject/plugin/commands/postproject.md +32 -0
- package/data/free-skills/devflow-postproject/plugin/skills/retrospective/SKILL.md +70 -0
- package/data/free-skills/devflow-postproject/plugin/skills/retrospective/assets/sample-output.md +79 -0
- package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/facilitation-techniques.md +178 -0
- package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/lessons-learned-template.md +118 -0
- package/data/free-skills/devflow-postproject/plugin/skills/retrospective/references/retro-techniques.md +100 -0
- package/data/free-skills/devflow-postproject/template/agents/transition-manager.md +71 -0
- package/data/free-skills/devflow-postproject/template/workflows/transition-workflow.md +72 -0
- package/data/free-skills/devflow-presale/manifest.json +15 -0
- package/data/free-skills/devflow-presale/plugin/commands/devflow.md +47 -0
- package/data/free-skills/devflow-presale/plugin/commands/presale/analyze.md +30 -0
- package/data/free-skills/devflow-presale/plugin/commands/presale/estimate.md +30 -0
- package/data/free-skills/devflow-presale/plugin/commands/presale/price.md +30 -0
- package/data/free-skills/devflow-presale/plugin/commands/presale/propose.md +30 -0
- package/data/free-skills/devflow-presale/plugin/commands/presale.md +42 -0
- package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/SKILL.md +63 -0
- package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/assets/sample-output.md +129 -0
- package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/references/extraction-framework.md +140 -0
- package/data/free-skills/devflow-presale/plugin/skills/requirement-analysis/references/output-template.md +132 -0
- package/data/free-skills/devflow-presale/template/agents/presale-lead.md +83 -0
- package/data/free-skills/devflow-presale/template/agents/proposal-reviewer.md +63 -0
- package/data/free-skills/devflow-presale/template/workflows/presale-workflow.md +70 -0
- package/data/registry/categories.json +7 -0
- package/data/registry/packages.json +184 -0
- package/data/shared/framework/agents/brainstormer.md +74 -0
- package/data/shared/framework/agents/code-reviewer.md +87 -0
- package/data/shared/framework/agents/debugger.md +84 -0
- package/data/shared/framework/agents/docs-manager.md +55 -0
- package/data/shared/framework/agents/git-manager.md +59 -0
- package/data/shared/framework/agents/planner.md +68 -0
- package/data/shared/framework/agents/researcher.md +66 -0
- package/data/shared/framework/agents/tester.md +65 -0
- package/data/shared/framework/commands/cook/auto.md +27 -0
- package/data/shared/framework/commands/cook.md +45 -0
- package/data/shared/framework/commands/fix/ci.md +21 -0
- package/data/shared/framework/commands/fix/test.md +26 -0
- package/data/shared/framework/commands/fix/types.md +29 -0
- package/data/shared/framework/commands/fix.md +26 -0
- package/data/shared/framework/commands/git/cm.md +37 -0
- package/data/shared/framework/commands/git/pr.md +40 -0
- package/data/shared/framework/config/CLAUDE.md.template +26 -0
- package/data/shared/framework/config/settings.json +41 -0
- package/data/shared/framework/config/skillstore.config.json +29 -0
- package/data/shared/framework/hooks/discord-notify.sh +85 -0
- package/data/shared/framework/hooks/docs-sync.sh +53 -0
- package/data/shared/framework/hooks/modularization-hook.js +103 -0
- package/data/shared/framework/hooks/notification.js +94 -0
- package/data/shared/framework/hooks/quality-gate.js +109 -0
- package/data/shared/framework/hooks/scout-block.js +77 -0
- package/data/shared/framework/hooks/telegram-notify.sh +77 -0
- package/data/shared/framework/protocols/error-recovery.md +80 -0
- package/data/shared/framework/protocols/orchestration-protocol.md +112 -0
- package/data/shared/framework/quality/review-protocol.md +76 -0
- package/data/shared/framework/quality/verification-protocol.md +66 -0
- package/data/shared/framework/rules/development-rules.md +75 -0
- package/data/shared/framework/skills/backend-development/SKILL.md +77 -0
- package/data/shared/framework/skills/backend-development/assets/sample-output.md +175 -0
- package/data/shared/framework/skills/backend-development/references/advanced-patterns.md +180 -0
- package/data/shared/framework/skills/backend-development/references/api-design-guide.md +160 -0
- package/data/shared/framework/skills/backend-development/references/architecture-patterns.md +183 -0
- package/data/shared/framework/skills/backend-development/references/observability-resilience.md +155 -0
- package/data/shared/framework/skills/backend-development/references/troubleshooting.md +199 -0
- package/data/shared/framework/skills/codebase-analysis/SKILL.md +72 -0
- package/data/shared/framework/skills/codebase-analysis/assets/sample-output.md +263 -0
- package/data/shared/framework/skills/codebase-analysis/references/analysis-techniques.md +241 -0
- package/data/shared/framework/skills/codebase-analysis/references/dependency-mapping.md +280 -0
- package/data/shared/framework/skills/codebase-analysis/references/tech-debt-assessment.md +208 -0
- package/data/shared/framework/skills/databases/SKILL.md +72 -0
- package/data/shared/framework/skills/databases/assets/sample-output.md +212 -0
- package/data/shared/framework/skills/databases/references/advanced-data-patterns.md +259 -0
- package/data/shared/framework/skills/databases/references/query-optimization.md +214 -0
- package/data/shared/framework/skills/databases/references/schema-design.md +159 -0
- package/data/shared/framework/skills/databases/references/troubleshooting.md +214 -0
- package/data/shared/framework/skills/debugging-investigation/SKILL.md +84 -0
- package/data/shared/framework/skills/debugging-investigation/assets/sample-output.md +314 -0
- package/data/shared/framework/skills/debugging-investigation/references/systematic-debugging.md +197 -0
- package/data/shared/framework/skills/debugging-investigation/references/tool-specific-guides.md +202 -0
- package/data/shared/framework/skills/debugging-investigation/references/troubleshooting-patterns.md +196 -0
- package/data/shared/framework/skills/frontend-development/SKILL.md +67 -0
- package/data/shared/framework/skills/frontend-development/assets/sample-output.md +110 -0
- package/data/shared/framework/skills/frontend-development/references/component-patterns.md +112 -0
- package/data/shared/framework/skills/frontend-development/references/performance-guide.md +169 -0
- package/data/shared/framework/skills/frontend-development/references/routing-forms-realtime.md +374 -0
- package/data/shared/framework/skills/frontend-development/references/ssr-rsc-patterns.md +284 -0
- package/data/shared/framework/skills/frontend-development/references/troubleshooting.md +154 -0
- package/data/shared/framework/skills/mobile-development/SKILL.md +67 -0
- package/data/shared/framework/skills/mobile-development/assets/sample-output.md +382 -0
- package/data/shared/framework/skills/mobile-development/references/mobile-patterns.md +681 -0
- package/data/shared/framework/skills/mobile-development/references/mobile-performance.md +524 -0
- package/data/shared/framework/skills/mobile-development/references/troubleshooting.md +158 -0
- package/data/shared/framework/skills/security-audit/SKILL.md +83 -0
- package/data/shared/framework/skills/security-audit/assets/sample-output.md +451 -0
- package/data/shared/framework/skills/security-audit/references/owasp-checklist.md +580 -0
- package/data/shared/framework/skills/security-audit/references/secure-coding-patterns.md +433 -0
- package/data/shared/framework/skills/security-audit/references/vulnerability-remediation.md +331 -0
- package/data/shared/framework/skills/ui-generation/SKILL.md +70 -0
- package/data/shared/framework/skills/ui-generation/assets/sample-output.md +139 -0
- package/data/shared/framework/skills/ui-generation/references/accessibility-responsive.md +127 -0
- package/data/shared/framework/skills/ui-generation/references/compound-components.md +252 -0
- package/data/shared/framework/skills/ui-generation/references/generation-patterns.md +110 -0
- package/data/shared/framework/skills/ui-generation/references/storybook-design-system.md +278 -0
- package/data/shared/framework/skills/ui-generation/references/troubleshooting.md +198 -0
- package/data/shared/framework/workflows/documentation-management.md +58 -0
- package/data/shared/framework/workflows/primary-workflow.md +88 -0
- package/dist/commands/activate.d.ts +3 -0
- package/dist/commands/activate.d.ts.map +1 -0
- package/dist/commands/activate.js +34 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/bundle.d.ts +3 -0
- package/dist/commands/bundle.d.ts.map +1 -0
- package/dist/commands/bundle.js +64 -0
- package/dist/commands/bundle.js.map +1 -0
- package/dist/commands/install.d.ts +3 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +99 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +37 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/search.d.ts +3 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +30 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +35 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +68 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/download/cache.d.ts +3 -0
- package/dist/download/cache.d.ts.map +1 -0
- package/dist/download/cache.js +18 -0
- package/dist/download/cache.js.map +1 -0
- package/dist/download/client.d.ts +2 -0
- package/dist/download/client.d.ts.map +1 -0
- package/dist/download/client.js +58 -0
- package/dist/download/client.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/installer/file-copier.d.ts +6 -0
- package/dist/installer/file-copier.d.ts.map +1 -0
- package/dist/installer/file-copier.js +32 -0
- package/dist/installer/file-copier.js.map +1 -0
- package/dist/installer/plugin-installer.d.ts +12 -0
- package/dist/installer/plugin-installer.d.ts.map +1 -0
- package/dist/installer/plugin-installer.js +33 -0
- package/dist/installer/plugin-installer.js.map +1 -0
- package/dist/installer/template-installer.d.ts +12 -0
- package/dist/installer/template-installer.d.ts.map +1 -0
- package/dist/installer/template-installer.js +45 -0
- package/dist/installer/template-installer.js.map +1 -0
- package/dist/license/crypto.d.ts +16 -0
- package/dist/license/crypto.d.ts.map +1 -0
- package/dist/license/crypto.js +50 -0
- package/dist/license/crypto.js.map +1 -0
- package/dist/license/license-store.d.ts +19 -0
- package/dist/license/license-store.d.ts.map +1 -0
- package/dist/license/license-store.js +99 -0
- package/dist/license/license-store.js.map +1 -0
- package/dist/license/validator.d.ts +32 -0
- package/dist/license/validator.d.ts.map +1 -0
- package/dist/license/validator.js +81 -0
- package/dist/license/validator.js.map +1 -0
- package/dist/registry/loader.d.ts +30 -0
- package/dist/registry/loader.d.ts.map +1 -0
- package/dist/registry/loader.js +22 -0
- package/dist/registry/loader.js.map +1 -0
- package/dist/registry/search-engine.d.ts +9 -0
- package/dist/registry/search-engine.d.ts.map +1 -0
- package/dist/registry/search-engine.js +30 -0
- package/dist/registry/search-engine.js.map +1 -0
- package/dist/utils/config.d.ts +14 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +28 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +22 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/paths.d.ts +20 -0
- package/dist/utils/paths.d.ts.map +1 -0
- package/dist/utils/paths.js +79 -0
- package/dist/utils/paths.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Sample Output: Data Table Component Plan
|
|
2
|
+
|
|
3
|
+
## Component: DataTable with Pagination, Sorting, and Filtering
|
|
4
|
+
|
|
5
|
+
### Requirements
|
|
6
|
+
- Display tabular data with configurable columns
|
|
7
|
+
- Client-side sorting (click column header to toggle asc/desc)
|
|
8
|
+
- Text filter per column + global search
|
|
9
|
+
- Pagination with configurable page size (10, 25, 50)
|
|
10
|
+
- Responsive: horizontal scroll on mobile, stacked cards below 480px
|
|
11
|
+
- Accessible: keyboard navigation, ARIA roles, screen reader support
|
|
12
|
+
|
|
13
|
+
### Component Tree
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
<DataTable>
|
|
17
|
+
├── <TableToolbar>
|
|
18
|
+
│ ├── <GlobalSearch />
|
|
19
|
+
│ ├── <ColumnFilter />
|
|
20
|
+
│ └── <PageSizeSelector />
|
|
21
|
+
├── <TableHeader>
|
|
22
|
+
│ └── <SortableColumn /> (per column)
|
|
23
|
+
├── <TableBody>
|
|
24
|
+
│ └── <TableRow /> (per visible row)
|
|
25
|
+
│ └── <TableCell /> (per column)
|
|
26
|
+
├── <TableFooter>
|
|
27
|
+
│ └── <Pagination />
|
|
28
|
+
└── <EmptyState /> (when no results)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### Props Interface
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
interface DataTableProps<T> {
|
|
35
|
+
data: T[];
|
|
36
|
+
columns: ColumnDef<T>[];
|
|
37
|
+
defaultPageSize?: number;
|
|
38
|
+
defaultSort?: { key: keyof T; direction: 'asc' | 'desc' };
|
|
39
|
+
onRowClick?: (row: T) => void;
|
|
40
|
+
loading?: boolean;
|
|
41
|
+
emptyMessage?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
interface ColumnDef<T> {
|
|
45
|
+
key: keyof T;
|
|
46
|
+
header: string;
|
|
47
|
+
sortable?: boolean;
|
|
48
|
+
filterable?: boolean;
|
|
49
|
+
render?: (value: T[keyof T], row: T) => ReactNode;
|
|
50
|
+
width?: string;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### State Management
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
// All state is local — no global store needed
|
|
58
|
+
const [currentPage, setCurrentPage] = useState(1);
|
|
59
|
+
const [pageSize, setPageSize] = useState(defaultPageSize);
|
|
60
|
+
const [sortConfig, setSortConfig] = useState(defaultSort);
|
|
61
|
+
const [filters, setFilters] = useState<Record<string, string>>({});
|
|
62
|
+
const [globalSearch, setGlobalSearch] = useState('');
|
|
63
|
+
|
|
64
|
+
// Derived data (memoized)
|
|
65
|
+
const filteredData = useMemo(() => applyFilters(data, filters, globalSearch), [data, filters, globalSearch]);
|
|
66
|
+
const sortedData = useMemo(() => applySort(filteredData, sortConfig), [filteredData, sortConfig]);
|
|
67
|
+
const paginatedData = useMemo(() => paginate(sortedData, currentPage, pageSize), [sortedData, currentPage, pageSize]);
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Performance Considerations
|
|
71
|
+
|
|
72
|
+
- **Virtual scrolling**: Enable when `data.length > 500` — use `@tanstack/react-virtual`
|
|
73
|
+
- **Debounced search**: `globalSearch` input debounced at 300ms
|
|
74
|
+
- **Memoized rows**: `React.memo(TableRow)` with stable `key` from row ID
|
|
75
|
+
- **Stable callbacks**: `useCallback` for `onSort`, `onFilter`, `onPageChange`
|
|
76
|
+
|
|
77
|
+
### Accessibility
|
|
78
|
+
|
|
79
|
+
- `<table role="grid">` with `aria-sort` on sortable columns
|
|
80
|
+
- `<th scope="col">` for column headers
|
|
81
|
+
- Keyboard: Enter/Space to sort, Tab to navigate, arrow keys within cells
|
|
82
|
+
- `aria-live="polite"` region announcing "Showing X of Y results"
|
|
83
|
+
- Focus management: return focus to table after filter/sort changes
|
|
84
|
+
|
|
85
|
+
### Testing Plan
|
|
86
|
+
|
|
87
|
+
| Test | Type | Tool |
|
|
88
|
+
|------|------|------|
|
|
89
|
+
| Sort toggles correctly | Unit | Vitest |
|
|
90
|
+
| Filter reduces visible rows | Component | Testing Library |
|
|
91
|
+
| Pagination shows correct slice | Component | Testing Library |
|
|
92
|
+
| Empty state renders | Component | Testing Library |
|
|
93
|
+
| Keyboard navigation works | Component | Testing Library |
|
|
94
|
+
| Responsive layout switches | Visual | Chromatic |
|
|
95
|
+
| 10,000 rows renders smoothly | Performance | Lighthouse |
|
|
96
|
+
|
|
97
|
+
### File Structure
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
components/DataTable/
|
|
101
|
+
├── DataTable.tsx
|
|
102
|
+
├── DataTable.module.css
|
|
103
|
+
├── DataTable.test.tsx
|
|
104
|
+
├── TableHeader.tsx
|
|
105
|
+
├── TableRow.tsx
|
|
106
|
+
├── Pagination.tsx
|
|
107
|
+
├── GlobalSearch.tsx
|
|
108
|
+
├── types.ts
|
|
109
|
+
└── utils.ts (applyFilters, applySort, paginate)
|
|
110
|
+
```
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Component Patterns
|
|
2
|
+
|
|
3
|
+
## Design Principles
|
|
4
|
+
|
|
5
|
+
### Single Responsibility
|
|
6
|
+
Each component does one thing. If a component handles data fetching, transformation, AND rendering — split it.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
Bad: <UserDashboard /> (fetches users, formats dates, renders table, handles pagination)
|
|
10
|
+
Good: <UserDashboard /> → <UserTable data={users} /> + <Pagination /> + useUsers() hook
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Composition Over Inheritance
|
|
14
|
+
Never extend component classes. Compose behavior through children, slots, hooks, or higher-order patterns.
|
|
15
|
+
|
|
16
|
+
### Props Down, Events Up
|
|
17
|
+
Data flows one direction. Children communicate upward through callbacks (React), events (Vue), or outputs (Angular).
|
|
18
|
+
|
|
19
|
+
## React Patterns
|
|
20
|
+
|
|
21
|
+
### Custom Hooks
|
|
22
|
+
Extract reusable logic into hooks. Every hook should have a single purpose.
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// Data fetching hook with loading/error states
|
|
26
|
+
function useApi<T>(url: string) {
|
|
27
|
+
const [data, setData] = useState<T | null>(null);
|
|
28
|
+
const [error, setError] = useState<Error | null>(null);
|
|
29
|
+
const [loading, setLoading] = useState(true);
|
|
30
|
+
// ... fetch logic
|
|
31
|
+
return { data, error, loading, refetch };
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Context for Cross-Cutting Concerns
|
|
36
|
+
Use context for theme, auth, locale — NOT for frequently changing state. Context changes re-render all consumers.
|
|
37
|
+
|
|
38
|
+
### Render Props / Children as Function
|
|
39
|
+
When a component needs to share internal state with flexible rendering:
|
|
40
|
+
```typescript
|
|
41
|
+
<DataLoader url="/api/users">
|
|
42
|
+
{({ data, loading }) => loading ? <Spinner /> : <UserList users={data} />}
|
|
43
|
+
</DataLoader>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Vue Patterns
|
|
47
|
+
|
|
48
|
+
### Composition API
|
|
49
|
+
Prefer `setup()` / `<script setup>` over Options API for new code. Group logic by feature, not by option type.
|
|
50
|
+
|
|
51
|
+
### Composables
|
|
52
|
+
Vue equivalent of custom hooks. Prefix with `use`:
|
|
53
|
+
```typescript
|
|
54
|
+
// useAuth.ts — encapsulates auth state and methods
|
|
55
|
+
export function useAuth() {
|
|
56
|
+
const user = ref<User | null>(null);
|
|
57
|
+
const login = async (credentials: Credentials) => { /* ... */ };
|
|
58
|
+
const logout = async () => { /* ... */ };
|
|
59
|
+
return { user, login, logout };
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Provide/Inject
|
|
64
|
+
Use for dependency injection across deep component trees (similar to React Context).
|
|
65
|
+
|
|
66
|
+
## State Management Strategies
|
|
67
|
+
|
|
68
|
+
Choose the simplest option that works:
|
|
69
|
+
|
|
70
|
+
| Scope | Solution | When |
|
|
71
|
+
|-------|----------|------|
|
|
72
|
+
| Single component | `useState` / `ref()` | Form inputs, toggles, local UI |
|
|
73
|
+
| Parent-child | Props + callbacks | Shared between 2-3 components |
|
|
74
|
+
| Subtree | Context / provide-inject | Theme, auth, shared config |
|
|
75
|
+
| Global | Zustand / Pinia / NgRx | Cart, notifications, complex flows |
|
|
76
|
+
| Server | React Query / SWR / Apollo | API data with cache + revalidation |
|
|
77
|
+
|
|
78
|
+
**Rule of thumb**: If you reach for global state, ask "can server state (React Query/SWR) handle this instead?"
|
|
79
|
+
|
|
80
|
+
## Error Boundaries
|
|
81
|
+
|
|
82
|
+
Wrap major UI sections in error boundaries. Never let one broken widget crash the entire page.
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
<ErrorBoundary fallback={<ErrorPanel />}>
|
|
86
|
+
<DashboardCharts />
|
|
87
|
+
</ErrorBoundary>
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Place boundaries at: route level, widget level, and around third-party components.
|
|
91
|
+
|
|
92
|
+
## Form Handling
|
|
93
|
+
|
|
94
|
+
- Use a form library (React Hook Form, Formik, VeeValidate) for complex forms
|
|
95
|
+
- Validate on blur for individual fields, on submit for the full form
|
|
96
|
+
- Show inline errors next to the field, summary errors at the top
|
|
97
|
+
- Disable submit button during submission, show loading indicator
|
|
98
|
+
- Handle server validation errors by mapping to field-level messages
|
|
99
|
+
|
|
100
|
+
## Data Fetching Patterns
|
|
101
|
+
|
|
102
|
+
### SWR / React Query / Apollo
|
|
103
|
+
- Deduplicate identical requests automatically
|
|
104
|
+
- Cache responses and revalidate in background
|
|
105
|
+
- Handle loading, error, and stale states out of the box
|
|
106
|
+
- Support optimistic updates for better UX
|
|
107
|
+
|
|
108
|
+
### Key Practices
|
|
109
|
+
- Define query keys consistently (e.g., `['users', { page, filter }]`)
|
|
110
|
+
- Set appropriate `staleTime` (how long data is fresh) and `cacheTime` (how long to keep unused data)
|
|
111
|
+
- Use `prefetchQuery` for anticipated navigation
|
|
112
|
+
- Implement optimistic updates for mutations that need instant feedback
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Frontend Performance Guide
|
|
2
|
+
|
|
3
|
+
## Core Web Vitals
|
|
4
|
+
|
|
5
|
+
### LCP (Largest Contentful Paint) — Target: < 2.5s
|
|
6
|
+
- Preload critical resources (`<link rel="preload">` for hero images, fonts)
|
|
7
|
+
- Server-side render or statically generate above-the-fold content
|
|
8
|
+
- Avoid render-blocking CSS/JS — inline critical CSS, defer the rest
|
|
9
|
+
- Use CDN for static assets with edge caching
|
|
10
|
+
|
|
11
|
+
### FID / INP (First Input Delay / Interaction to Next Paint) — Target: < 100ms / < 200ms
|
|
12
|
+
- Break long tasks (> 50ms) into smaller chunks with `requestIdleCallback` or `scheduler.yield()`
|
|
13
|
+
- Move heavy computation to Web Workers
|
|
14
|
+
- Minimize main-thread JavaScript during page load
|
|
15
|
+
- Lazy-load non-critical third-party scripts
|
|
16
|
+
|
|
17
|
+
### CLS (Cumulative Layout Shift) — Target: < 0.1
|
|
18
|
+
- Always set `width` and `height` on images and videos (or use `aspect-ratio`)
|
|
19
|
+
- Reserve space for dynamic content (ads, embeds, lazy-loaded sections)
|
|
20
|
+
- Avoid inserting content above existing content after load
|
|
21
|
+
- Use `font-display: swap` with proper font fallback metrics
|
|
22
|
+
|
|
23
|
+
## Bundle Size Optimization
|
|
24
|
+
|
|
25
|
+
### Code Splitting
|
|
26
|
+
```typescript
|
|
27
|
+
// Route-level splitting (React)
|
|
28
|
+
const Dashboard = lazy(() => import('./pages/Dashboard'));
|
|
29
|
+
|
|
30
|
+
// Feature-level splitting
|
|
31
|
+
const HeavyChart = lazy(() => import('./components/HeavyChart'));
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Tree Shaking
|
|
35
|
+
- Use ES modules (`import/export`), not CommonJS (`require`)
|
|
36
|
+
- Import specific functions: `import { debounce } from 'lodash-es'` not `import _ from 'lodash'`
|
|
37
|
+
- Mark packages as side-effect-free in `package.json`: `"sideEffects": false`
|
|
38
|
+
|
|
39
|
+
### Bundle Analysis
|
|
40
|
+
- Run `npx webpack-bundle-analyzer stats.json` or `npx source-map-explorer build/static/js/*.js`
|
|
41
|
+
- Look for: duplicate dependencies, large libraries with small usage, unintended polyfills
|
|
42
|
+
|
|
43
|
+
### Budget Targets
|
|
44
|
+
| Resource | Budget |
|
|
45
|
+
|----------|--------|
|
|
46
|
+
| Total JS (compressed) | < 200 KB |
|
|
47
|
+
| Total CSS (compressed) | < 50 KB |
|
|
48
|
+
| Largest single chunk | < 100 KB |
|
|
49
|
+
| Third-party JS | < 100 KB |
|
|
50
|
+
|
|
51
|
+
## Rendering Optimization
|
|
52
|
+
|
|
53
|
+
### React
|
|
54
|
+
- `React.memo()` for components that render often with same props
|
|
55
|
+
- `useMemo()` for expensive computed values (not for everything)
|
|
56
|
+
- `useCallback()` for callbacks passed to memoized children
|
|
57
|
+
- Use `key` prop correctly — stable, unique identifiers, never array index for dynamic lists
|
|
58
|
+
|
|
59
|
+
### Virtual Lists
|
|
60
|
+
For lists > 100 items, use virtualization:
|
|
61
|
+
- `react-window` or `@tanstack/react-virtual`
|
|
62
|
+
- Only renders visible items + small buffer
|
|
63
|
+
- Reduces DOM nodes from thousands to dozens
|
|
64
|
+
|
|
65
|
+
### Avoid
|
|
66
|
+
- Inline object/array literals in JSX props (creates new reference every render)
|
|
67
|
+
- Anonymous functions in JSX when passed to memoized children
|
|
68
|
+
- Premature optimization — measure first with React DevTools Profiler
|
|
69
|
+
|
|
70
|
+
## Image Optimization
|
|
71
|
+
|
|
72
|
+
### Format Selection
|
|
73
|
+
| Format | Use Case |
|
|
74
|
+
|--------|----------|
|
|
75
|
+
| WebP | General use, 25-35% smaller than JPEG |
|
|
76
|
+
| AVIF | Best compression, limited browser support — use as first choice with fallback |
|
|
77
|
+
| SVG | Icons, logos, illustrations (scalable, tiny file size) |
|
|
78
|
+
| PNG | Screenshots, images requiring transparency |
|
|
79
|
+
|
|
80
|
+
### Implementation
|
|
81
|
+
```html
|
|
82
|
+
<picture>
|
|
83
|
+
<source srcset="hero.avif" type="image/avif" />
|
|
84
|
+
<source srcset="hero.webp" type="image/webp" />
|
|
85
|
+
<img src="hero.jpg" alt="..." loading="lazy" decoding="async" width="800" height="400" />
|
|
86
|
+
</picture>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Use `loading="lazy"` for below-the-fold images
|
|
90
|
+
- Use `fetchpriority="high"` for LCP image
|
|
91
|
+
- Serve responsive sizes with `srcset` and `sizes` attributes
|
|
92
|
+
- Compress images in CI pipeline (sharp, squoosh)
|
|
93
|
+
|
|
94
|
+
## CSS Performance
|
|
95
|
+
|
|
96
|
+
### Critical CSS
|
|
97
|
+
- Inline above-the-fold CSS in `<head>` (< 14 KB)
|
|
98
|
+
- Load remaining CSS asynchronously: `<link rel="preload" href="styles.css" as="style">`
|
|
99
|
+
|
|
100
|
+
### CSS-in-JS Trade-offs
|
|
101
|
+
| Approach | Pros | Cons |
|
|
102
|
+
|----------|------|------|
|
|
103
|
+
| CSS Modules | Zero runtime, scoped | Build step required |
|
|
104
|
+
| Tailwind | Tiny production CSS, utility-first | Learning curve, verbose JSX |
|
|
105
|
+
| styled-components | Dynamic styles, colocation | Runtime cost, larger bundle |
|
|
106
|
+
|
|
107
|
+
**Recommendation**: CSS Modules or Tailwind for performance-critical apps. CSS-in-JS is fine for internal tools.
|
|
108
|
+
|
|
109
|
+
## Caching Strategies
|
|
110
|
+
|
|
111
|
+
### HTTP Cache Headers
|
|
112
|
+
- Static assets (JS/CSS/images with hash): `Cache-Control: public, max-age=31536000, immutable`
|
|
113
|
+
- HTML: `Cache-Control: no-cache` (always revalidate)
|
|
114
|
+
- API responses: `Cache-Control: private, max-age=0, stale-while-revalidate=60`
|
|
115
|
+
|
|
116
|
+
### Service Workers
|
|
117
|
+
- Cache app shell for offline support
|
|
118
|
+
- Use `stale-while-revalidate` strategy for API data
|
|
119
|
+
- Precache critical routes during install phase
|
|
120
|
+
- Version your cache and clean up old versions
|
|
121
|
+
|
|
122
|
+
## Data Fetching Cleanup
|
|
123
|
+
|
|
124
|
+
### AbortController for fetch requests
|
|
125
|
+
|
|
126
|
+
Cancel in-flight requests when component unmounts or dependencies change:
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
useEffect(() => {
|
|
130
|
+
const controller = new AbortController();
|
|
131
|
+
|
|
132
|
+
async function fetchData() {
|
|
133
|
+
try {
|
|
134
|
+
const res = await fetch('/api/data', { signal: controller.signal });
|
|
135
|
+
const data = await res.json();
|
|
136
|
+
setData(data);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
if (err instanceof DOMException && err.name === 'AbortError') return; // Expected
|
|
139
|
+
setError(err);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
fetchData();
|
|
144
|
+
return () => controller.abort();
|
|
145
|
+
}, [dependency]);
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
**With TanStack Query**: Abort is handled automatically — no manual cleanup needed.
|
|
149
|
+
|
|
150
|
+
### Timer cleanup
|
|
151
|
+
|
|
152
|
+
Always clear intervals and timeouts on unmount:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
useEffect(() => {
|
|
156
|
+
const id = setInterval(() => refetch(), 30_000);
|
|
157
|
+
return () => clearInterval(id);
|
|
158
|
+
}, []);
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Measurement Tools
|
|
162
|
+
|
|
163
|
+
| Tool | Purpose |
|
|
164
|
+
|------|---------|
|
|
165
|
+
| Lighthouse CI | Automated audits in CI pipeline |
|
|
166
|
+
| WebPageTest | Real-world loading waterfall analysis |
|
|
167
|
+
| Chrome DevTools Performance | Flame chart, main thread analysis |
|
|
168
|
+
| `web-vitals` library | Collect real user metrics (RUM) |
|
|
169
|
+
| Bundle Analyzer | Identify large dependencies |
|