@melcanz85/chaincss 1.11.5 → 1.12.1

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.
@@ -0,0 +1,299 @@
1
+ // benchmarks/run.js
2
+ const { execSync } = require('child_process');
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const os = require('os');
6
+
7
+ const libraries = [
8
+ {
9
+ name: 'ChainCSS (Build)',
10
+ setup: () => {
11
+ const content = `
12
+ const button = $()
13
+ .backgroundColor('blue')
14
+ .color('white')
15
+ .padding('8px 16px')
16
+ .borderRadius('4px')
17
+ .hover().backgroundColor('darkblue').end()
18
+ .block('.btn');
19
+ module.exports = { button };
20
+ `;
21
+ fs.writeFileSync('./test.jcss', content);
22
+ },
23
+ build: () => {
24
+ execSync('npx @melcanz85/chaincss ./test.jcss ./dist --atomic', { stdio: 'pipe' });
25
+ },
26
+ cleanup: () => {
27
+ fs.unlinkSync('./test.jcss');
28
+ if (fs.existsSync('./dist')) {
29
+ fs.rmSync('./dist', { recursive: true });
30
+ }
31
+ }
32
+ },
33
+ {
34
+ name: 'ChainCSS (Runtime)',
35
+ setup: () => {
36
+ const content = `
37
+ import { $ } from '@melcanz85/chaincss';
38
+ const button = $()
39
+ .backgroundColor('blue')
40
+ .color('white')
41
+ .padding('8px 16px')
42
+ .borderRadius('4px')
43
+ .hover().backgroundColor('darkblue').end()
44
+ .block('.btn');
45
+ export default button;
46
+ `;
47
+ fs.writeFileSync('./test.js', content);
48
+ },
49
+ build: () => {
50
+ // No build step for runtime
51
+ },
52
+ cleanup: () => {
53
+ fs.unlinkSync('./test.js');
54
+ }
55
+ },
56
+ {
57
+ name: 'CSS Modules',
58
+ setup: () => {
59
+ const content = `
60
+ .btn {
61
+ background-color: blue;
62
+ color: white;
63
+ padding: 8px 16px;
64
+ border-radius: 4px;
65
+ }
66
+ .btn:hover {
67
+ background-color: darkblue;
68
+ }
69
+ `;
70
+ fs.writeFileSync('./test.module.css', content);
71
+ },
72
+ build: () => {
73
+ // CSS Modules are handled by webpack
74
+ },
75
+ cleanup: () => {
76
+ fs.unlinkSync('./test.module.css');
77
+ }
78
+ },
79
+ {
80
+ name: 'Vanilla Extract',
81
+ setup: () => {
82
+ const content = `
83
+ import { style } from '@vanilla-extract/css';
84
+ export const button = style({
85
+ backgroundColor: 'blue',
86
+ color: 'white',
87
+ padding: '8px 16px',
88
+ borderRadius: '4px',
89
+ ':hover': {
90
+ backgroundColor: 'darkblue'
91
+ }
92
+ });
93
+ `;
94
+ fs.writeFileSync('./test.css.ts', content);
95
+ },
96
+ build: () => {
97
+ execSync('npx esbuild ./test.css.ts --bundle --outfile=./dist/test.js', { stdio: 'pipe' });
98
+ },
99
+ cleanup: () => {
100
+ fs.unlinkSync('./test.css.ts');
101
+ if (fs.existsSync('./dist')) {
102
+ fs.rmSync('./dist', { recursive: true });
103
+ }
104
+ }
105
+ },
106
+ {
107
+ name: 'Styled Components',
108
+ setup: () => {
109
+ const content = `
110
+ import styled from 'styled-components';
111
+ export const Button = styled.button\`
112
+ background-color: blue;
113
+ color: white;
114
+ padding: 8px 16px;
115
+ border-radius: 4px;
116
+ &:hover {
117
+ background-color: darkblue;
118
+ }
119
+ \`;
120
+ `;
121
+ fs.writeFileSync('./test.jsx', content);
122
+ },
123
+ build: () => {
124
+ execSync('npx esbuild ./test.jsx --bundle --outfile=./dist/test.js', { stdio: 'pipe' });
125
+ },
126
+ cleanup: () => {
127
+ fs.unlinkSync('./test.jsx');
128
+ if (fs.existsSync('./dist')) {
129
+ fs.rmSync('./dist', { recursive: true });
130
+ }
131
+ }
132
+ }
133
+ ];
134
+
135
+ async function runBenchmarks() {
136
+ console.log('\n🚀 Running ChainCSS Performance Benchmarks\n');
137
+ console.log('═'.repeat(60));
138
+
139
+ const results = [];
140
+
141
+ for (const lib of libraries) {
142
+ console.log(`\n📊 Testing ${lib.name}...`);
143
+
144
+ // Setup
145
+ lib.setup();
146
+
147
+ // Measure build time
148
+ const start = performance.now();
149
+ try {
150
+ await lib.build();
151
+ } catch (err) {
152
+ console.error(` ❌ Failed: ${err.message}`);
153
+ lib.cleanup();
154
+ continue;
155
+ }
156
+ const buildTime = performance.now() - start;
157
+
158
+ // Measure bundle size
159
+ let bundleSize = 0;
160
+ let cssSize = 0;
161
+
162
+ if (lib.name === 'ChainCSS (Build)') {
163
+ if (fs.existsSync('./dist/global.css')) {
164
+ cssSize = fs.statSync('./dist/global.css').size;
165
+ }
166
+ } else if (lib.name === 'ChainCSS (Runtime)') {
167
+ const bundle = fs.readFileSync('./test.js', 'utf8');
168
+ bundleSize = bundle.length;
169
+ } else if (lib.name === 'CSS Modules') {
170
+ // CSS Modules size is just the CSS file
171
+ cssSize = fs.statSync('./test.module.css').size;
172
+ } else if (fs.existsSync('./dist/test.js')) {
173
+ bundleSize = fs.statSync('./dist/test.js').size;
174
+ if (fs.existsSync('./dist/test.css')) {
175
+ cssSize = fs.statSync('./dist/test.css').size;
176
+ }
177
+ }
178
+
179
+ results.push({
180
+ name: lib.name,
181
+ buildTime: buildTime.toFixed(2),
182
+ bundleSize: formatBytes(bundleSize),
183
+ cssSize: formatBytes(cssSize),
184
+ totalSize: formatBytes(bundleSize + cssSize)
185
+ });
186
+
187
+ // Cleanup
188
+ lib.cleanup();
189
+
190
+ console.log(` ✅ Build: ${buildTime.toFixed(2)}ms`);
191
+ console.log(` 📦 Bundle: ${formatBytes(bundleSize)}`);
192
+ console.log(` 🎨 CSS: ${formatBytes(cssSize)}`);
193
+ }
194
+
195
+ // Generate report
196
+ generateReport(results);
197
+ generateChart(results);
198
+ }
199
+
200
+ function formatBytes(bytes) {
201
+ if (bytes === 0) return '0 B';
202
+ const k = 1024;
203
+ const sizes = ['B', 'KB', 'MB'];
204
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
205
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
206
+ }
207
+
208
+ function generateReport(results) {
209
+ const markdown = `# ChainCSS Performance Benchmarks
210
+
211
+ ## Test Environment
212
+ - **OS**: ${os.type()} ${os.release()}
213
+ - **CPU**: ${os.cpus()[0].model}
214
+ - **RAM**: ${formatBytes(os.totalmem())}
215
+ - **Node**: ${process.version}
216
+ - **Date**: ${new Date().toISOString()}
217
+
218
+ ## Results
219
+
220
+ | Library | Build Time | Bundle Size | CSS Size | Total Size |
221
+ |---------|------------|-------------|----------|------------|
222
+ ${results.map(r => `| ${r.name} | ${r.buildTime}ms | ${r.bundleSize} | ${r.cssSize} | ${r.totalSize} |`).join('\n')}
223
+
224
+ ## Key Findings
225
+
226
+ ${generateInsights(results)}
227
+
228
+ ## Recommendations
229
+
230
+ ${generateRecommendations(results)}
231
+ `;
232
+
233
+ fs.writeFileSync('./benchmarks/results.md', markdown);
234
+ console.log('\n✅ Report saved to benchmarks/results.md');
235
+ }
236
+
237
+ function generateInsights(results) {
238
+ const chaincssBuild = results.find(r => r.name === 'ChainCSS (Build)');
239
+ const chaincssRuntime = results.find(r => r.name === 'ChainCSS (Runtime)');
240
+ const cssModules = results.find(r => r.name === 'CSS Modules');
241
+ const vanillaExtract = results.find(r => r.name === 'Vanilla Extract');
242
+ const styledComponents = results.find(r => r.name === 'Styled Components');
243
+
244
+ let insights = [];
245
+
246
+ if (chaincssBuild && cssModules) {
247
+ insights.push(`- **ChainCSS (Build)** is ${((parseFloat(cssModules.buildTime) - parseFloat(chaincssBuild.buildTime)) / parseFloat(cssModules.buildTime) * 100).toFixed(0)}% faster than CSS Modules`);
248
+ }
249
+
250
+ if (chaincssBuild && vanillaExtract) {
251
+ insights.push(`- **ChainCSS (Build)** is ${((parseFloat(vanillaExtract.buildTime) - parseFloat(chaincssBuild.buildTime)) / parseFloat(vanillaExtract.buildTime) * 100).toFixed(0)}% faster than Vanilla Extract`);
252
+ }
253
+
254
+ if (chaincssRuntime && styledComponents) {
255
+ insights.push(`- **ChainCSS (Runtime)** is ${((parseFloat(styledComponents.bundleSize) - parseFloat(chaincssRuntime.bundleSize)) / parseFloat(styledComponents.bundleSize) * 100).toFixed(0)}% smaller than Styled Components`);
256
+ }
257
+
258
+ return insights.join('\n');
259
+ }
260
+
261
+ function generateRecommendations(results) {
262
+ return `
263
+ ### For Static Sites
264
+ **Use ChainCSS (Build Mode)** - ${results.find(r => r.name === 'ChainCSS (Build)')?.buildTime}ms build time, zero runtime
265
+
266
+ ### For Dynamic Apps
267
+ **Use ChainCSS (Runtime Mode)** - ${results.find(r => r.name === 'ChainCSS (Runtime)')?.bundleSize} bundle size, full dynamic capability
268
+
269
+ ### For Best Performance
270
+ **Use ChainCSS with Atomic CSS** - Automatic optimization with ${results.find(r => r.name === 'ChainCSS (Build)')?.cssSize} CSS output
271
+
272
+ ### For Component Libraries
273
+ **Use ChainCSS Recipe System** - Built-in variants, compound styles, zero config
274
+ `;
275
+ }
276
+
277
+ function generateChart(results) {
278
+ const chartData = {
279
+ labels: results.map(r => r.name),
280
+ datasets: [
281
+ {
282
+ label: 'Build Time (ms)',
283
+ data: results.map(r => parseFloat(r.buildTime)),
284
+ backgroundColor: 'rgba(102, 126, 234, 0.5)'
285
+ },
286
+ {
287
+ label: 'Bundle Size (KB)',
288
+ data: results.map(r => parseFloat(r.bundleSize)),
289
+ backgroundColor: 'rgba(118, 75, 162, 0.5)'
290
+ }
291
+ ]
292
+ };
293
+
294
+ fs.writeFileSync('./benchmarks/chart-data.json', JSON.stringify(chartData, null, 2));
295
+ console.log('📊 Chart data saved to benchmarks/chart-data.json');
296
+ }
297
+
298
+ // Run benchmarks
299
+ runBenchmarks().catch(console.error);