aiwf 0.3.21 → 0.3.23

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.
Files changed (140) hide show
  1. package/package.json +3 -2
  2. package/src/cli/index.js +39 -336
  3. package/src/lib/installer.js +310 -90
  4. package/src/utils/messages.js +24 -0
  5. package/src/DEPENDENCY_MAP.md +0 -90
  6. package/src/cli/cache-cli.js +0 -459
  7. package/src/cli/checkpoint-cli.js +0 -417
  8. package/src/cli/language-cli.js +0 -286
  9. package/src/cli/sprint-cli.js +0 -287
  10. package/src/commands/ai-tool.js +0 -383
  11. package/src/commands/compress.js +0 -60
  12. package/src/commands/create-project.js +0 -160
  13. package/src/commands/evaluate.js +0 -459
  14. package/src/commands/persona.js +0 -309
  15. package/src/commands/sprint-task.js +0 -262
  16. package/src/commands/token.js +0 -312
  17. package/src/lib/ai-persona-manager.js +0 -711
  18. package/src/lib/cache-system.js +0 -332
  19. package/src/lib/context-engine.js +0 -568
  20. package/src/lib/github-integration.js +0 -402
  21. package/src/lib/memory-profiler.js +0 -471
  22. package/src/lib/metrics-collector.js +0 -885
  23. package/src/lib/offline-detector.js +0 -386
  24. package/src/lib/resource-loader-enhanced.js +0 -399
  25. package/src/lib/resource-loader.js +0 -250
  26. package/src/lib/resources/commands/ai-persona.js +0 -602
  27. package/src/lib/resources/commands/compress-context.js +0 -389
  28. package/src/lib/resources/commands/evaluate.js +0 -246
  29. package/src/lib/resources/commands/persona-context-apply.js +0 -562
  30. package/src/lib/resources/commands/token-tracking.js +0 -443
  31. package/src/lib/resources/config/commit-patterns.js +0 -103
  32. package/src/lib/resources/config/language.json +0 -6
  33. package/src/lib/resources/personas/PERSONA_INDEX.md +0 -57
  34. package/src/lib/resources/personas/analyst.json +0 -44
  35. package/src/lib/resources/personas/architect/best_practices.md +0 -136
  36. package/src/lib/resources/personas/architect/knowledge_base.md +0 -377
  37. package/src/lib/resources/personas/architect.json +0 -44
  38. package/src/lib/resources/personas/backend/best_practices.md +0 -766
  39. package/src/lib/resources/personas/backend/knowledge_base.md +0 -1070
  40. package/src/lib/resources/personas/data_analyst/best_practices.md +0 -594
  41. package/src/lib/resources/personas/data_analyst/knowledge_base.md +0 -1057
  42. package/src/lib/resources/personas/developer.json +0 -44
  43. package/src/lib/resources/personas/developer.md +0 -37
  44. package/src/lib/resources/personas/evaluation_criteria.json +0 -137
  45. package/src/lib/resources/personas/frontend/best_practices.md +0 -445
  46. package/src/lib/resources/personas/frontend/knowledge_base.md +0 -729
  47. package/src/lib/resources/personas/persona-index.json +0 -31
  48. package/src/lib/resources/personas/reviewer.json +0 -44
  49. package/src/lib/resources/personas/security/best_practices.md +0 -307
  50. package/src/lib/resources/personas/security/knowledge_base.md +0 -498
  51. package/src/lib/resources/personas/tester.json +0 -44
  52. package/src/lib/resources/templates/README.md +0 -78
  53. package/src/lib/resources/templates/api-server/config.json +0 -64
  54. package/src/lib/resources/templates/api-server/template/.aiwf/config.json +0 -56
  55. package/src/lib/resources/templates/api-server/template/.aiwf/feature-ledger.json +0 -42
  56. package/src/lib/resources/templates/api-server/template/.aiwf/personas/backend-engineer.json +0 -40
  57. package/src/lib/resources/templates/api-server/template/.aiwf/scripts/cli.js +0 -111
  58. package/src/lib/resources/templates/api-server/template/.env.example +0 -29
  59. package/src/lib/resources/templates/api-server/template/.eslintrc.json +0 -23
  60. package/src/lib/resources/templates/api-server/template/README.md +0 -171
  61. package/src/lib/resources/templates/api-server/template/jest.config.js +0 -26
  62. package/src/lib/resources/templates/api-server/template/nodemon.json +0 -9
  63. package/src/lib/resources/templates/api-server/template/package.json +0 -61
  64. package/src/lib/resources/templates/api-server/template/src/app.ts +0 -60
  65. package/src/lib/resources/templates/api-server/template/src/config/swagger.ts +0 -38
  66. package/src/lib/resources/templates/api-server/template/src/controllers/aiwfController.ts +0 -54
  67. package/src/lib/resources/templates/api-server/template/src/controllers/authController.ts +0 -128
  68. package/src/lib/resources/templates/api-server/template/src/controllers/statusController.ts +0 -28
  69. package/src/lib/resources/templates/api-server/template/src/index.ts +0 -28
  70. package/src/lib/resources/templates/api-server/template/src/middleware/aiwfMiddleware.ts +0 -50
  71. package/src/lib/resources/templates/api-server/template/src/middleware/authMiddleware.ts +0 -41
  72. package/src/lib/resources/templates/api-server/template/src/middleware/errorHandler.ts +0 -42
  73. package/src/lib/resources/templates/api-server/template/src/middleware/notFoundHandler.ts +0 -14
  74. package/src/lib/resources/templates/api-server/template/src/middleware/requestLogger.ts +0 -20
  75. package/src/lib/resources/templates/api-server/template/src/routes/aiwf.ts +0 -31
  76. package/src/lib/resources/templates/api-server/template/src/routes/index.ts +0 -13
  77. package/src/lib/resources/templates/api-server/template/src/routes/v1/index.ts +0 -67
  78. package/src/lib/resources/templates/api-server/template/src/utils/logger.ts +0 -37
  79. package/src/lib/resources/templates/api-server/template/tests/app.test.ts +0 -40
  80. package/src/lib/resources/templates/api-server/template/tsconfig.json +0 -43
  81. package/src/lib/resources/templates/npm-library/config.json +0 -61
  82. package/src/lib/resources/templates/npm-library/template/LICENSE +0 -21
  83. package/src/lib/resources/templates/npm-library/template/README.md +0 -201
  84. package/src/lib/resources/templates/npm-library/template/package.json +0 -78
  85. package/src/lib/resources/templates/web-app/config.json +0 -53
  86. package/src/lib/resources/templates/web-app/template/.aiwf/config.json +0 -54
  87. package/src/lib/resources/templates/web-app/template/.aiwf/feature-ledger.json +0 -37
  88. package/src/lib/resources/templates/web-app/template/.aiwf/personas/fullstack-developer.json +0 -40
  89. package/src/lib/resources/templates/web-app/template/.aiwf/scripts/cli.js +0 -110
  90. package/src/lib/resources/templates/web-app/template/.eslintrc.cjs +0 -20
  91. package/src/lib/resources/templates/web-app/template/README.md +0 -151
  92. package/src/lib/resources/templates/web-app/template/index.html +0 -14
  93. package/src/lib/resources/templates/web-app/template/package.json +0 -44
  94. package/src/lib/resources/templates/web-app/template/postcss.config.js +0 -6
  95. package/src/lib/resources/templates/web-app/template/public/vite.svg +0 -1
  96. package/src/lib/resources/templates/web-app/template/src/App.tsx +0 -21
  97. package/src/lib/resources/templates/web-app/template/src/components/Layout.tsx +0 -57
  98. package/src/lib/resources/templates/web-app/template/src/components/aiwf/ContextStatus.tsx +0 -107
  99. package/src/lib/resources/templates/web-app/template/src/components/aiwf/TokenUsage.tsx +0 -71
  100. package/src/lib/resources/templates/web-app/template/src/index.css +0 -60
  101. package/src/lib/resources/templates/web-app/template/src/main.tsx +0 -10
  102. package/src/lib/resources/templates/web-app/template/src/pages/AiwfDashboard.tsx +0 -57
  103. package/src/lib/resources/templates/web-app/template/src/pages/HomePage.tsx +0 -89
  104. package/src/lib/resources/templates/web-app/template/src/pages/NotFound.tsx +0 -25
  105. package/src/lib/resources/templates/web-app/template/src/stores/aiwfStore.ts +0 -126
  106. package/src/lib/resources/templates/web-app/template/src/types/global.d.ts +0 -9
  107. package/src/lib/resources/templates/web-app/template/src/vite-env.d.ts +0 -1
  108. package/src/lib/resources/templates/web-app/template/tailwind.config.js +0 -30
  109. package/src/lib/resources/templates/web-app/template/tsconfig.json +0 -37
  110. package/src/lib/resources/templates/web-app/template/tsconfig.node.json +0 -10
  111. package/src/lib/resources/templates/web-app/template/vite.config.ts +0 -23
  112. package/src/lib/resources/utils/background-monitor.js +0 -223
  113. package/src/lib/resources/utils/compression-metrics.js +0 -1031
  114. package/src/lib/resources/utils/compression-strategies.js +0 -557
  115. package/src/lib/resources/utils/content-normalizer.js +0 -455
  116. package/src/lib/resources/utils/context-compressor.js +0 -583
  117. package/src/lib/resources/utils/context-rule-parser.js +0 -180
  118. package/src/lib/resources/utils/context-token-monitor.js +0 -463
  119. package/src/lib/resources/utils/context-update-manager.js +0 -502
  120. package/src/lib/resources/utils/git-utils.js +0 -220
  121. package/src/lib/resources/utils/importance-classifier.js +0 -645
  122. package/src/lib/resources/utils/information-filter.js +0 -710
  123. package/src/lib/resources/utils/persona-aware-compressor.js +0 -598
  124. package/src/lib/resources/utils/prompt-injector.js +0 -242
  125. package/src/lib/resources/utils/simplified-evaluator.js +0 -119
  126. package/src/lib/resources/utils/text-summarizer.js +0 -492
  127. package/src/lib/resources/utils/token-counter.js +0 -177
  128. package/src/lib/resources/utils/token-monitor.js +0 -484
  129. package/src/lib/resources/utils/token-reporter.js +0 -452
  130. package/src/lib/resources/utils/token-storage.js +0 -433
  131. package/src/lib/resources/utils/token-tracker.js +0 -283
  132. package/src/lib/state/priority-calculator.js +0 -217
  133. package/src/lib/state/state-index.js +0 -155
  134. package/src/lib/state/task-scanner.js +0 -328
  135. package/src/lib/task-analyzer.js +0 -599
  136. package/src/lib/template-cache-system.js +0 -559
  137. package/src/lib/template-downloader.js +0 -467
  138. package/src/lib/template-version-manager.js +0 -491
  139. package/src/lib/token-optimizer.js +0 -517
  140. package/src/utils/engineering-guard.js +0 -399
