@ovh-ux/manager-static-analysis-kit 0.7.1 → 0.8.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.
Files changed (36) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/bin/cli-utils.js +56 -0
  3. package/bin/lint-cli.js +18 -16
  4. package/bin/perf-budgets-cli.js +359 -0
  5. package/bin/perf-budgets-tests-cli.js +74 -0
  6. package/dist/adapters/eslint/rules/eslint-naming-conventions.d.ts.map +1 -1
  7. package/dist/adapters/eslint/rules/eslint-naming-conventions.js +1 -0
  8. package/dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.d.ts +7 -0
  9. package/dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.d.ts.map +1 -0
  10. package/dist/adapters/perf-budgets/helpers/perfs-bundle-analysis-helper.js +192 -0
  11. package/dist/adapters/perf-budgets/rules/perfs-budgets-rules.d.ts +10 -0
  12. package/dist/adapters/perf-budgets/rules/perfs-budgets-rules.d.ts.map +1 -0
  13. package/dist/adapters/perf-budgets/rules/perfs-budgets-rules.js +20 -0
  14. package/dist/adapters/perf-budgets/rules/perfs-budgets-scoring.d.ts +5 -0
  15. package/dist/adapters/perf-budgets/rules/perfs-budgets-scoring.d.ts.map +1 -0
  16. package/dist/adapters/perf-budgets/rules/perfs-budgets-scoring.js +35 -0
  17. package/dist/adapters/perf-budgets/types/PerfBudget.d.ts +22 -0
  18. package/dist/adapters/perf-budgets/types/PerfBudget.d.ts.map +1 -0
  19. package/dist/adapters/perf-budgets/types/PerfBudget.js +1 -0
  20. package/dist/adapters/perf-budgets/types/PerfBudgetAssets.d.ts +13 -0
  21. package/dist/adapters/perf-budgets/types/PerfBudgetAssets.d.ts.map +1 -0
  22. package/dist/adapters/perf-budgets/types/PerfBudgetAssets.js +1 -0
  23. package/dist/adapters/perf-budgets/types/PerfBudgetScore.d.ts +13 -0
  24. package/dist/adapters/perf-budgets/types/PerfBudgetScore.d.ts.map +1 -0
  25. package/dist/adapters/perf-budgets/types/PerfBudgetScore.js +1 -0
  26. package/dist/configs/assets-budgets-config.d.ts +28 -0
  27. package/dist/configs/assets-budgets-config.d.ts.map +1 -0
  28. package/dist/configs/assets-budgets-config.js +45 -0
  29. package/dist/configs/bundle-analysis-config.d.ts +8 -0
  30. package/dist/configs/bundle-analysis-config.d.ts.map +1 -0
  31. package/dist/configs/bundle-analysis-config.js +7 -0
  32. package/dist/configs/file-globs-config.d.ts +1 -1
  33. package/dist/configs/file-globs-config.d.ts.map +1 -1
  34. package/dist/configs/file-globs-config.js +1 -1
  35. package/dist/tsconfig.tsbuildinfo +1 -1
  36. package/package.json +6 -3
