@mandujs/mcp 0.13.0 → 0.16.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 +6 -7
- package/package.json +3 -2
- package/src/adapters/index.ts +20 -20
- package/src/adapters/monitor-adapter.ts +100 -100
- package/src/adapters/tool-adapter.ts +88 -88
- package/src/executor/error-handler.ts +250 -250
- package/src/executor/index.ts +22 -22
- package/src/executor/tool-executor.ts +148 -148
- package/src/hooks/config-watcher.ts +174 -174
- package/src/hooks/index.ts +23 -23
- package/src/hooks/mcp-hooks.ts +227 -227
- package/src/logging/index.ts +15 -15
- package/src/logging/mcp-transport.ts +134 -134
- package/src/registry/index.ts +13 -13
- package/src/registry/mcp-tool-registry.ts +298 -298
- package/src/resources/skills/guides.ts +1136 -1136
- package/src/resources/skills/index.ts +12 -12
- package/src/resources/skills/loader.ts +218 -218
- package/src/resources/skills/mandu-composition/SKILL.md +91 -91
- package/src/resources/skills/mandu-composition/metadata.json +13 -13
- package/src/resources/skills/mandu-composition/rules/_sections.md +26 -26
- package/src/resources/skills/mandu-composition/rules/_template.md +77 -77
- package/src/resources/skills/mandu-composition/rules/comp-arch-avoid-boolean-props.md +146 -146
- package/src/resources/skills/mandu-composition/rules/comp-arch-compound-components.md +164 -164
- package/src/resources/skills/mandu-composition/rules/comp-island-event.md +161 -161
- package/src/resources/skills/mandu-composition/rules/comp-island-slot-split.md +167 -167
- package/src/resources/skills/mandu-composition/rules/comp-pattern-children.md +149 -149
- package/src/resources/skills/mandu-composition/rules/comp-state-context-interface.md +148 -148
- package/src/resources/skills/mandu-composition/rules/comp-state-lift-state.md +150 -150
- package/src/resources/skills/mandu-deployment/SKILL.md +92 -92
- package/src/resources/skills/mandu-deployment/_sections.md +41 -41
- package/src/resources/skills/mandu-deployment/_template.md +38 -38
- package/src/resources/skills/mandu-deployment/metadata.json +13 -13
- package/src/resources/skills/mandu-deployment/rules/deploy-build-bun.md +109 -109
- package/src/resources/skills/mandu-deployment/rules/deploy-build-output.md +115 -115
- package/src/resources/skills/mandu-deployment/rules/deploy-cicd-github.md +219 -219
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-bun.md +150 -150
- package/src/resources/skills/mandu-deployment/rules/deploy-docker-compose.md +223 -223
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-fly.md +152 -152
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-render.md +179 -179
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-supabase.md +323 -323
- package/src/resources/skills/mandu-deployment/rules/deploy-platform-vercel.md +140 -140
- package/src/resources/skills/mandu-fs-routes/SKILL.md +82 -82
- package/src/resources/skills/mandu-fs-routes/metadata.json +12 -12
- package/src/resources/skills/mandu-fs-routes/rules/_sections.md +36 -36
- package/src/resources/skills/mandu-fs-routes/rules/_template.md +69 -69
- package/src/resources/skills/mandu-fs-routes/rules/routes-api-methods.md +65 -65
- package/src/resources/skills/mandu-fs-routes/rules/routes-dynamic-param.md +93 -93
- package/src/resources/skills/mandu-fs-routes/rules/routes-naming-page.md +55 -55
- package/src/resources/skills/mandu-guard/SKILL.md +129 -129
- package/src/resources/skills/mandu-guard/metadata.json +12 -12
- package/src/resources/skills/mandu-guard/rules/_sections.md +36 -36
- package/src/resources/skills/mandu-guard/rules/_template.md +82 -82
- package/src/resources/skills/mandu-guard/rules/guard-config-rules.md +100 -100
- package/src/resources/skills/mandu-guard/rules/guard-layer-direction.md +76 -76
- package/src/resources/skills/mandu-guard/rules/guard-preset-mandu.md +81 -81
- package/src/resources/skills/mandu-guard/rules/guard-validate-import.md +80 -80
- package/src/resources/skills/mandu-hydration/SKILL.md +91 -91
- package/src/resources/skills/mandu-hydration/metadata.json +12 -12
- package/src/resources/skills/mandu-hydration/rules/_sections.md +31 -31
- package/src/resources/skills/mandu-hydration/rules/_template.md +72 -72
- package/src/resources/skills/mandu-hydration/rules/hydration-data-event.md +109 -109
- package/src/resources/skills/mandu-hydration/rules/hydration-directive-use-client.md +55 -55
- package/src/resources/skills/mandu-hydration/rules/hydration-island-setup.md +113 -113
- package/src/resources/skills/mandu-hydration/rules/hydration-priority-visible.md +68 -68
- package/src/resources/skills/mandu-performance/SKILL.md +85 -85
- package/src/resources/skills/mandu-performance/metadata.json +14 -14
- package/src/resources/skills/mandu-performance/rules/_sections.md +31 -31
- package/src/resources/skills/mandu-performance/rules/_template.md +64 -64
- package/src/resources/skills/mandu-performance/rules/perf-async-defer-await.md +103 -103
- package/src/resources/skills/mandu-performance/rules/perf-async-parallel.md +95 -95
- package/src/resources/skills/mandu-performance/rules/perf-bun-file.md +124 -124
- package/src/resources/skills/mandu-performance/rules/perf-bun-serve.md +125 -125
- package/src/resources/skills/mandu-performance/rules/perf-bundle-imports.md +80 -80
- package/src/resources/skills/mandu-performance/rules/perf-bundle-island-lazy.md +145 -145
- package/src/resources/skills/mandu-performance/rules/perf-cache-react.md +98 -98
- package/src/resources/skills/mandu-performance/rules/perf-render-transitions.md +154 -154
- package/src/resources/skills/mandu-security/SKILL.md +87 -87
- package/src/resources/skills/mandu-security/metadata.json +13 -13
- package/src/resources/skills/mandu-security/rules/_sections.md +31 -31
- package/src/resources/skills/mandu-security/rules/_template.md +74 -74
- package/src/resources/skills/mandu-security/rules/sec-auth-guard.md +127 -127
- package/src/resources/skills/mandu-security/rules/sec-env-management.md +133 -133
- package/src/resources/skills/mandu-security/rules/sec-input-validate.md +148 -148
- package/src/resources/skills/mandu-security/rules/sec-protect-csrf.md +146 -146
- package/src/resources/skills/mandu-security/rules/sec-protect-headers.md +138 -138
- package/src/resources/skills/mandu-slot/SKILL.md +85 -85
- package/src/resources/skills/mandu-slot/metadata.json +12 -12
- package/src/resources/skills/mandu-slot/rules/_sections.md +36 -36
- package/src/resources/skills/mandu-slot/rules/_template.md +63 -63
- package/src/resources/skills/mandu-slot/rules/slot-basic-structure.md +38 -38
- package/src/resources/skills/mandu-slot/rules/slot-ctx-response.md +56 -56
- package/src/resources/skills/mandu-slot/rules/slot-guard-auth.md +59 -59
- package/src/resources/skills/mandu-slot/rules/slot-http-methods.md +64 -64
- package/src/resources/skills/mandu-styling/SKILL.md +154 -154
- package/src/resources/skills/mandu-styling/_sections.md +43 -43
- package/src/resources/skills/mandu-styling/_template.md +32 -32
- package/src/resources/skills/mandu-styling/metadata.json +15 -15
- package/src/resources/skills/mandu-styling/rules/style-component-compound.md +235 -235
- package/src/resources/skills/mandu-styling/rules/style-component-slots.md +255 -255
- package/src/resources/skills/mandu-styling/rules/style-component-tokens.md +205 -205
- package/src/resources/skills/mandu-styling/rules/style-island-animations.md +272 -272
- package/src/resources/skills/mandu-styling/rules/style-island-scoping.md +167 -167
- package/src/resources/skills/mandu-styling/rules/style-island-variants.md +221 -221
- package/src/resources/skills/mandu-styling/rules/style-perf-critical.md +209 -209
- package/src/resources/skills/mandu-styling/rules/style-perf-purge.md +192 -192
- package/src/resources/skills/mandu-styling/rules/style-setup-modules.md +162 -162
- package/src/resources/skills/mandu-styling/rules/style-setup-panda.md +164 -164
- package/src/resources/skills/mandu-styling/rules/style-setup-tailwind.md +170 -170
- package/src/resources/skills/mandu-styling/rules/style-tailwind-v4-gotchas.md +179 -179
- package/src/resources/skills/mandu-styling/rules/style-theme-darkmode.md +229 -229
- package/src/resources/skills/mandu-testing/SKILL.md +99 -99
- package/src/resources/skills/mandu-testing/metadata.json +13 -13
- package/src/resources/skills/mandu-testing/rules/_sections.md +26 -26
- package/src/resources/skills/mandu-testing/rules/_template.md +65 -65
- package/src/resources/skills/mandu-testing/rules/test-component-island.md +195 -195
- package/src/resources/skills/mandu-testing/rules/test-e2e-playwright.md +196 -196
- package/src/resources/skills/mandu-testing/rules/test-mock-fetch.md +219 -219
- package/src/resources/skills/mandu-testing/rules/test-slot-unit.md +192 -192
- package/src/resources/skills/mandu-ui/SKILL.md +117 -117
- package/src/resources/skills/mandu-ui/_sections.md +23 -23
- package/src/resources/skills/mandu-ui/_template.md +32 -32
- package/src/resources/skills/mandu-ui/metadata.json +13 -13
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-aria.md +232 -232
- package/src/resources/skills/mandu-ui/rules/ui-accessibility-focus.md +238 -238
- package/src/resources/skills/mandu-ui/rules/ui-composition-patterns.md +259 -259
- package/src/resources/skills/mandu-ui/rules/ui-island-integration.md +258 -258
- package/src/resources/skills/mandu-ui/rules/ui-radix-patterns.md +213 -213
- package/src/resources/skills/mandu-ui/rules/ui-shadcn-setup.md +209 -209
- package/src/resources/skills/recipes.ts +932 -932
- package/src/tools/ate.ts +129 -0
- package/src/tools/index.ts +4 -1
- package/src/tools/project.ts +334 -334
- package/src/tools/runtime.ts +497 -497
- package/src/tools/seo.ts +417 -417
- package/src/utils/withWarnings.ts +83 -83
|
@@ -1,192 +1,192 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: CSS Purge and Tree Shaking
|
|
3
|
-
impact: MEDIUM
|
|
4
|
-
impactDescription: Removes unused CSS for smaller bundles
|
|
5
|
-
tags: styling, performance, purge, tree-shaking
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## CSS Purge and Tree Shaking
|
|
9
|
-
|
|
10
|
-
**Impact: MEDIUM (Removes unused CSS for smaller bundles)**
|
|
11
|
-
|
|
12
|
-
미사용 CSS를 제거하여 번들 크기를 최소화하세요.
|
|
13
|
-
|
|
14
|
-
## Tailwind 자동 Purge
|
|
15
|
-
|
|
16
|
-
Tailwind v3+는 JIT 컴파일로 사용된 클래스만 생성합니다.
|
|
17
|
-
|
|
18
|
-
```typescript
|
|
19
|
-
// tailwind.config.ts
|
|
20
|
-
export default {
|
|
21
|
-
// content 경로가 정확해야 함
|
|
22
|
-
content: [
|
|
23
|
-
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
|
24
|
-
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
25
|
-
"./lib/**/*.{js,ts,jsx,tsx,mdx}",
|
|
26
|
-
],
|
|
27
|
-
// ...
|
|
28
|
-
};
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Safelist 관리
|
|
32
|
-
|
|
33
|
-
```typescript
|
|
34
|
-
// tailwind.config.ts
|
|
35
|
-
export default {
|
|
36
|
-
content: ["./app/**/*.{ts,tsx}"],
|
|
37
|
-
|
|
38
|
-
// 동적으로 생성되는 클래스는 safelist에 추가
|
|
39
|
-
safelist: [
|
|
40
|
-
// 정적 패턴
|
|
41
|
-
"bg-red-500",
|
|
42
|
-
"bg-green-500",
|
|
43
|
-
"bg-blue-500",
|
|
44
|
-
|
|
45
|
-
// 정규식 패턴
|
|
46
|
-
{
|
|
47
|
-
pattern: /bg-(red|green|blue)-(100|500|900)/,
|
|
48
|
-
},
|
|
49
|
-
|
|
50
|
-
// 변형 포함
|
|
51
|
-
{
|
|
52
|
-
pattern: /text-(red|green|blue)-500/,
|
|
53
|
-
variants: ["hover", "dark"],
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
};
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## 동적 클래스 문제 방지
|
|
60
|
-
|
|
61
|
-
```tsx
|
|
62
|
-
// ❌ Tailwind가 감지 못함
|
|
63
|
-
const color = "blue";
|
|
64
|
-
<div className={`bg-${color}-500`} />
|
|
65
|
-
|
|
66
|
-
// ✅ 전체 클래스명 사용
|
|
67
|
-
const colorClasses = {
|
|
68
|
-
blue: "bg-blue-500",
|
|
69
|
-
red: "bg-red-500",
|
|
70
|
-
green: "bg-green-500",
|
|
71
|
-
};
|
|
72
|
-
<div className={colorClasses[color]} />
|
|
73
|
-
|
|
74
|
-
// ✅ cva 사용
|
|
75
|
-
const badge = cva("px-2 py-1 rounded", {
|
|
76
|
-
variants: {
|
|
77
|
-
color: {
|
|
78
|
-
blue: "bg-blue-500",
|
|
79
|
-
red: "bg-red-500",
|
|
80
|
-
green: "bg-green-500",
|
|
81
|
-
},
|
|
82
|
-
},
|
|
83
|
-
});
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## PurgeCSS 수동 설정
|
|
87
|
-
|
|
88
|
-
Tailwind 외 CSS 파일용:
|
|
89
|
-
|
|
90
|
-
```bash
|
|
91
|
-
bun add -d purgecss
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
```javascript
|
|
95
|
-
// purgecss.config.js
|
|
96
|
-
export default {
|
|
97
|
-
content: ["./app/**/*.tsx", "./components/**/*.tsx"],
|
|
98
|
-
css: ["./styles/legacy.css"],
|
|
99
|
-
output: "./dist/styles/",
|
|
100
|
-
|
|
101
|
-
// 유지할 선택자
|
|
102
|
-
safelist: {
|
|
103
|
-
standard: [/^data-/],
|
|
104
|
-
deep: [/^modal/],
|
|
105
|
-
greedy: [/tooltip/],
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
// 커스텀 추출기
|
|
109
|
-
extractors: [
|
|
110
|
-
{
|
|
111
|
-
extractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
|
|
112
|
-
extensions: ["tsx", "ts"],
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
};
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
```bash
|
|
119
|
-
bunx purgecss --config purgecss.config.js
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
## CSS Modules 최적화
|
|
123
|
-
|
|
124
|
-
CSS Modules는 자동으로 스코프되지만, 미사용 클래스는 제거되지 않음:
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
bun add -d postcss-modules
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
```javascript
|
|
131
|
-
// postcss.config.js
|
|
132
|
-
export default {
|
|
133
|
-
plugins: {
|
|
134
|
-
"postcss-modules": {
|
|
135
|
-
generateScopedName: "[name]__[local]___[hash:base64:5]",
|
|
136
|
-
// 미사용 export 경고
|
|
137
|
-
getJSON: (cssFileName, json) => {
|
|
138
|
-
// 사용되지 않은 클래스 로깅
|
|
139
|
-
console.log(`CSS Modules in ${cssFileName}:`, Object.keys(json));
|
|
140
|
-
},
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
## 번들 분석
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
# CSS 번들 크기 분석
|
|
150
|
-
bun add -d source-map-explorer
|
|
151
|
-
|
|
152
|
-
# 분석 실행
|
|
153
|
-
bunx source-map-explorer dist/styles.css --html report.html
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
## 빌드 스크립트
|
|
157
|
-
|
|
158
|
-
```typescript
|
|
159
|
-
// scripts/analyze-css.ts
|
|
160
|
-
import { Glob } from "bun";
|
|
161
|
-
|
|
162
|
-
const cssGlob = new Glob("dist/**/*.css");
|
|
163
|
-
let totalSize = 0;
|
|
164
|
-
|
|
165
|
-
for await (const file of cssGlob.scan()) {
|
|
166
|
-
const stat = await Bun.file(file).size;
|
|
167
|
-
console.log(`${file}: ${(stat / 1024).toFixed(2)} KB`);
|
|
168
|
-
totalSize += stat;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
console.log(`\nTotal CSS: ${(totalSize / 1024).toFixed(2)} KB`);
|
|
172
|
-
|
|
173
|
-
// 경고 임계값
|
|
174
|
-
if (totalSize > 50 * 1024) {
|
|
175
|
-
console.warn("⚠️ CSS bundle exceeds 50KB");
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
## CI에서 크기 체크
|
|
180
|
-
|
|
181
|
-
```yaml
|
|
182
|
-
# .github/workflows/ci.yml
|
|
183
|
-
- name: Check CSS size
|
|
184
|
-
run: |
|
|
185
|
-
SIZE=$(stat -f%z dist/styles.css 2>/dev/null || stat -c%s dist/styles.css)
|
|
186
|
-
if [ $SIZE -gt 51200 ]; then
|
|
187
|
-
echo "CSS size ($SIZE bytes) exceeds 50KB limit"
|
|
188
|
-
exit 1
|
|
189
|
-
fi
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
Reference: [Tailwind Optimizing for Production](https://tailwindcss.com/docs/optimizing-for-production)
|
|
1
|
+
---
|
|
2
|
+
title: CSS Purge and Tree Shaking
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: Removes unused CSS for smaller bundles
|
|
5
|
+
tags: styling, performance, purge, tree-shaking
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## CSS Purge and Tree Shaking
|
|
9
|
+
|
|
10
|
+
**Impact: MEDIUM (Removes unused CSS for smaller bundles)**
|
|
11
|
+
|
|
12
|
+
미사용 CSS를 제거하여 번들 크기를 최소화하세요.
|
|
13
|
+
|
|
14
|
+
## Tailwind 자동 Purge
|
|
15
|
+
|
|
16
|
+
Tailwind v3+는 JIT 컴파일로 사용된 클래스만 생성합니다.
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
// tailwind.config.ts
|
|
20
|
+
export default {
|
|
21
|
+
// content 경로가 정확해야 함
|
|
22
|
+
content: [
|
|
23
|
+
"./app/**/*.{js,ts,jsx,tsx,mdx}",
|
|
24
|
+
"./components/**/*.{js,ts,jsx,tsx,mdx}",
|
|
25
|
+
"./lib/**/*.{js,ts,jsx,tsx,mdx}",
|
|
26
|
+
],
|
|
27
|
+
// ...
|
|
28
|
+
};
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Safelist 관리
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
// tailwind.config.ts
|
|
35
|
+
export default {
|
|
36
|
+
content: ["./app/**/*.{ts,tsx}"],
|
|
37
|
+
|
|
38
|
+
// 동적으로 생성되는 클래스는 safelist에 추가
|
|
39
|
+
safelist: [
|
|
40
|
+
// 정적 패턴
|
|
41
|
+
"bg-red-500",
|
|
42
|
+
"bg-green-500",
|
|
43
|
+
"bg-blue-500",
|
|
44
|
+
|
|
45
|
+
// 정규식 패턴
|
|
46
|
+
{
|
|
47
|
+
pattern: /bg-(red|green|blue)-(100|500|900)/,
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// 변형 포함
|
|
51
|
+
{
|
|
52
|
+
pattern: /text-(red|green|blue)-500/,
|
|
53
|
+
variants: ["hover", "dark"],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 동적 클래스 문제 방지
|
|
60
|
+
|
|
61
|
+
```tsx
|
|
62
|
+
// ❌ Tailwind가 감지 못함
|
|
63
|
+
const color = "blue";
|
|
64
|
+
<div className={`bg-${color}-500`} />
|
|
65
|
+
|
|
66
|
+
// ✅ 전체 클래스명 사용
|
|
67
|
+
const colorClasses = {
|
|
68
|
+
blue: "bg-blue-500",
|
|
69
|
+
red: "bg-red-500",
|
|
70
|
+
green: "bg-green-500",
|
|
71
|
+
};
|
|
72
|
+
<div className={colorClasses[color]} />
|
|
73
|
+
|
|
74
|
+
// ✅ cva 사용
|
|
75
|
+
const badge = cva("px-2 py-1 rounded", {
|
|
76
|
+
variants: {
|
|
77
|
+
color: {
|
|
78
|
+
blue: "bg-blue-500",
|
|
79
|
+
red: "bg-red-500",
|
|
80
|
+
green: "bg-green-500",
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## PurgeCSS 수동 설정
|
|
87
|
+
|
|
88
|
+
Tailwind 외 CSS 파일용:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
bun add -d purgecss
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
// purgecss.config.js
|
|
96
|
+
export default {
|
|
97
|
+
content: ["./app/**/*.tsx", "./components/**/*.tsx"],
|
|
98
|
+
css: ["./styles/legacy.css"],
|
|
99
|
+
output: "./dist/styles/",
|
|
100
|
+
|
|
101
|
+
// 유지할 선택자
|
|
102
|
+
safelist: {
|
|
103
|
+
standard: [/^data-/],
|
|
104
|
+
deep: [/^modal/],
|
|
105
|
+
greedy: [/tooltip/],
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
// 커스텀 추출기
|
|
109
|
+
extractors: [
|
|
110
|
+
{
|
|
111
|
+
extractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],
|
|
112
|
+
extensions: ["tsx", "ts"],
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
bunx purgecss --config purgecss.config.js
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## CSS Modules 최적화
|
|
123
|
+
|
|
124
|
+
CSS Modules는 자동으로 스코프되지만, 미사용 클래스는 제거되지 않음:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
bun add -d postcss-modules
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
// postcss.config.js
|
|
132
|
+
export default {
|
|
133
|
+
plugins: {
|
|
134
|
+
"postcss-modules": {
|
|
135
|
+
generateScopedName: "[name]__[local]___[hash:base64:5]",
|
|
136
|
+
// 미사용 export 경고
|
|
137
|
+
getJSON: (cssFileName, json) => {
|
|
138
|
+
// 사용되지 않은 클래스 로깅
|
|
139
|
+
console.log(`CSS Modules in ${cssFileName}:`, Object.keys(json));
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
};
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 번들 분석
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
# CSS 번들 크기 분석
|
|
150
|
+
bun add -d source-map-explorer
|
|
151
|
+
|
|
152
|
+
# 분석 실행
|
|
153
|
+
bunx source-map-explorer dist/styles.css --html report.html
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## 빌드 스크립트
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
// scripts/analyze-css.ts
|
|
160
|
+
import { Glob } from "bun";
|
|
161
|
+
|
|
162
|
+
const cssGlob = new Glob("dist/**/*.css");
|
|
163
|
+
let totalSize = 0;
|
|
164
|
+
|
|
165
|
+
for await (const file of cssGlob.scan()) {
|
|
166
|
+
const stat = await Bun.file(file).size;
|
|
167
|
+
console.log(`${file}: ${(stat / 1024).toFixed(2)} KB`);
|
|
168
|
+
totalSize += stat;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log(`\nTotal CSS: ${(totalSize / 1024).toFixed(2)} KB`);
|
|
172
|
+
|
|
173
|
+
// 경고 임계값
|
|
174
|
+
if (totalSize > 50 * 1024) {
|
|
175
|
+
console.warn("⚠️ CSS bundle exceeds 50KB");
|
|
176
|
+
}
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## CI에서 크기 체크
|
|
180
|
+
|
|
181
|
+
```yaml
|
|
182
|
+
# .github/workflows/ci.yml
|
|
183
|
+
- name: Check CSS size
|
|
184
|
+
run: |
|
|
185
|
+
SIZE=$(stat -f%z dist/styles.css 2>/dev/null || stat -c%s dist/styles.css)
|
|
186
|
+
if [ $SIZE -gt 51200 ]; then
|
|
187
|
+
echo "CSS size ($SIZE bytes) exceeds 50KB limit"
|
|
188
|
+
exit 1
|
|
189
|
+
fi
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Reference: [Tailwind Optimizing for Production](https://tailwindcss.com/docs/optimizing-for-production)
|