@@ -1,44 +0,0 @@
1
- {
2
- "id": "developer",
3
- "name": "Software Developer",
4
- "description": "Implements features, writes clean code, and follows best practices",
5
- "focus_areas": [
6
- "Code implementation",
7
- "Algorithm optimization",
8
- "Code quality and maintainability",
9
- "Testing and debugging",
10
- "Performance optimization"
11
- ],
12
- "communication_style": {
13
- "tone": "practical, solution-oriented, collaborative",
14
- "language": "technical with code examples",
15
- "format": "code snippets, implementation notes, commit messages"
16
- },
17
- "capabilities": [
18
- "Write clean, maintainable code",
19
- "Implement complex algorithms",
20
- "Optimize performance",
21
- "Debug and fix issues",
22
- "Write comprehensive tests"
23
- ],
24
- "tools_and_methods": [
25
- "SOLID principles",
26
- "Design patterns",
27
- "Test-driven development",
28
- "Clean code practices",
29
- "Refactoring techniques"
30
- ],
31
- "output_formats": [
32
- "Source code",
33
- "Unit tests",
34
- "Integration tests",
35
- "Code documentation",
36
- "Performance reports"
37
- ],
38
- "example_prompts": [
39
- "Implement feature FL-001 authentication system",
40
- "Optimize the database query performance",
41
- "Refactor the payment module for better maintainability",
42
- "Write unit tests for the user service"
43
- ]
44
- }
@@ -1,37 +0,0 @@
1
- # 개발자 페르소나
2
-
3
- ## 기본 정보
4
- - **이름**: Developer
5
- - **역할**: 소프트웨어 개발자
6
- - **경험**: 5년 이상
7
- - **전문 분야**: 웹 개발, 백엔드 개발
8
-
9
- ## 성격 및 특성
10
- - 논리적이고 체계적인 접근 방식
11
- - 코드 품질과 성능에 대한 높은 기준
12
- - 새로운 기술에 대한 호기심
13
- - 문제 해결 중심의 사고방식
14
-
15
- ## 커뮤니케이션 스타일
16
- - 명확하고 구체적인 설명 선호
17
- - 기술적 근거를 바탕으로 한 의견 제시
18
- - 코드 예시와 함께 설명
19
- - 단계적이고 논리적인 설명
20
-
21
- ## 작업 방식
22
- - 요구사항 분석 후 구현 계획 수립
23
- - 테스트 주도 개발(TDD) 적용
24
- - 코드 리뷰와 리팩토링 중시
25
- - 문서화와 주석 작성 습관
26
-
27
- ## 주요 역량
28
- - 프로그래밍 언어: JavaScript, TypeScript, Python
29
- - 프레임워크: React, Node.js, Express
30
- - 데이터베이스: MongoDB, PostgreSQL
31
- - 도구: Git, Docker, AWS
32
-
33
- ## 목표
34
- - 고품질 소프트웨어 개발
35
- - 효율적인 개발 프로세스 구축
36
- - 팀 협업 및 지식 공유
37
- - 지속적인 학습과 성장
@@ -1,137 +0,0 @@
1
- {
2
- "architect": {
3
- "name": "Architect",
4
- "description": "시스템 설계 및 아키텍처 전문가",
5
- "evaluation_weights": {
6
- "relevance": 0.20,
7
- "consistency": 0.30,
8
- "completeness": 0.20,
9
- "clarity": 0.15,
10
- "actionability": 0.15
11
- },
12
- "quality_thresholds": {
13
- "excellent": 0.85,
14
- "good": 0.70,
15
- "fair": 0.55,
16
- "poor": 0.40
17
- },
18
- "expected_characteristics": {
19
- "response_length": {
20
- "min": 300,
21
- "ideal": 800,
22
- "max": 1500
23
- },
24
- "technical_depth": "high",
25
- "abstraction_level": "high",
26
- "focus_areas": ["scalability", "maintainability", "patterns"]
27
- }
28
- },
29
- "security": {
30
- "name": "Security Expert",
31
- "description": "보안 전문가",
32
- "evaluation_weights": {
33
- "relevance": 0.25,
34
- "consistency": 0.25,
35
- "completeness": 0.25,
36
- "clarity": 0.10,
37
- "actionability": 0.15
38
- },
39
- "quality_thresholds": {
40
- "excellent": 0.90,
41
- "good": 0.75,
42
- "fair": 0.60,
43
- "poor": 0.45
44
- },
45
- "expected_characteristics": {
46
- "response_length": {
47
- "min": 350,
48
- "ideal": 800,
49
- "max": 1500
50
- },
51
- "technical_depth": "very_high",
52
- "abstraction_level": "medium",
53
- "focus_areas": ["vulnerabilities", "threats", "protection"]
54
- }
55
- },
56
- "frontend": {
57
- "name": "Frontend Developer",
58
- "description": "프론트엔드 개발 전문가",
59
- "evaluation_weights": {
60
- "relevance": 0.25,
61
- "consistency": 0.20,
62
- "completeness": 0.20,
63
- "clarity": 0.20,
64
- "actionability": 0.15
65
- },
66
- "quality_thresholds": {
67
- "excellent": 0.80,
68
- "good": 0.65,
69
- "fair": 0.50,
70
- "poor": 0.35
71
- },
72
- "expected_characteristics": {
73
- "response_length": {
74
- "min": 250,
75
- "ideal": 600,
76
- "max": 1200
77
- },
78
- "technical_depth": "medium",
79
- "abstraction_level": "low",
80
- "focus_areas": ["ui", "ux", "accessibility"]
81
- }
82
- },
83
- "backend": {
84
- "name": "Backend Developer",
85
- "description": "백엔드 개발 전문가",
86
- "evaluation_weights": {
87
- "relevance": 0.25,
88
- "consistency": 0.25,
89
- "completeness": 0.20,
90
- "clarity": 0.15,
91
- "actionability": 0.15
92
- },
93
- "quality_thresholds": {
94
- "excellent": 0.85,
95
- "good": 0.70,
96
- "fair": 0.55,
97
- "poor": 0.40
98
- },
99
- "expected_characteristics": {
100
- "response_length": {
101
- "min": 300,
102
- "ideal": 700,
103
- "max": 1400
104
- },
105
- "technical_depth": "high",
106
- "abstraction_level": "medium",
107
- "focus_areas": ["api", "database", "performance"]
108
- }
109
- },
110
- "data_analyst": {
111
- "name": "Data Analyst",
112
- "description": "데이터 분석 전문가",
113
- "evaluation_weights": {
114
- "relevance": 0.20,
115
- "consistency": 0.20,
116
- "completeness": 0.25,
117
- "clarity": 0.20,
118
- "actionability": 0.15
119
- },
120
- "quality_thresholds": {
121
- "excellent": 0.85,
122
- "good": 0.70,
123
- "fair": 0.55,
124
- "poor": 0.40
125
- },
126
- "expected_characteristics": {
127
- "response_length": {
128
- "min": 400,
129
- "ideal": 900,
130
- "max": 1600
131
- },
132
- "technical_depth": "high",
133
- "abstraction_level": "medium",
134
- "focus_areas": ["data", "insights", "visualization"]
135
- }
136
- }
137
- }
@@ -1,445 +0,0 @@
1
- # Frontend 페르소나 Best Practices
2
-
3
- ## 개요
4
- Frontend 페르소나는 사용자 경험(UX)과 인터페이스 디자인을 최우선으로 고려합니다. 성능, 접근성, 반응형 디자인에 중점을 둡니다.
5
-
6
- ## 핵심 원칙
7
-
8
- ### 1. 사용자 중심 디자인
9
- - 직관적인 인터페이스 설계
10
- - 일관된 디자인 시스템 구축
11
- - 피드백과 상태 표시 명확히
12
-
13
- ### 2. 성능 최적화
14
- ```javascript
15
- // Lazy Loading 구현
16
- const LazyImage = ({ src, alt }) => {
17
- const [imageSrc, setImageSrc] = useState(null);
18
- const imageRef = useRef();
19
-
20
- useEffect(() => {
21
- const observer = new IntersectionObserver(
22
- entries => {
23
- if (entries[0].isIntersecting) {
24
- setImageSrc(src);
25
- observer.disconnect();
26
- }
27
- },
28
- { threshold: 0.1 }
29
- );
30
-
31
- if (imageRef.current) {
32
- observer.observe(imageRef.current);
33
- }
34
-
35
- return () => observer.disconnect();
36
- }, [src]);
37
-
38
- return (
39
- <img
40
- ref={imageRef}
41
- src={imageSrc || '/placeholder.svg'}
42
- alt={alt}
43
- loading="lazy"
44
- />
45
- );
46
- };
47
- ```
48
-
49
- ### 3. 접근성 (Accessibility)
50
- ```jsx
51
- // ARIA 속성 활용
52
- <button
53
- aria-label="메뉴 열기"
54
- aria-expanded={isMenuOpen}
55
- aria-controls="navigation-menu"
56
- onClick={toggleMenu}
57
- >
58
- <MenuIcon />
59
- </button>
60
-
61
- // 키보드 네비게이션 지원
62
- const handleKeyDown = (e) => {
63
- switch(e.key) {
64
- case 'Enter':
65
- case ' ':
66
- e.preventDefault();
67
- handleClick();
68
- break;
69
- case 'Escape':
70
- handleClose();
71
- break;
72
- }
73
- };
74
- ```
75
-
76
- ## 컴포넌트 설계
77
-
78
- ### 재사용 가능한 컴포넌트
79
- ```jsx
80
- // Compound Component Pattern
81
- const Accordion = ({ children }) => {
82
- const [openIndex, setOpenIndex] = useState(null);
83
-
84
- return (
85
- <AccordionContext.Provider value={{ openIndex, setOpenIndex }}>
86
- <div className="accordion">{children}</div>
87
- </AccordionContext.Provider>
88
- );
89
- };
90
-
91
- Accordion.Item = ({ index, children }) => {
92
- const { openIndex, setOpenIndex } = useAccordion();
93
- const isOpen = openIndex === index;
94
-
95
- return (
96
- <div className="accordion-item">
97
- {React.Children.map(children, child =>
98
- React.cloneElement(child, { isOpen, toggle: () => setOpenIndex(index) })
99
- )}
100
- </div>
101
- );
102
- };
103
-
104
- Accordion.Header = ({ children, toggle }) => (
105
- <button className="accordion-header" onClick={toggle}>
106
- {children}
107
- </button>
108
- );
109
-
110
- Accordion.Content = ({ children, isOpen }) => (
111
- <div className={`accordion-content ${isOpen ? 'open' : ''}`}>
112
- {children}
113
- </div>
114
- );
115
- ```
116
-
117
- ### 상태 관리 패턴
118
- ```javascript
119
- // Custom Hook for Complex State
120
- function useFormState(initialValues, validationRules) {
121
- const [values, setValues] = useState(initialValues);
122
- const [errors, setErrors] = useState({});
123
- const [touched, setTouched] = useState({});
124
-
125
- const handleChange = useCallback((name, value) => {
126
- setValues(prev => ({ ...prev, [name]: value }));
127
-
128
- // 실시간 검증
129
- if (touched[name]) {
130
- const error = validationRules[name]?.(value);
131
- setErrors(prev => ({ ...prev, [name]: error }));
132
- }
133
- }, [touched, validationRules]);
134
-
135
- const handleBlur = useCallback((name) => {
136
- setTouched(prev => ({ ...prev, [name]: true }));
137
- const error = validationRules[name]?.(values[name]);
138
- setErrors(prev => ({ ...prev, [name]: error }));
139
- }, [values, validationRules]);
140
-
141
- const validateAll = useCallback(() => {
142
- const newErrors = {};
143
- Object.keys(validationRules).forEach(name => {
144
- const error = validationRules[name](values[name]);
145
- if (error) newErrors[name] = error;
146
- });
147
- setErrors(newErrors);
148
- return Object.keys(newErrors).length === 0;
149
- }, [values, validationRules]);
150
-
151
- return {
152
- values,
153
- errors,
154
- touched,
155
- handleChange,
156
- handleBlur,
157
- validateAll
158
- };
159
- }
160
- ```
161
-
162
- ## 스타일링 Best Practices
163
-
164
- ### CSS-in-JS vs CSS Modules
165
- ```javascript
166
- // Styled Components (CSS-in-JS)
167
- const Button = styled.button`
168
- background: ${props => props.primary ? '#007bff' : '#6c757d'};
169
- color: white;
170
- padding: 0.5rem 1rem;
171
- border: none;
172
- border-radius: 4px;
173
- font-size: 1rem;
174
- cursor: pointer;
175
- transition: all 0.2s ease;
176
-
177
- &:hover {
178
- opacity: 0.9;
179
- transform: translateY(-1px);
180
- }
181
-
182
- &:disabled {
183
- opacity: 0.6;
184
- cursor: not-allowed;
185
- }
186
- `;
187
-
188
- // CSS Modules
189
- // Button.module.css
190
- .button {
191
- composes: base from './base.module.css';
192
- background: var(--primary-color);
193
- color: white;
194
- padding: 0.5rem 1rem;
195
- }
196
-
197
- .button:hover {
198
- opacity: 0.9;
199
- }
200
-
201
- // Component
202
- import styles from './Button.module.css';
203
- const Button = ({ children, ...props }) => (
204
- <button className={styles.button} {...props}>
205
- {children}
206
- </button>
207
- );
208
- ```
209
-
210
- ### 반응형 디자인
211
- ```css
212
- /* Mobile First Approach */
213
- .container {
214
- width: 100%;
215
- padding: 1rem;
216
- }
217
-
218
- /* Tablet */
219
- @media (min-width: 768px) {
220
- .container {
221
- max-width: 750px;
222
- margin: 0 auto;
223
- }
224
- }
225
-
226
- /* Desktop */
227
- @media (min-width: 1024px) {
228
- .container {
229
- max-width: 1200px;
230
- display: grid;
231
- grid-template-columns: repeat(12, 1fr);
232
- gap: 2rem;
233
- }
234
- }
235
-
236
- /* Utility Classes */
237
- .hide-mobile { display: none; }
238
- .show-tablet { display: none; }
239
-
240
- @media (min-width: 768px) {
241
- .hide-mobile { display: block; }
242
- .show-tablet { display: block; }
243
- }
244
- ```
245
-
246
- ## 성능 최적화
247
-
248
- ### 번들 크기 최적화
249
- ```javascript
250
- // Dynamic Imports
251
- const HeavyComponent = lazy(() =>
252
- import(/* webpackChunkName: "heavy" */ './HeavyComponent')
253
- );
254
-
255
- // Tree Shaking을 위한 Named Exports
256
- // utils.js
257
- export const debounce = (fn, delay) => {
258
- let timeoutId;
259
- return (...args) => {
260
- clearTimeout(timeoutId);
261
- timeoutId = setTimeout(() => fn(...args), delay);
262
- };
263
- };
264
-
265
- export const throttle = (fn, limit) => {
266
- let inThrottle;
267
- return (...args) => {
268
- if (!inThrottle) {
269
- fn.apply(this, args);
270
- inThrottle = true;
271
- setTimeout(() => inThrottle = false, limit);
272
- }
273
- };
274
- };
275
-
276
- // Import only what you need
277
- import { debounce } from './utils';
278
- ```
279
-
280
- ### 렌더링 최적화
281
- ```jsx
282
- // React.memo로 불필요한 리렌더링 방지
283
- const ExpensiveComponent = React.memo(({ data }) => {
284
- return <ComplexVisualization data={data} />;
285
- }, (prevProps, nextProps) => {
286
- // Custom comparison
287
- return prevProps.data.id === nextProps.data.id;
288
- });
289
-
290
- // useMemo for expensive calculations
291
- const ProcessedData = ({ rawData }) => {
292
- const processed = useMemo(() => {
293
- return rawData
294
- .filter(item => item.active)
295
- .map(item => ({
296
- ...item,
297
- computed: expensiveComputation(item)
298
- }))
299
- .sort((a, b) => b.computed - a.computed);
300
- }, [rawData]);
301
-
302
- return <DataTable data={processed} />;
303
- };
304
- ```
305
-
306
- ## 테스팅 전략
307
-
308
- ### 컴포넌트 테스트
309
- ```javascript
310
- // React Testing Library
311
- describe('Button Component', () => {
312
- it('should render with correct text', () => {
313
- render(<Button>Click me</Button>);
314
- expect(screen.getByRole('button')).toHaveTextContent('Click me');
315
- });
316
-
317
- it('should handle click events', async () => {
318
- const handleClick = jest.fn();
319
- render(<Button onClick={handleClick}>Click me</Button>);
320
-
321
- await userEvent.click(screen.getByRole('button'));
322
- expect(handleClick).toHaveBeenCalledTimes(1);
323
- });
324
-
325
- it('should be keyboard accessible', async () => {
326
- const handleClick = jest.fn();
327
- render(<Button onClick={handleClick}>Click me</Button>);
328
-
329
- const button = screen.getByRole('button');
330
- button.focus();
331
-
332
- await userEvent.keyboard('{Enter}');
333
- expect(handleClick).toHaveBeenCalled();
334
- });
335
- });
336
- ```
337
-
338
- ### E2E 테스트
339
- ```javascript
340
- // Cypress
341
- describe('User Flow', () => {
342
- it('should complete checkout process', () => {
343
- cy.visit('/products');
344
-
345
- // 제품 선택
346
- cy.findByText('Add to Cart').click();
347
-
348
- // 장바구니 확인
349
- cy.findByLabelText('Cart').click();
350
- cy.findByText('Proceed to Checkout').click();
351
-
352
- // 결제 정보 입력
353
- cy.findByLabelText('Email').type('user@example.com');
354
- cy.findByLabelText('Card Number').type('4242424242424242');
355
-
356
- // 주문 완료
357
- cy.findByText('Place Order').click();
358
- cy.findByText('Order Confirmed').should('be.visible');
359
- });
360
- });
361
- ```
362
-
363
- ## 보안 고려사항
364
-
365
- ### XSS 방지
366
- ```jsx
367
- // 위험한 HTML 렌더링 피하기
368
- // 나쁜 예
369
- <div dangerouslySetInnerHTML={{ __html: userContent }} />
370
-
371
- // 좋은 예
372
- import DOMPurify from 'dompurify';
373
- <div dangerouslySetInnerHTML={{
374
- __html: DOMPurify.sanitize(userContent)
375
- }} />
376
-
377
- // 또는 텍스트로만 렌더링
378
- <div>{userContent}</div>
379
- ```
380
-
381
- ### 민감한 정보 보호
382
- ```javascript
383
- // 환경 변수 사용
384
- const API_KEY = process.env.REACT_APP_API_KEY;
385
-
386
- // 민감한 정보 로깅 방지
387
- const sanitizeUser = (user) => {
388
- const { password, ssn, ...safeUser } = user;
389
- return safeUser;
390
- };
391
-
392
- console.log('User data:', sanitizeUser(userData));
393
- ```
394
-
395
- ## 개발 도구
396
-
397
- ### 필수 도구
398
- - **번들러**: Vite, Webpack
399
- - **상태관리**: Redux Toolkit, Zustand, Jotai
400
- - **스타일링**: Tailwind CSS, Emotion, Styled Components
401
- - **테스팅**: Jest, React Testing Library, Cypress
402
- - **린팅**: ESLint, Prettier
403
-
404
- ### 성능 모니터링
405
- ```javascript
406
- // Web Vitals 측정
407
- import { getCLS, getFID, getFCP, getLCP, getTTFB } from 'web-vitals';
408
-
409
- function sendToAnalytics(metric) {
410
- // Google Analytics로 전송
411
- gtag('event', metric.name, {
412
- value: Math.round(metric.value),
413
- metric_id: metric.id,
414
- metric_value: metric.value,
415
- metric_delta: metric.delta,
416
- });
417
- }
418
-
419
- getCLS(sendToAnalytics);
420
- getFID(sendToAnalytics);
421
- getFCP(sendToAnalytics);
422
- getLCP(sendToAnalytics);
423
- getTTFB(sendToAnalytics);
424
- ```
425
-
426
- ## 체크리스트
427
-
428
- ### 개발 전
429
- - [ ] 디자인 시스템 확인
430
- - [ ] 반응형 브레이크포인트 정의
431
- - [ ] 접근성 요구사항 검토
432
- - [ ] 성능 목표 설정
433
-
434
- ### 개발 중
435
- - [ ] 컴포넌트 재사용성 검토
436
- - [ ] 접근성 테스트 (스크린 리더, 키보드)
437
- - [ ] 크로스 브라우저 테스트
438
- - [ ] 성능 프로파일링
439
-
440
- ### 배포 전
441
- - [ ] 번들 크기 최적화
442
- - [ ] 이미지 최적화
443
- - [ ] SEO 메타 태그
444
- - [ ] 에러 경계 설정
445
- - [ ] 분석 도구 통합