@@ -0,0 +1,192 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { assetsBudgetsConfig } from '../../../configs/assets-budgets-config.js';
4
+ import { evaluatePerfBudgets } from '../rules/perfs-budgets-rules.js';
5
+ import { scoreAllPerfBudgets } from '../rules/perfs-budgets-scoring.js';
6
+ const perfBudgetsReportDirName = 'perf-budgets-reports';
7
+ export function escapeHtml(str) {
8
+ return String(str)
9
+ .replace(/&/g, '&')
10
+ .replace(/</g, '&lt;')
11
+ .replace(/>/g, '&gt;')
12
+ .replace(/"/g, '&quot;')
13
+ .replace(/'/g, '&#039;');
14
+ }
15
+ const buildAssetsInfos = (data) => data.map((entry) => {
16
+ const filename = entry?.filename ?? 'unknown';
17
+ const sizeKb = typeof entry?.parsedSize === 'number' ? entry.parsedSize / 1024 : 0;
18
+ let type = 'other';
19
+ if (/\.js$/i.test(filename))
20
+ type = 'js';
21
+ else if (/\.css$/i.test(filename))
22
+ type = 'css';
23
+ else if (/\.html$/i.test(filename))
24
+ type = 'html';
25
+ else if (/\.(png|jpe?g|gif|svg|webp)$/i.test(filename))
26
+ type = 'img';
27
+ return { filename, type, sizeKb };
28
+ });
29
+ export function parseAnalyzerJson(raw) {
30
+ if (!Array.isArray(raw)) {
31
+ return { jsKb: 0, cssKb: 0, htmlKb: 0, imgKb: 0, assets: [] };
32
+ }
33
+ const assets = buildAssetsInfos(raw);
34
+ const sumByType = (type) => assets.filter((a) => a.type === type).reduce((sum, a) => sum + a.sizeKb, 0);
35
+ return {
36
+ jsKb: sumByType('js'),
37
+ cssKb: sumByType('css'),
38
+ htmlKb: sumByType('html'),
39
+ imgKb: sumByType('img'),
40
+ assets,
41
+ };
42
+ }
43
+ export function collectPerfBudgets(rootDir) {
44
+ const reportsRoot = path.join(rootDir, perfBudgetsReportDirName);
45
+ if (!fs.existsSync(reportsRoot)) {
46
+ throw new Error(`Reports directory not found: ${reportsRoot}`);
47
+ }
48
+ const apps = fs.readdirSync(reportsRoot).filter((d) => {
49
+ const appJson = path.join(reportsRoot, d, 'bundle-report.json');
50
+ return fs.existsSync(appJson);
51
+ });
52
+ const results = [];
53
+ for (const app of apps) {
54
+ const jsonPath = path.join(reportsRoot, app, 'bundle-report.json');
55
+ const raw = JSON.parse(fs.readFileSync(jsonPath, 'utf-8'));
56
+ const { jsKb, cssKb, htmlKb, imgKb, assets } = parseAnalyzerJson(raw);
57
+ const appResult = {
58
+ ...evaluatePerfBudgets({ app, jsKb, cssKb, htmlKb, imgKb }),
59
+ assets,
60
+ };
61
+ results.push(appResult);
62
+ }
63
+ const scores = scoreAllPerfBudgets(results);
64
+ return {
65
+ results,
66
+ scores,
67
+ medians: assetsBudgetsConfig.medians,
68
+ };
69
+ }
70
+ export function generatePerfBudgetsHtml(summary) {
71
+ const { results, scores, medians } = summary;
72
+ const heavyCount = assetsBudgetsConfig.heavyAssetsCount;
73
+ function colorizeClass(status) {
74
+ switch (status) {
75
+ case 'ok':
76
+ return 'status-ok';
77
+ case 'near':
78
+ return 'status-near';
79
+ case 'exceed':
80
+ return 'status-exceed';
81
+ }
82
+ }
83
+ function heaviestOfType(assets, type) {
84
+ return assets.filter((a) => a.type === type).sort((a, b) => b.sizeKb - a.sizeKb)[0];
85
+ }
86
+ function formatCell(total, status, type, assets) {
87
+ const heavy = heaviestOfType(assets, type);
88
+ const heavyInfo = heavy
89
+ ? `<br/><small><b>Largest ${type.toUpperCase()} asset:</b> <code>${escapeHtml(heavy.filename)}</code> — ${heavy.sizeKb.toFixed(1)} KB</small>`
90
+ : '';
91
+ return `<td class="${colorizeClass(status)}">
92
+ <b>Total ${type.toUpperCase()} assets size:</b> ${total.toFixed(1)} KB
93
+ ${heavyInfo}
94
+ </td>`;
95
+ }
96
+ const rows = scores
97
+ .map((s) => {
98
+ const result = results.find((r) => r.app === s.app);
99
+ const heavyAssets = [...result.assets]
100
+ .sort((a, b) => b.sizeKb - a.sizeKb)
101
+ .slice(0, heavyCount);
102
+ const assetsHtml = heavyAssets
103
+ .map((a) => `<li><code>${escapeHtml(a.filename)}</code> — <strong>${a.sizeKb.toFixed(1)} KB</strong> (${a.type})</li>`)
104
+ .join('\n');
105
+ return `
106
+ <tr>
107
+ <td><strong>${escapeHtml(s.app)}</strong></td>
108
+ ${formatCell(result.jsKb, result.jsStatus, 'js', result.assets)}
109
+ ${formatCell(result.cssKb, result.cssStatus, 'css', result.assets)}
110
+ ${formatCell(result.htmlKb, result.htmlStatus, 'html', result.assets)}
111
+ ${formatCell(result.imgKb, result.imgStatus, 'img', result.assets)}
112
+ <td><b>${escapeHtml(s.status.toUpperCase())}</b></td>
113
+ <td>
114
+ <details>
115
+ <summary>Top ${heavyCount} Assets</summary>
116
+ <ul>${assetsHtml || '<li>No assets found</li>'}</ul>
117
+ </details>
118
+ </td>
119
+ </tr>
120
+ `;
121
+ })
122
+ .join('\n');
123
+ const linksHtml = assetsBudgetsConfig.links.httpArchive
124
+ .map(({ label, url }) => `<li><a href="${escapeHtml(url)}" target="_blank">${escapeHtml(label)}</a></li>`)
125
+ .join('\n');
126
+ const tipsHtml = assetsBudgetsConfig.links.tips
127
+ .map(({ label, desc }) => `<li><strong>${escapeHtml(label)}:</strong> ${escapeHtml(desc)}</li>`)
128
+ .join('\n');
129
+ const optimizationHtml = assetsBudgetsConfig.links.optimization
130
+ .map(({ label, url }) => `<li><a href="${escapeHtml(url)}" target="_blank">${escapeHtml(label)}</a></li>`)
131
+ .join('\n');
132
+ return `
133
+ <html lang="en">
134
+ <head>
135
+ <meta charset="UTF-8" />
136
+ <title>Perf Budgets Report</title>
137
+ <style>
138
+ body { font-family: Arial, sans-serif; padding: 20px; background: #fafafa; }
139
+ h1, h2 { text-align: center; }
140
+ table { width: 100%; border-collapse: collapse; margin-top: 20px; }
141
+ th, td { border: 1px solid #ddd; padding: 8px; text-align: left; vertical-align: top; }
142
+ th { background: #f0f0f0; }
143
+ tr:nth-child(even) { background: #f9f9f9; }
144
+ tr:hover { background: #f1f7ff; }
145
+ .status-ok { background: #e6f9e6; color: #207520; }
146
+ .status-near { background: #fff8e1; color: #a87900; }
147
+ .status-exceed { background: #fdecea; color: #b71c1c; }
148
+ code { font-family: monospace; background: #f5f5f5; padding: 1px 3px; border-radius: 3px; }
149
+ details summary { cursor: pointer; }
150
+ .box { border: 1px solid #ccc; background: #fff; padding: 10px; margin: 15px 0; border-radius: 6px; }
151
+ </style>
152
+ </head>
153
+ <body>
154
+ <h1>Performance Budgets Report</h1>
155
+ <div class="box">
156
+ <h2>Medians (Desktop)</h2>
157
+ <p>
158
+ JS: ${medians.jsKb} KB ·
159
+ CSS: ${medians.cssKb} KB ·
160
+ HTML: ${medians.htmlKb} KB ·
161
+ IMG: ${medians.imgKb} KB
162
+ </p>
163
+ <p><b>Links:</b></p>
164
+ <ul>${linksHtml}</ul>
165
+ </div>
166
+
167
+ <div class="box">
168
+ <details open>
169
+ <summary><b>Optimization & Best Practices</b></summary>
170
+ <h3>Tips</h3>
171
+ <ul>${tipsHtml}</ul>
172
+ <h3>Resources</h3>
173
+ <ul>${optimizationHtml}</ul>
174
+ </details>
175
+ </div>
176
+
177
+ <h2>Applications</h2>
178
+ <table>
179
+ <tr>
180
+ <th>App</th>
181
+ <th>JS</th>
182
+ <th>CSS</th>
183
+ <th>HTML</th>
184
+ <th>IMG</th>
185
+ <th>Status</th>
186
+ <th>Details</th>
187
+ </tr>
188
+ ${rows}
189
+ </table>
190
+ </body>
191
+ </html>`;
192
+ }
@@ -0,0 +1,10 @@
1
+ import { PerfBudgetResult } from '../types/PerfBudget.js';
2
+ export declare function evaluateAsset(sizeKb: number, medianKb: number): 'ok' | 'near' | 'exceed';
3
+ export declare function evaluatePerfBudgets(appReport: {
4
+ app: string;
5
+ jsKb: number;
6
+ cssKb: number;
7
+ htmlKb: number;
8
+ imgKb: number;
9
+ }): PerfBudgetResult;
10
+ //# sourceMappingURL=perfs-budgets-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perfs-budgets-rules.d.ts","sourceRoot":"","sources":["../../../../src/adapters/perf-budgets/rules/perfs-budgets-rules.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAQvD,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,QAAQ,CASxF;AAOD,wBAAgB,mBAAmB,CAAC,SAAS,EAAE;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,gBAAgB,CAQnB"}
@@ -0,0 +1,20 @@
1
+ import { assetsBudgetsConfig } from '../../../configs/assets-budgets-config.js';
2
+ export function evaluateAsset(sizeKb, medianKb) {
3
+ const { nearFactor, exceedFactor } = assetsBudgetsConfig.thresholds;
4
+ if (sizeKb > medianKb * exceedFactor) {
5
+ return 'exceed';
6
+ }
7
+ else if (sizeKb >= medianKb * nearFactor) {
8
+ return 'near';
9
+ }
10
+ return 'ok';
11
+ }
12
+ export function evaluatePerfBudgets(appReport) {
13
+ return {
14
+ ...appReport,
15
+ jsStatus: evaluateAsset(appReport.jsKb, assetsBudgetsConfig.medians.jsKb),
16
+ cssStatus: evaluateAsset(appReport.cssKb, assetsBudgetsConfig.medians.cssKb),
17
+ htmlStatus: evaluateAsset(appReport.htmlKb, assetsBudgetsConfig.medians.htmlKb),
18
+ imgStatus: evaluateAsset(appReport.imgKb, assetsBudgetsConfig.medians.imgKb),
19
+ };
20
+ }
@@ -0,0 +1,5 @@
1
+ import { PerfBudgetResult } from '../types/PerfBudget.js';
2
+ import { PerfBudgetScoreSummary } from '../types/PerfBudgetScore.js';
3
+ export declare function scorePerfBudget(result: PerfBudgetResult): PerfBudgetScoreSummary;
4
+ export declare function scoreAllPerfBudgets(results: PerfBudgetResult[]): PerfBudgetScoreSummary[];
5
+ //# sourceMappingURL=perfs-budgets-scoring.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perfs-budgets-scoring.d.ts","sourceRoot":"","sources":["../../../../src/adapters/perf-budgets/rules/perfs-budgets-scoring.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAwB,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAuBxF,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,sBAAsB,CAqBhF;AAOD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,sBAAsB,EAAE,CAEzF"}
@@ -0,0 +1,35 @@
1
+ function statusToScore(status) {
2
+ switch (status) {
3
+ case 'ok':
4
+ return 0;
5
+ case 'near':
6
+ return 1;
7
+ case 'exceed':
8
+ return 2;
9
+ }
10
+ }
11
+ export function scorePerfBudget(result) {
12
+ const scores = {
13
+ js: statusToScore(result.jsStatus),
14
+ css: statusToScore(result.cssStatus),
15
+ html: statusToScore(result.htmlStatus),
16
+ img: statusToScore(result.imgStatus),
17
+ };
18
+ const totalScore = Object.values(scores).reduce((sum, v) => sum + v, 0);
19
+ let status;
20
+ if (totalScore === 0)
21
+ status = 'pass';
22
+ else if (totalScore <= 2)
23
+ status = 'warn';
24
+ else
25
+ status = 'fail';
26
+ return {
27
+ app: result.app,
28
+ scores,
29
+ totalScore,
30
+ status,
31
+ };
32
+ }
33
+ export function scoreAllPerfBudgets(results) {
34
+ return results.map(scorePerfBudget);
35
+ }
@@ -0,0 +1,22 @@
1
+ import { assetsBudgetsConfig } from '../../../configs/assets-budgets-config.js';
2
+ import { ParsedAsset } from './PerfBudgetAssets.js';
3
+ import { PerfBudgetScoreSummary } from './PerfBudgetScore.js';
4
+ export interface PerfBudgetResult {
5
+ app: string;
6
+ jsKb: number;
7
+ cssKb: number;
8
+ htmlKb: number;
9
+ imgKb: number;
10
+ jsStatus: 'ok' | 'near' | 'exceed';
11
+ cssStatus: 'ok' | 'near' | 'exceed';
12
+ htmlStatus: 'ok' | 'near' | 'exceed';
13
+ imgStatus: 'ok' | 'near' | 'exceed';
14
+ }
15
+ export interface PerfBudgetsSummary {
16
+ results: (PerfBudgetResult & {
17
+ assets: ParsedAsset[];
18
+ })[];
19
+ scores: PerfBudgetScoreSummary[];
20
+ medians: typeof assetsBudgetsConfig.medians;
21
+ }
22
+ //# sourceMappingURL=PerfBudget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PerfBudget.d.ts","sourceRoot":"","sources":["../../../../src/adapters/perf-budgets/types/PerfBudget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAK3D,MAAM,WAAW,gBAAgB;IAE/B,GAAG,EAAE,MAAM,CAAC;IAEZ,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,MAAM,CAAC;IAEf,KAAK,EAAE,MAAM,CAAC;IAGd,QAAQ,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;IAEnC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;IAEpC,UAAU,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;IAErC,SAAS,EAAE,IAAI,GAAG,MAAM,GAAG,QAAQ,CAAC;CACrC;AAgDD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,CAAC,gBAAgB,GAAG;QAAE,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC,EAAE,CAAC;IAC1D,MAAM,EAAE,sBAAsB,EAAE,CAAC;IACjC,OAAO,EAAE,OAAO,mBAAmB,CAAC,OAAO,CAAC;CAC7C"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ export interface ParsedAsset {
2
+ filename: string;
3
+ type: 'js' | 'css' | 'html' | 'img' | 'other';
4
+ sizeKb: number;
5
+ }
6
+ export interface ParsedBundle {
7
+ jsKb: number;
8
+ cssKb: number;
9
+ htmlKb: number;
10
+ imgKb: number;
11
+ assets: ParsedAsset[];
12
+ }
13
+ //# sourceMappingURL=PerfBudgetAssets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PerfBudgetAssets.d.ts","sourceRoot":"","sources":["../../../../src/adapters/perf-budgets/types/PerfBudgetAssets.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAE1B,QAAQ,EAAE,MAAM,CAAC;IAEjB,IAAI,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;IAE9C,MAAM,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,YAAY;IAE3B,IAAI,EAAE,MAAM,CAAC;IAEb,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,MAAM,CAAC;IAEf,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,WAAW,EAAE,CAAC;CACvB"}
@@ -0,0 +1,13 @@
1
+ export type PerfBudgetScoreLevel = 0 | 1 | 2;
2
+ export interface PerfBudgetScoreSummary {
3
+ app: string;
4
+ scores: {
5
+ js: PerfBudgetScoreLevel;
6
+ css: PerfBudgetScoreLevel;
7
+ html: PerfBudgetScoreLevel;
8
+ img: PerfBudgetScoreLevel;
9
+ };
10
+ totalScore: number;
11
+ status: 'pass' | 'warn' | 'fail';
12
+ }
13
+ //# sourceMappingURL=PerfBudgetScore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PerfBudgetScore.d.ts","sourceRoot":"","sources":["../../../../src/adapters/perf-budgets/types/PerfBudgetScore.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,oBAAoB,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAK7C,MAAM,WAAW,sBAAsB;IAErC,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE;QACN,EAAE,EAAE,oBAAoB,CAAC;QACzB,GAAG,EAAE,oBAAoB,CAAC;QAC1B,IAAI,EAAE,oBAAoB,CAAC;QAC3B,GAAG,EAAE,oBAAoB,CAAC;KAC3B,CAAC;IAEF,UAAU,EAAE,MAAM,CAAC;IAEnB,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;CAClC"}
@@ -0,0 +1,28 @@
1
+ export declare const assetsBudgetsConfig: {
2
+ medians: {
3
+ jsKb: number;
4
+ cssKb: number;
5
+ imgKb: number;
6
+ htmlKb: number;
7
+ };
8
+ thresholds: {
9
+ nearFactor: number;
10
+ exceedFactor: number;
11
+ };
12
+ heavyAssetsCount: number;
13
+ links: {
14
+ httpArchive: {
15
+ label: string;
16
+ url: string;
17
+ }[];
18
+ optimization: {
19
+ label: string;
20
+ url: string;
21
+ }[];
22
+ tips: {
23
+ label: string;
24
+ desc: string;
25
+ }[];
26
+ };
27
+ };
28
+ //# sourceMappingURL=assets-budgets-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets-budgets-config.d.ts","sourceRoot":"","sources":["../../src/configs/assets-budgets-config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;CA2D/B,CAAC"}
@@ -0,0 +1,45 @@
1
+ export const assetsBudgetsConfig = {
2
+ medians: {
3
+ jsKb: 747.5,
4
+ cssKb: 86.8,
5
+ imgKb: 1066.6,
6
+ htmlKb: 35.5,
7
+ },
8
+ thresholds: {
9
+ nearFactor: 0.7,
10
+ exceedFactor: 1.0,
11
+ },
12
+ heavyAssetsCount: 5,
13
+ links: {
14
+ httpArchive: [
15
+ { label: 'JavaScript Median', url: 'https://httparchive.org/reports/page-weight#bytesJs' },
16
+ { label: 'CSS Median', url: 'https://httparchive.org/reports/page-weight#bytesCss' },
17
+ { label: 'HTML Median', url: 'https://httparchive.org/reports/page-weight#bytesHtml' },
18
+ { label: 'Image Median', url: 'https://httparchive.org/reports/page-weight#bytesImg' },
19
+ ],
20
+ optimization: [
21
+ { label: 'Web.dev: Learn Performance', url: 'https://web.dev/learn/performance' },
22
+ { label: 'Web.dev: Performance Guide', url: 'https://web.dev/performance' },
23
+ { label: 'Bundle Splitting', url: 'https://www.patterns.dev/vanilla/bundle-splitting/' },
24
+ { label: 'Dynamic Import', url: 'https://www.patterns.dev/vanilla/dynamic-import/' },
25
+ {
26
+ label: 'Import on Interaction',
27
+ url: 'https://www.patterns.dev/vanilla/import-on-interaction/',
28
+ },
29
+ {
30
+ label: 'Import on Visibility',
31
+ url: 'https://www.patterns.dev/vanilla/import-on-visibility/',
32
+ },
33
+ { label: 'Loading Sequence', url: 'https://www.patterns.dev/vanilla/loading-sequence/' },
34
+ { label: 'Virtual Lists', url: 'https://www.patterns.dev/vanilla/virtual-lists/' },
35
+ { label: 'Third-party Scripts', url: 'https://www.patterns.dev/vanilla/third-party/' },
36
+ ],
37
+ tips: [
38
+ { label: 'State Localization', desc: 'Minimize unnecessary re-renders by localizing state.' },
39
+ { label: 'Memoization', desc: 'Use useMemo/useCallback for expensive calcs and functions.' },
40
+ { label: 'Lazy Loading', desc: 'Load components/routes lazily to improve initial load.' },
41
+ { label: 'Virtualization', desc: 'Use react-window/react-virtualized for large lists.' },
42
+ { label: 'Profiling', desc: 'Use React Profiler and browser DevTools to spot bottlenecks.' },
43
+ ],
44
+ },
45
+ };
@@ -0,0 +1,8 @@
1
+ export declare const bundleAnalysisConfig: {
2
+ format: string;
3
+ open: boolean;
4
+ gzipSize: boolean;
5
+ brotliSize: boolean;
6
+ reportFile: string;
7
+ };
8
+ //# sourceMappingURL=bundle-analysis-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-analysis-config.d.ts","sourceRoot":"","sources":["../../src/configs/bundle-analysis-config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB;;;;;;CAMhC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const bundleAnalysisConfig = {
2
+ format: 'static',
3
+ open: false,
4
+ gzipSize: true,
5
+ brotliSize: true,
6
+ reportFile: 'bundle-report',
7
+ };
@@ -8,7 +8,7 @@ export declare const cssFiles = "**/*.{scss,css}";
8
8
  export declare const htmlFiles = "**/*.html";
9
9
  export declare const storyFiles = "**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)";
10
10
  export declare const testFiles: string[];
11
- export declare const commonTextFiles = "**/*.{ts,tsx,js,jsx,json,yml,yaml,md}";
11
+ export declare const commonTextFiles = "**/*.{ts,tsx,mts,js,jsx,mjs,json,yml,yaml,md}";
12
12
  export declare const jsonFiles = "**/*.json";
13
13
  export declare const yamlFiles = "**/*.{yml,yaml}";
14
14
  export declare const markdownFiles = "**/*.md";
@@ -1 +1 @@
1
- {"version":3,"file":"file-globs-config.d.ts","sourceRoot":"","sources":["../../src/configs/file-globs-config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,mDAAmD,CAAC;AAE3E,eAAO,MAAM,OAAO,sBAAsB,CAAC;AAC3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AACvC,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAC5C,eAAO,MAAM,SAAS,yBAAyB,CAAC;AAChD,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,eAAO,MAAM,QAAQ,oBAAoB,CAAC;AAC1C,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,eAAO,MAAM,UAAU,0CAA0C,CAAC;AAClE,eAAO,MAAM,SAAS,UAA4E,CAAC;AAEnG,eAAO,MAAM,eAAe,0CAA0C,CAAC;AACvE,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAC3C,eAAO,MAAM,aAAa,YAAY,CAAC"}
1
+ {"version":3,"file":"file-globs-config.d.ts","sourceRoot":"","sources":["../../src/configs/file-globs-config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,UAAU,mDAAmD,CAAC;AAE3E,eAAO,MAAM,OAAO,sBAAsB,CAAC;AAC3C,eAAO,MAAM,OAAO,kBAAkB,CAAC;AACvC,eAAO,MAAM,WAAW,mBAAmB,CAAC;AAC5C,eAAO,MAAM,SAAS,yBAAyB,CAAC;AAChD,eAAO,MAAM,YAAY,kBAAkB,CAAC;AAE5C,eAAO,MAAM,QAAQ,oBAAoB,CAAC;AAC1C,eAAO,MAAM,SAAS,cAAc,CAAC;AAErC,eAAO,MAAM,UAAU,0CAA0C,CAAC;AAClE,eAAO,MAAM,SAAS,UAA4E,CAAC;AAEnG,eAAO,MAAM,eAAe,kDAAkD,CAAC;AAC/E,eAAO,MAAM,SAAS,cAAc,CAAC;AACrC,eAAO,MAAM,SAAS,oBAAoB,CAAC;AAC3C,eAAO,MAAM,aAAa,YAAY,CAAC"}
@@ -8,7 +8,7 @@ export const cssFiles = '**/*.{scss,css}';
8
8
  export const htmlFiles = '**/*.html';
9
9
  export const storyFiles = '**/*.stories.@(ts|tsx|js|jsx|mjs|cjs)';
10
10
  export const testFiles = ['**/*.{test,spec}.{ts,tsx,js,jsx}', '**/__tests__/**/*.{ts,tsx,js,jsx}'];
11
- export const commonTextFiles = '**/*.{ts,tsx,js,jsx,json,yml,yaml,md}';
11
+ export const commonTextFiles = '**/*.{ts,tsx,mts,js,jsx,mjs,json,yml,yaml,md}';
12
12
  export const jsonFiles = '**/*.json';
13
13
  export const yamlFiles = '**/*.{yml,yaml}';
14
14
  export const markdownFiles = '**/*.md';