packlyze 1.0.4 โ 2.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 +128 -59
- package/dist/cli.js +169 -35
- package/dist/cli.js.map +1 -1
- package/dist/visualization/reports.d.ts +1 -1
- package/dist/visualization/reports.d.ts.map +1 -1
- package/dist/visualization/reports.js +513 -76
- package/dist/visualization/reports.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,83 +4,79 @@
|
|
|
4
4
|
[](https://github.com/iamabhshk/Packlyze/actions)
|
|
5
5
|
[](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Packlyze
|
|
8
8
|
|
|
9
|
-
Advanced bundle analyzer with insights, recommendations, and
|
|
9
|
+
Advanced bundle analyzer with insights, recommendations, historical tracking, and a sleek HTML report.
|
|
10
10
|
|
|
11
11
|
## ๐ Features
|
|
12
12
|
|
|
13
|
-
- **Package Analysis**: Parse and analyze webpack, rollup, and esbuild stats files
|
|
14
|
-
- **Smart Recommendations**:
|
|
15
|
-
- **Tree-Shaking Detection**: Identify modules
|
|
16
|
-
- **Duplicate Detection**: Find and quantify duplicate modules
|
|
17
|
-
- **Beautiful
|
|
18
|
-
- **
|
|
19
|
-
- **
|
|
13
|
+
- **Package Analysis**: Parse and analyze webpack, rollup, and esbuild stats files.
|
|
14
|
+
- **Smart Recommendations**: Suggestions to optimize bundle size and structure.
|
|
15
|
+
- **Tree-Shaking Detection**: Identify modules and patterns that block tree-shaking.
|
|
16
|
+
- **Duplicate Detection**: Find and quantify duplicate modules with potential savings.
|
|
17
|
+
- **Beautiful HTML Report**: Sleek, dark-themed, responsive report with high-level metrics and deep insights.
|
|
18
|
+
- **Baseline Comparison**: Compare current vs previous stats to see regressions and improvements.
|
|
19
|
+
- **CLI Tool**: Easy-to-use command-line interface with filters and CI-friendly thresholds.
|
|
20
|
+
- **TypeScript Ready**: Full TypeScript support with type definitions.
|
|
21
|
+
|
|
22
|
+
## ๐ Quick Start
|
|
23
|
+
|
|
24
|
+
Packlyze can be used in two main ways: as a CLI tool and as a Node.js/TypeScript library.
|
|
20
25
|
|
|
21
|
-
|
|
26
|
+
**1. Install Packlyze (globally or with npx):**
|
|
22
27
|
|
|
23
28
|
You can install Packlyze globally or use it via npx:
|
|
24
29
|
|
|
25
30
|
```bash
|
|
26
|
-
npm install -g packlyze
|
|
31
|
+
npm install -g packlyze
|
|
27
32
|
# or
|
|
28
|
-
npx packlyze
|
|
33
|
+
npx packlyze --help
|
|
29
34
|
```
|
|
30
35
|
|
|
36
|
+
**2. Generate a stats file from your bundler (e.g., webpack):**
|
|
31
37
|
|
|
38
|
+
> โ ๏ธ **Important:**
|
|
39
|
+
> You must generate a valid JSON stats file before running Packlyze.
|
|
40
|
+
> For webpack, use the following command in your project folder:
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
```bash
|
|
43
|
+
npx webpack --profile --json stats.json
|
|
44
|
+
```
|
|
45
|
+
- This will create a readable `stats.json` file in your project directory.
|
|
34
46
|
|
|
35
|
-
|
|
47
|
+
**3. Run Packlyze analysis (CLI):**
|
|
48
|
+
```bash
|
|
49
|
+
packlyze analyze stats.json
|
|
50
|
+
# or (if using npx)
|
|
51
|
+
npx packlyze analyze stats.json
|
|
52
|
+
```
|
|
36
53
|
|
|
37
|
-
|
|
54
|
+
**4. (Optional) Output an HTML report (sleek UI):**
|
|
55
|
+
```bash
|
|
56
|
+
packlyze analyze stats.json -o ./reports/bundle-report.html
|
|
57
|
+
```
|
|
38
58
|
|
|
39
|
-
|
|
40
|
-
1. **Install Packlyze** (globally or use npx):
|
|
41
|
-
```bash
|
|
42
|
-
npm install -g packlyze
|
|
43
|
-
# or
|
|
44
|
-
npx packlyze --help
|
|
45
|
-
```
|
|
46
|
-
2. **Generate a stats file** from your bundler (e.g., webpack, rollup, esbuild):
|
|
47
|
-
```bash
|
|
48
|
-
# For webpack:
|
|
49
|
-
webpack --profile --json > stats.json
|
|
50
|
-
```
|
|
51
|
-
3. **Run Packlyze analysis**:
|
|
52
|
-
```bash
|
|
53
|
-
packlyze analyze stats.json
|
|
54
|
-
# or (if using npx)
|
|
55
|
-
npx packlyze analyze stats.json
|
|
56
|
-
```
|
|
57
|
-
4. **Output an HTML report to a custom location**:
|
|
58
|
-
```bash
|
|
59
|
-
packlyze analyze stats.json -o ./reports/bundle-report.html
|
|
60
|
-
```
|
|
61
|
-
5. **Get results in JSON format (for CI/CD or automation):**
|
|
62
|
-
```bash
|
|
63
|
-
packlyze analyze stats.json --json
|
|
64
|
-
```
|
|
59
|
+
---
|
|
65
60
|
|
|
66
|
-
|
|
61
|
+
## ๐ Common Issues & Solutions
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
npm install packlyze
|
|
72
|
-
```
|
|
73
|
-
2. **Import and use in your code:**
|
|
74
|
-
```typescript
|
|
75
|
-
import { Packlyze } from 'packlyze';
|
|
63
|
+
- **"Stats file not found":**
|
|
64
|
+
Make sure `stats.json` exists in your folder.
|
|
65
|
+
Generate it using your bundler (see above).
|
|
76
66
|
|
|
77
|
-
|
|
78
|
-
|
|
67
|
+
- **"Invalid JSON in stats file":**
|
|
68
|
+
Your stats file may be corrupted or not plain JSON.
|
|
69
|
+
- Delete the file and re-run the correct webpack command.
|
|
70
|
+
- Open `stats.json` in a text editor; it should start with `{` and be readable.
|
|
79
71
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
72
|
+
- **"webpack not recognized":**
|
|
73
|
+
Install webpack locally in your project:
|
|
74
|
+
```bash
|
|
75
|
+
npm install --save-dev webpack webpack-cli
|
|
83
76
|
```
|
|
77
|
+
Then use `npx webpack ...` to generate stats.
|
|
78
|
+
|
|
79
|
+
---
|
|
84
80
|
|
|
85
81
|
## ๐ File Structure
|
|
86
82
|
|
|
@@ -127,10 +123,83 @@ The analyzer provides:
|
|
|
127
123
|
- Info: Monitor for growth
|
|
128
124
|
|
|
129
125
|
### Insights
|
|
130
|
-
- Tree-shaking issues
|
|
131
|
-
- Duplicate modules
|
|
132
|
-
- Large modules (>5% of bundle)
|
|
133
|
-
- Module count analysis
|
|
126
|
+
- Tree-shaking issues.
|
|
127
|
+
- Duplicate modules.
|
|
128
|
+
- Large modules (configurable threshold, default >5% of bundle).
|
|
129
|
+
- Module count and chunk analysis.
|
|
130
|
+
|
|
131
|
+
### HTML Report (UI Overview)
|
|
132
|
+
|
|
133
|
+
The generated HTML report is a single, static file with a modern dark UI:
|
|
134
|
+
|
|
135
|
+
- **Header**: Run timestamp, optional baseline timestamp, and quick badges that summarize what youโre seeing.
|
|
136
|
+
- **Metrics Grid**: Cards for total size, gzip size, modules, chunks, average module size, and largest module.
|
|
137
|
+
- When a `--baseline` is provided, each metric shows a colored delta (green for improvement, red for regression).
|
|
138
|
+
- **Recommendations**: Color-coded cards grouped by severity (critical, warning, info) with clear โActionโ text.
|
|
139
|
+
- **Top Modules Table**: Top 10 modules by size, with size and share of the bundle.
|
|
140
|
+
- **Duplicate Modules Section**: Table with count, total size, potential savings, and example module names.
|
|
141
|
+
- **Tree-Shaking Section**: List of CommonJS / `require`-style modules that may block tree-shaking.
|
|
142
|
+
|
|
143
|
+
You can open the HTML report directly in any modern browser; no network access or JS bundling is required.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## โ๏ธ CLI Usage & Options
|
|
148
|
+
|
|
149
|
+
The main CLI entry point is the `analyze` command:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
packlyze analyze <statsFile> [options]
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Core options
|
|
156
|
+
|
|
157
|
+
- `-o, --output <path>`: Path to the HTML report (default: `./bundle-report.html`).
|
|
158
|
+
- `-j, --json`: Output raw JSON analysis to stdout instead of human-readable text/HTML.
|
|
159
|
+
- `-v, --verbose`: Reserved for future verbose logging.
|
|
160
|
+
|
|
161
|
+
### Focus & filter options
|
|
162
|
+
|
|
163
|
+
- `--only-duplicates`: Only print duplicate modules table in the CLI output.
|
|
164
|
+
- `--only-large-modules`: Only print large modules table in the CLI output.
|
|
165
|
+
- `--large-module-threshold <percent>`: Percentage of bundle size at which a module is considered โlargeโ (default: `5`).
|
|
166
|
+
- `--no-html`: Skip HTML report generation (useful in fast CLI-only workflows).
|
|
167
|
+
|
|
168
|
+
### Baseline comparison
|
|
169
|
+
|
|
170
|
+
- `--baseline <statsFile>`: Provide a previous stats file to compare against.
|
|
171
|
+
|
|
172
|
+
When a baseline is provided:
|
|
173
|
+
|
|
174
|
+
- CLI summary prints deltas for total size, gzip size, module count, and chunk count.
|
|
175
|
+
- HTML metrics cards show deltas under each metric (green good, red regression).
|
|
176
|
+
|
|
177
|
+
Example:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
packlyze analyze dist/stats.new.json --baseline dist/stats.old.json
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### CI-friendly thresholds
|
|
184
|
+
|
|
185
|
+
Packlyze can enforce bundle-size budgets and fail your CI when limits are exceeded:
|
|
186
|
+
|
|
187
|
+
- `--max-gzip-size <mb>`: Fail if gzip size exceeds this many megabytes.
|
|
188
|
+
- `--max-initial-size <mb>`: Fail if initial bundle size (initial chunks) exceeds this many megabytes.
|
|
189
|
+
|
|
190
|
+
When thresholds are violated:
|
|
191
|
+
|
|
192
|
+
- The CLI prints a clear error message.
|
|
193
|
+
- `packlyze` exits with a non-zero exit code so your CI job can fail on regressions.
|
|
194
|
+
|
|
195
|
+
Example:
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
packlyze analyze dist/stats.json \
|
|
199
|
+
--max-gzip-size 1.2 \
|
|
200
|
+
--max-initial-size 0.9 \
|
|
201
|
+
--no-html
|
|
202
|
+
```
|
|
134
203
|
|
|
135
204
|
## ๐ฏ Use Cases
|
|
136
205
|
|
package/dist/cli.js
CHANGED
|
@@ -7,9 +7,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
8
|
const chalk_1 = __importDefault(require("chalk"));
|
|
9
9
|
const ora_1 = __importDefault(require("ora"));
|
|
10
|
+
const fs_1 = __importDefault(require("fs"));
|
|
11
|
+
const table_1 = require("table");
|
|
10
12
|
const packlyze_1 = require("./analyzer/packlyze");
|
|
11
13
|
const reports_1 = require("./visualization/reports");
|
|
12
|
-
const fs_1 = __importDefault(require("fs"));
|
|
13
14
|
const program = new commander_1.Command();
|
|
14
15
|
program
|
|
15
16
|
.name('packlyze')
|
|
@@ -22,6 +23,13 @@ program
|
|
|
22
23
|
.option('-o, --output <path>', 'Output HTML report path', './bundle-report.html')
|
|
23
24
|
.option('-j, --json', 'Output as JSON')
|
|
24
25
|
.option('-v, --verbose', 'Verbose output')
|
|
26
|
+
.option('--no-html', 'Do not generate HTML report')
|
|
27
|
+
.option('--only-duplicates', 'Show only duplicate modules information')
|
|
28
|
+
.option('--only-large-modules', 'Show only large modules information')
|
|
29
|
+
.option('--large-module-threshold <percent>', 'Threshold in % of bundle size for a module to be considered large', parseFloat, 5)
|
|
30
|
+
.option('--max-gzip-size <mb>', 'Fail if gzip bundle size exceeds this value (in MB)', parseFloat)
|
|
31
|
+
.option('--max-initial-size <mb>', 'Fail if initial bundle size exceeds this value (in MB)', parseFloat)
|
|
32
|
+
.option('--baseline <statsFile>', 'Baseline stats file to compare against')
|
|
25
33
|
.action(async (statsFile, options) => {
|
|
26
34
|
const spinner = (0, ora_1.default)('Analyzing package...').start();
|
|
27
35
|
try {
|
|
@@ -31,48 +39,41 @@ program
|
|
|
31
39
|
}
|
|
32
40
|
const analyzer = new packlyze_1.Packlyze(statsFile);
|
|
33
41
|
const result = await analyzer.analyze();
|
|
42
|
+
let baselineResult;
|
|
43
|
+
if (options.baseline) {
|
|
44
|
+
const baselinePath = options.baseline;
|
|
45
|
+
if (!fs_1.default.existsSync(baselinePath)) {
|
|
46
|
+
throw new Error(`Baseline file not found: ${baselinePath}`);
|
|
47
|
+
}
|
|
48
|
+
const baselineAnalyzer = new packlyze_1.Packlyze(baselinePath);
|
|
49
|
+
baselineResult = await baselineAnalyzer.analyze();
|
|
50
|
+
}
|
|
34
51
|
spinner.succeed('Analysis complete!');
|
|
35
52
|
if (options.json) {
|
|
36
53
|
console.log(JSON.stringify(result, null, 2));
|
|
37
54
|
}
|
|
38
55
|
else {
|
|
39
56
|
// Display formatted results
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
console.log(` Chunks: ${chalk_1.default.blue(result.metrics.chunkCount)}`);
|
|
46
|
-
console.log(` Avg Module: ${chalk_1.default.green((result.metrics.averageModuleSize / 1024).toFixed(2))}KB\n`);
|
|
47
|
-
// Top modules
|
|
48
|
-
console.log(chalk_1.default.bold('Top 5 Modules:'));
|
|
49
|
-
result.bundleStats.modules.slice(0, 5).forEach((m, i) => {
|
|
50
|
-
const bar = 'โ'.repeat(Math.round(m.percentage / 2));
|
|
51
|
-
console.log(` ${i + 1}. ${m.name.slice(-30).padEnd(30)} ${(m.size / 1024).toFixed(2)}KB ${bar}`);
|
|
52
|
-
});
|
|
53
|
-
// Recommendations
|
|
54
|
-
if (result.recommendations.length > 0) {
|
|
55
|
-
console.log(chalk_1.default.bold.cyan('\n๐ก Recommendations\n'));
|
|
56
|
-
result.recommendations.forEach(rec => {
|
|
57
|
-
const icon = rec.severity === 'critical' ? '๐ด' : rec.severity === 'warning' ? '๐ก' : '๐ข';
|
|
58
|
-
console.log(`${icon} ${rec.message}`);
|
|
59
|
-
console.log(` โ ${rec.action}\n`);
|
|
60
|
-
});
|
|
57
|
+
printSummary(result, options, baselineResult);
|
|
58
|
+
if (!options.onlyDuplicates && !options.onlyLargeModules) {
|
|
59
|
+
printTopModules(result);
|
|
60
|
+
printRecommendations(result);
|
|
61
|
+
printTreeshakingIssues(result);
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
63
|
+
if (options.onlyDuplicates || (!options.onlyLargeModules && !options.onlyDuplicates)) {
|
|
64
|
+
printDuplicates(result);
|
|
65
|
+
}
|
|
66
|
+
if (options.onlyLargeModules || (!options.onlyLargeModules && !options.onlyDuplicates)) {
|
|
67
|
+
printLargeModules(result, options.largeModuleThreshold);
|
|
68
|
+
}
|
|
69
|
+
if (options.html !== false) {
|
|
70
|
+
(0, reports_1.generateHTMLReport)(result, options.output, baselineResult);
|
|
71
|
+
console.log(chalk_1.default.green(`โ
Report saved to ${options.output}`));
|
|
72
|
+
}
|
|
73
|
+
const exitCode = evaluateThresholds(result, options);
|
|
74
|
+
if (exitCode !== 0) {
|
|
75
|
+
process.exit(exitCode);
|
|
72
76
|
}
|
|
73
|
-
// Generate HTML report
|
|
74
|
-
(0, reports_1.generateHTMLReport)(result, options.output);
|
|
75
|
-
console.log(chalk_1.default.green(`โ
Report saved to ${options.output}`));
|
|
76
77
|
}
|
|
77
78
|
}
|
|
78
79
|
catch (error) {
|
|
@@ -82,4 +83,137 @@ program
|
|
|
82
83
|
}
|
|
83
84
|
});
|
|
84
85
|
program.parse();
|
|
86
|
+
function printSummary(result, options, baseline) {
|
|
87
|
+
console.log(chalk_1.default.bold.cyan('\n๐ Package Analysis Results\n'));
|
|
88
|
+
console.log(chalk_1.default.bold('Metrics:'));
|
|
89
|
+
const totalMb = result.metrics.totalSize / 1024 / 1024;
|
|
90
|
+
const gzipMb = result.metrics.totalGzipSize / 1024 / 1024;
|
|
91
|
+
console.log(` Total Size: ${chalk_1.default.red(totalMb.toFixed(2))}MB${formatDeltaMb(baseline?.metrics.totalSize, result.metrics.totalSize)}`);
|
|
92
|
+
console.log(` Gzip Size: ${chalk_1.default.yellow(gzipMb.toFixed(2))}MB${formatDeltaMb(baseline?.metrics.totalGzipSize, result.metrics.totalGzipSize)}`);
|
|
93
|
+
console.log(` Modules: ${chalk_1.default.blue(result.metrics.moduleCount)}${formatDeltaCount(baseline?.metrics.moduleCount, result.metrics.moduleCount)}`);
|
|
94
|
+
console.log(` Chunks: ${chalk_1.default.blue(result.metrics.chunkCount)}${formatDeltaCount(baseline?.metrics.chunkCount, result.metrics.chunkCount)}`);
|
|
95
|
+
console.log(` Avg Module: ${chalk_1.default.green((result.metrics.averageModuleSize / 1024).toFixed(2))}KB\n`);
|
|
96
|
+
if (options.maxGzipSize) {
|
|
97
|
+
console.log(` Max Gzip Threshold: ${chalk_1.default.yellow(options.maxGzipSize)}MB (${result.metrics.totalGzipSize / 1024 / 1024 > options.maxGzipSize ? chalk_1.default.red('violated') : chalk_1.default.green('ok')})`);
|
|
98
|
+
}
|
|
99
|
+
if (options.maxInitialSize) {
|
|
100
|
+
const initialMb = (result.bundleStats.isInitialBySize / 1024 / 1024).toFixed(2);
|
|
101
|
+
console.log(` Max Initial Threshold: ${chalk_1.default.yellow(options.maxInitialSize)}MB (${Number(initialMb) > options.maxInitialSize ? chalk_1.default.red('violated') : chalk_1.default.green('ok')})`);
|
|
102
|
+
}
|
|
103
|
+
console.log();
|
|
104
|
+
}
|
|
105
|
+
function printTopModules(result) {
|
|
106
|
+
console.log(chalk_1.default.bold('Top 5 Modules:'));
|
|
107
|
+
result.bundleStats.modules.slice(0, 5).forEach((m, i) => {
|
|
108
|
+
const bar = 'โ'.repeat(Math.round(m.percentage / 2));
|
|
109
|
+
console.log(` ${i + 1}. ${m.name.slice(-30).padEnd(30)} ${(m.size / 1024).toFixed(2)}KB ${bar}`);
|
|
110
|
+
});
|
|
111
|
+
console.log();
|
|
112
|
+
}
|
|
113
|
+
function printRecommendations(result) {
|
|
114
|
+
if (result.recommendations.length === 0)
|
|
115
|
+
return;
|
|
116
|
+
console.log(chalk_1.default.bold.cyan('\n๐ก Recommendations\n'));
|
|
117
|
+
result.recommendations.forEach((rec) => {
|
|
118
|
+
const icon = rec.severity === 'critical' ? '๐ด' : rec.severity === 'warning' ? '๐ก' : '๐ข';
|
|
119
|
+
console.log(`${icon} ${rec.message}`);
|
|
120
|
+
console.log(` โ ${rec.action}\n`);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
function printTreeshakingIssues(result) {
|
|
124
|
+
if (result.treeshakingIssues.length === 0)
|
|
125
|
+
return;
|
|
126
|
+
console.log(chalk_1.default.bold.yellow('\n๐ณ Tree-Shaking Issues\n'));
|
|
127
|
+
result.treeshakingIssues.slice(0, 3).forEach((issue) => {
|
|
128
|
+
console.log(` โข ${issue}`);
|
|
129
|
+
});
|
|
130
|
+
if (result.treeshakingIssues.length > 3) {
|
|
131
|
+
console.log(` ... and ${result.treeshakingIssues.length - 3} more`);
|
|
132
|
+
}
|
|
133
|
+
console.log();
|
|
134
|
+
}
|
|
135
|
+
function printDuplicates(result) {
|
|
136
|
+
if (result.duplicates.length === 0) {
|
|
137
|
+
console.log(chalk_1.default.bold.green('\nโ
No duplicate modules detected\n'));
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
console.log(chalk_1.default.bold.magenta('\n๐ Duplicate Modules\n'));
|
|
141
|
+
const data = [];
|
|
142
|
+
data.push(['#', 'Count', 'Total Size (KB)', 'Potential Savings (KB)', 'Example Names']);
|
|
143
|
+
result.duplicates.forEach((dup, index) => {
|
|
144
|
+
const totalKb = (dup.totalSize / 1024).toFixed(2);
|
|
145
|
+
const savingsKb = (dup.savings / 1024).toFixed(2);
|
|
146
|
+
const sampleNames = dup.names.slice(0, 3).join('\n');
|
|
147
|
+
data.push([String(index + 1), String(dup.names.length), totalKb, savingsKb, sampleNames]);
|
|
148
|
+
});
|
|
149
|
+
console.log((0, table_1.table)(data, {
|
|
150
|
+
columns: {
|
|
151
|
+
0: { alignment: 'right' },
|
|
152
|
+
1: { alignment: 'right' },
|
|
153
|
+
2: { alignment: 'right' },
|
|
154
|
+
3: { alignment: 'right' },
|
|
155
|
+
4: { alignment: 'left' },
|
|
156
|
+
},
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
159
|
+
function printLargeModules(result, thresholdPercent) {
|
|
160
|
+
const threshold = Number.isFinite(thresholdPercent) ? thresholdPercent : 5;
|
|
161
|
+
const largeModules = result.bundleStats.modules.filter((m) => m.percentage >= threshold);
|
|
162
|
+
if (largeModules.length === 0) {
|
|
163
|
+
console.log(chalk_1.default.bold.green(`\nโ
No modules above ${threshold}% of bundle size\n`));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
console.log(chalk_1.default.bold.red(`\n๐ฆ Modules >= ${threshold}% of bundle size\n`));
|
|
167
|
+
const data = [];
|
|
168
|
+
data.push(['#', 'Module', 'Size (KB)', '% of Bundle']);
|
|
169
|
+
largeModules.forEach((m, index) => {
|
|
170
|
+
data.push([String(index + 1), m.name.slice(-60), (m.size / 1024).toFixed(2), m.percentage.toFixed(2)]);
|
|
171
|
+
});
|
|
172
|
+
console.log((0, table_1.table)(data, {
|
|
173
|
+
columns: {
|
|
174
|
+
0: { alignment: 'right' },
|
|
175
|
+
1: { alignment: 'left' },
|
|
176
|
+
2: { alignment: 'right' },
|
|
177
|
+
3: { alignment: 'right' },
|
|
178
|
+
},
|
|
179
|
+
}));
|
|
180
|
+
}
|
|
181
|
+
function evaluateThresholds(result, options) {
|
|
182
|
+
let exitCode = 0;
|
|
183
|
+
if (typeof options.maxGzipSize === 'number') {
|
|
184
|
+
const gzipMb = result.metrics.totalGzipSize / 1024 / 1024;
|
|
185
|
+
if (gzipMb > options.maxGzipSize) {
|
|
186
|
+
console.error(chalk_1.default.red(`\nโ Bundle gzip size (${gzipMb.toFixed(2)}MB) exceeds threshold (${options.maxGzipSize}MB).`));
|
|
187
|
+
exitCode = 2;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (typeof options.maxInitialSize === 'number') {
|
|
191
|
+
const initialMb = result.bundleStats.isInitialBySize / 1024 / 1024;
|
|
192
|
+
if (initialMb > options.maxInitialSize) {
|
|
193
|
+
console.error(chalk_1.default.red(`\nโ Initial bundle size (${initialMb.toFixed(2)}MB) exceeds threshold (${options.maxInitialSize}MB).`));
|
|
194
|
+
exitCode = Math.max(exitCode, 3);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return exitCode;
|
|
198
|
+
}
|
|
199
|
+
function formatDeltaMb(baselineBytes, currentBytes) {
|
|
200
|
+
if (baselineBytes === undefined || currentBytes === undefined)
|
|
201
|
+
return '';
|
|
202
|
+
const diffMb = (currentBytes - baselineBytes) / 1024 / 1024;
|
|
203
|
+
if (Math.abs(diffMb) < 0.01)
|
|
204
|
+
return '';
|
|
205
|
+
const sign = diffMb > 0 ? '+' : '-';
|
|
206
|
+
const color = diffMb > 0 ? chalk_1.default.red : chalk_1.default.green;
|
|
207
|
+
return ` (${color(`${sign}${Math.abs(diffMb).toFixed(2)}MB vs baseline`)})`;
|
|
208
|
+
}
|
|
209
|
+
function formatDeltaCount(baseline, current) {
|
|
210
|
+
if (baseline === undefined || current === undefined)
|
|
211
|
+
return '';
|
|
212
|
+
const diff = current - baseline;
|
|
213
|
+
if (diff === 0)
|
|
214
|
+
return '';
|
|
215
|
+
const sign = diff > 0 ? '+' : '-';
|
|
216
|
+
const color = diff > 0 ? chalk_1.default.red : chalk_1.default.green;
|
|
217
|
+
return ` (${color(`${sign}${Math.abs(diff)} vs baseline`)})`;
|
|
218
|
+
}
|
|
85
219
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { AnalysisResult } from '../types.js';
|
|
2
|
-
export declare function generateHTMLReport(result: AnalysisResult, outputPath: string): void;
|
|
2
|
+
export declare function generateHTMLReport(result: AnalysisResult, outputPath: string, baselineResult?: AnalysisResult): void;
|
|
3
3
|
//# sourceMappingURL=reports.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"reports.d.ts","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,cAAc,GAAG,IAAI,CAGpH"}
|
|
@@ -5,11 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.generateHTMLReport = generateHTMLReport;
|
|
7
7
|
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
function generateHTMLReport(result, outputPath) {
|
|
9
|
-
const html = generateHTML(result);
|
|
8
|
+
function generateHTMLReport(result, outputPath, baselineResult) {
|
|
9
|
+
const html = generateHTML(result, baselineResult);
|
|
10
10
|
fs_1.default.writeFileSync(outputPath, html);
|
|
11
11
|
}
|
|
12
|
-
function generateHTML(result) {
|
|
12
|
+
function generateHTML(result, baseline) {
|
|
13
13
|
const recommendations = result.recommendations
|
|
14
14
|
.map(rec => `
|
|
15
15
|
<div class="recommendation ${rec.severity}">
|
|
@@ -31,6 +31,20 @@ function generateHTML(result) {
|
|
|
31
31
|
</tr>
|
|
32
32
|
`)
|
|
33
33
|
.join('');
|
|
34
|
+
const duplicates = result.duplicates
|
|
35
|
+
.map(dup => `
|
|
36
|
+
<tr>
|
|
37
|
+
<td>${dup.names.length}</td>
|
|
38
|
+
<td>${(dup.totalSize / 1024).toFixed(2)} KB</td>
|
|
39
|
+
<td>${(dup.savings / 1024).toFixed(2)} KB</td>
|
|
40
|
+
<td>${dup.names.slice(0, 3).map(name => escapeHtml(name)).join('<br/>')}${dup.names.length > 3 ? 'โฆ' : ''}</td>
|
|
41
|
+
</tr>
|
|
42
|
+
`)
|
|
43
|
+
.join('');
|
|
44
|
+
const treeshakingIssues = result.treeshakingIssues
|
|
45
|
+
.slice(0, 10)
|
|
46
|
+
.map(issue => `<li>${escapeHtml(issue)}</li>`)
|
|
47
|
+
.join('');
|
|
34
48
|
return `
|
|
35
49
|
<!DOCTYPE html>
|
|
36
50
|
<html lang="en">
|
|
@@ -39,97 +53,448 @@ function generateHTML(result) {
|
|
|
39
53
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
40
54
|
<title>Package Analysis Report</title>
|
|
41
55
|
<style>
|
|
42
|
-
* {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
* {
|
|
57
|
+
margin: 0;
|
|
58
|
+
padding: 0;
|
|
59
|
+
box-sizing: border-box;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
:root {
|
|
63
|
+
--bg-body: #050816;
|
|
64
|
+
--bg-panel: #0f172a;
|
|
65
|
+
--bg-panel-soft: #020617;
|
|
66
|
+
--border-subtle: rgba(148, 163, 184, 0.3);
|
|
67
|
+
--accent: #6366f1;
|
|
68
|
+
--accent-soft: rgba(99, 102, 241, 0.18);
|
|
69
|
+
--accent-strong: #4f46e5;
|
|
70
|
+
--text-main: #e5e7eb;
|
|
71
|
+
--text-soft: #9ca3af;
|
|
72
|
+
--text-subtle: #6b7280;
|
|
73
|
+
--critical: #f97373;
|
|
74
|
+
--warning: #fb923c;
|
|
75
|
+
--info: #38bdf8;
|
|
76
|
+
--good: #22c55e;
|
|
77
|
+
--shadow-soft: 0 18px 40px rgba(15, 23, 42, 0.75);
|
|
78
|
+
--radius-lg: 18px;
|
|
79
|
+
--radius-md: 12px;
|
|
80
|
+
--radius-sm: 9px;
|
|
81
|
+
--blur-backdrop: 20px;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
body {
|
|
85
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'SF Pro Text', 'Segoe UI', sans-serif;
|
|
86
|
+
background: radial-gradient(circle at top, #1e293b 0, #020617 45%, #000 100%);
|
|
87
|
+
color: var(--text-main);
|
|
47
88
|
min-height: 100vh;
|
|
48
|
-
padding: 20px;
|
|
89
|
+
padding: 32px 20px 40px;
|
|
90
|
+
display: flex;
|
|
91
|
+
justify-content: center;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.container {
|
|
95
|
+
width: 100%;
|
|
96
|
+
max-width: 1120px;
|
|
49
97
|
}
|
|
50
|
-
|
|
98
|
+
|
|
51
99
|
header {
|
|
52
|
-
background:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
margin-bottom:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
100
|
+
background: linear-gradient(135deg, rgba(15, 23, 42, 0.96), rgba(15, 23, 42, 0.92));
|
|
101
|
+
border-radius: 24px;
|
|
102
|
+
padding: 24px 28px 20px;
|
|
103
|
+
margin-bottom: 24px;
|
|
104
|
+
border: 1px solid rgba(148, 163, 184, 0.35);
|
|
105
|
+
box-shadow: var(--shadow-soft);
|
|
106
|
+
backdrop-filter: blur(var(--blur-backdrop));
|
|
107
|
+
position: relative;
|
|
108
|
+
overflow: hidden;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
header::before {
|
|
112
|
+
content: '';
|
|
113
|
+
position: absolute;
|
|
114
|
+
inset: -40%;
|
|
115
|
+
background:
|
|
116
|
+
radial-gradient(circle at 0% 0%, rgba(56, 189, 248, 0.09) 0, transparent 55%),
|
|
117
|
+
radial-gradient(circle at 100% 0%, rgba(129, 140, 248, 0.18) 0, transparent 60%);
|
|
118
|
+
opacity: 0.7;
|
|
119
|
+
pointer-events: none;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.header-inner {
|
|
123
|
+
position: relative;
|
|
124
|
+
display: flex;
|
|
125
|
+
justify-content: space-between;
|
|
126
|
+
align-items: flex-start;
|
|
127
|
+
gap: 16px;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
h1 {
|
|
131
|
+
color: #f9fafb;
|
|
132
|
+
font-size: 26px;
|
|
133
|
+
letter-spacing: 0.02em;
|
|
134
|
+
margin-bottom: 6px;
|
|
135
|
+
display: flex;
|
|
136
|
+
align-items: center;
|
|
137
|
+
gap: 10px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
h1 span.icon {
|
|
141
|
+
font-size: 26px;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.header-subtitle {
|
|
145
|
+
color: var(--text-soft);
|
|
146
|
+
font-size: 13px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.timestamp-group {
|
|
150
|
+
text-align: right;
|
|
151
|
+
font-size: 11px;
|
|
152
|
+
color: var(--text-subtle);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.timestamp-label {
|
|
156
|
+
text-transform: uppercase;
|
|
157
|
+
letter-spacing: 0.1em;
|
|
158
|
+
font-size: 10px;
|
|
159
|
+
color: var(--text-subtle);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
.timestamp-value {
|
|
163
|
+
margin-top: 3px;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
.badge-row {
|
|
167
|
+
display: flex;
|
|
168
|
+
flex-wrap: wrap;
|
|
169
|
+
gap: 8px;
|
|
170
|
+
margin-top: 14px;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.badge {
|
|
174
|
+
border-radius: 999px;
|
|
175
|
+
padding: 4px 9px;
|
|
176
|
+
font-size: 11px;
|
|
177
|
+
border: 1px solid rgba(148, 163, 184, 0.35);
|
|
178
|
+
color: var(--text-soft);
|
|
179
|
+
display: inline-flex;
|
|
180
|
+
align-items: center;
|
|
181
|
+
gap: 6px;
|
|
182
|
+
background: rgba(15, 23, 42, 0.8);
|
|
183
|
+
backdrop-filter: blur(10px);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
.badge-accent {
|
|
187
|
+
border-color: rgba(99, 102, 241, 0.5);
|
|
188
|
+
color: #e0e7ff;
|
|
189
|
+
background: rgba(79, 70, 229, 0.22);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.badge-dot {
|
|
193
|
+
width: 7px;
|
|
194
|
+
height: 7px;
|
|
195
|
+
border-radius: 999px;
|
|
196
|
+
background: var(--good);
|
|
197
|
+
box-shadow: 0 0 0 4px rgba(34, 197, 94, 0.17);
|
|
198
|
+
}
|
|
199
|
+
|
|
61
200
|
.metrics-grid {
|
|
62
201
|
display: grid;
|
|
63
|
-
grid-template-columns: repeat(auto-fit, minmax(
|
|
64
|
-
gap:
|
|
65
|
-
margin-bottom:
|
|
202
|
+
grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
|
|
203
|
+
gap: 14px;
|
|
204
|
+
margin-bottom: 22px;
|
|
66
205
|
}
|
|
206
|
+
|
|
67
207
|
.metric-card {
|
|
68
|
-
background:
|
|
69
|
-
padding:
|
|
70
|
-
border-radius:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
208
|
+
background: radial-gradient(circle at 0 0, rgba(148, 163, 184, 0.08) 0, rgba(15, 23, 42, 0.98) 55%);
|
|
209
|
+
padding: 16px 16px 14px;
|
|
210
|
+
border-radius: var(--radius-md);
|
|
211
|
+
border: 1px solid rgba(30, 64, 175, 0.55);
|
|
212
|
+
box-shadow: 0 10px 30px rgba(15, 23, 42, 0.8);
|
|
213
|
+
position: relative;
|
|
214
|
+
overflow: hidden;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
.metric-card::after {
|
|
218
|
+
content: '';
|
|
219
|
+
position: absolute;
|
|
220
|
+
inset: 0;
|
|
221
|
+
background: linear-gradient(135deg, rgba(148, 163, 184, 0.05), transparent 40%);
|
|
222
|
+
opacity: 0.9;
|
|
223
|
+
pointer-events: none;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
.metric-label {
|
|
227
|
+
color: var(--text-subtle);
|
|
228
|
+
font-size: 11px;
|
|
229
|
+
text-transform: uppercase;
|
|
230
|
+
letter-spacing: 0.12em;
|
|
231
|
+
margin-bottom: 8px;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.metric-value {
|
|
235
|
+
font-size: 22px;
|
|
236
|
+
font-weight: 600;
|
|
237
|
+
color: #e5e7eb;
|
|
238
|
+
position: relative;
|
|
239
|
+
z-index: 1;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.metric-delta {
|
|
243
|
+
font-size: 11px;
|
|
244
|
+
margin-top: 4px;
|
|
245
|
+
position: relative;
|
|
246
|
+
z-index: 1;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
.delta-positive {
|
|
250
|
+
color: #4ade80;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.delta-negative {
|
|
254
|
+
color: #fb7185;
|
|
255
|
+
}
|
|
256
|
+
|
|
76
257
|
.section {
|
|
77
|
-
background:
|
|
78
|
-
padding:
|
|
79
|
-
border-radius:
|
|
80
|
-
margin-bottom:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
258
|
+
background: radial-gradient(circle at 0 0, rgba(148, 163, 184, 0.07) 0, rgba(15, 23, 42, 0.98) 55%);
|
|
259
|
+
padding: 20px 20px 18px;
|
|
260
|
+
border-radius: var(--radius-lg);
|
|
261
|
+
margin-bottom: 18px;
|
|
262
|
+
border: 1px solid var(--border-subtle);
|
|
263
|
+
box-shadow: var(--shadow-soft);
|
|
264
|
+
position: relative;
|
|
265
|
+
overflow: hidden;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
.section::before {
|
|
269
|
+
content: '';
|
|
270
|
+
position: absolute;
|
|
271
|
+
inset: -30%;
|
|
272
|
+
background: radial-gradient(circle at 100% 0, rgba(96, 165, 250, 0.11) 0, transparent 55%);
|
|
273
|
+
opacity: 0.75;
|
|
274
|
+
pointer-events: none;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
.section-inner {
|
|
278
|
+
position: relative;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
.section h2 {
|
|
282
|
+
color: #e5e7eb;
|
|
283
|
+
margin-bottom: 16px;
|
|
284
|
+
font-size: 16px;
|
|
285
|
+
font-weight: 600;
|
|
286
|
+
display: flex;
|
|
287
|
+
align-items: center;
|
|
288
|
+
justify-content: space-between;
|
|
289
|
+
gap: 10px;
|
|
290
|
+
border-bottom: 1px solid rgba(148, 163, 184, 0.25);
|
|
291
|
+
padding-bottom: 9px;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
.section-tag {
|
|
295
|
+
font-size: 11px;
|
|
296
|
+
text-transform: uppercase;
|
|
297
|
+
letter-spacing: 0.16em;
|
|
298
|
+
color: var(--text-subtle);
|
|
299
|
+
}
|
|
300
|
+
|
|
85
301
|
.recommendation {
|
|
86
302
|
display: flex;
|
|
87
|
-
gap:
|
|
88
|
-
padding:
|
|
303
|
+
gap: 14px;
|
|
304
|
+
padding: 13px 12px;
|
|
89
305
|
margin-bottom: 10px;
|
|
90
|
-
border-radius:
|
|
91
|
-
border
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
.recommendation.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
306
|
+
border-radius: var(--radius-md);
|
|
307
|
+
border: 1px solid rgba(148, 163, 184, 0.35);
|
|
308
|
+
background: rgba(15, 23, 42, 0.92);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.recommendation.critical {
|
|
312
|
+
border-color: rgba(248, 113, 113, 0.6);
|
|
313
|
+
background: linear-gradient(135deg, rgba(127, 29, 29, 0.9), rgba(15, 23, 42, 0.96));
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
.recommendation.warning {
|
|
317
|
+
border-color: rgba(251, 146, 60, 0.7);
|
|
318
|
+
background: linear-gradient(135deg, rgba(124, 45, 18, 0.9), rgba(15, 23, 42, 0.96));
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.recommendation.info {
|
|
322
|
+
border-color: rgba(56, 189, 248, 0.65);
|
|
323
|
+
background: linear-gradient(135deg, rgba(12, 74, 110, 0.9), rgba(15, 23, 42, 0.96));
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
.rec-icon {
|
|
327
|
+
font-size: 22px;
|
|
328
|
+
line-height: 1;
|
|
329
|
+
margin-top: 2px;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.rec-content {
|
|
333
|
+
flex: 1;
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
.rec-message {
|
|
337
|
+
font-weight: 600;
|
|
338
|
+
margin-bottom: 4px;
|
|
339
|
+
color: #f9fafb;
|
|
340
|
+
font-size: 14px;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
.rec-action {
|
|
344
|
+
font-size: 12px;
|
|
345
|
+
color: var(--text-soft);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
table {
|
|
349
|
+
width: 100%;
|
|
350
|
+
border-collapse: collapse;
|
|
351
|
+
font-size: 12px;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
th,
|
|
355
|
+
td {
|
|
356
|
+
padding: 9px 10px;
|
|
357
|
+
border-bottom: 1px solid rgba(51, 65, 85, 0.9);
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
th {
|
|
361
|
+
background: radial-gradient(circle at 0 0, rgba(148, 163, 184, 0.22) 0, rgba(15, 23, 42, 0.98) 70%);
|
|
362
|
+
text-align: left;
|
|
363
|
+
font-weight: 600;
|
|
364
|
+
color: #e5e7eb;
|
|
365
|
+
position: sticky;
|
|
366
|
+
top: 0;
|
|
367
|
+
z-index: 1;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
td {
|
|
371
|
+
color: var(--text-main);
|
|
372
|
+
vertical-align: top;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
tr:nth-child(even) td {
|
|
376
|
+
background: rgba(15, 23, 42, 0.92);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
tr:nth-child(odd) td {
|
|
380
|
+
background: rgba(15, 23, 42, 0.86);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
tr:hover td {
|
|
384
|
+
background: rgba(30, 64, 175, 0.6);
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
ul {
|
|
388
|
+
list-style: none;
|
|
389
|
+
padding-left: 0;
|
|
390
|
+
font-size: 13px;
|
|
391
|
+
color: var(--text-main);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
ul li {
|
|
395
|
+
margin-bottom: 7px;
|
|
396
|
+
padding-left: 14px;
|
|
397
|
+
position: relative;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
ul li::before {
|
|
401
|
+
content: 'โข';
|
|
402
|
+
position: absolute;
|
|
403
|
+
left: 0;
|
|
404
|
+
color: var(--accent);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
footer {
|
|
408
|
+
text-align: center;
|
|
409
|
+
color: var(--text-subtle);
|
|
410
|
+
font-size: 11px;
|
|
411
|
+
margin-top: 28px;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
footer span {
|
|
415
|
+
color: var(--accent);
|
|
416
|
+
font-weight: 500;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
@media (max-width: 768px) {
|
|
420
|
+
body {
|
|
421
|
+
padding: 18px 12px 28px;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
header {
|
|
425
|
+
padding: 18px 16px 16px;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.header-inner {
|
|
429
|
+
flex-direction: column;
|
|
430
|
+
align-items: flex-start;
|
|
431
|
+
gap: 10px;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
.timestamp-group {
|
|
435
|
+
text-align: left;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
.metrics-grid {
|
|
439
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
@media (max-width: 520px) {
|
|
444
|
+
.metrics-grid {
|
|
445
|
+
grid-template-columns: minmax(0, 1fr);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
108
448
|
</style>
|
|
109
449
|
</head>
|
|
110
450
|
<body>
|
|
111
451
|
<div class="container">
|
|
112
452
|
<header>
|
|
113
|
-
<
|
|
114
|
-
|
|
453
|
+
<div class="header-inner">
|
|
454
|
+
<div>
|
|
455
|
+
<h1><span class="icon">๐</span> Package Analysis Report</h1>
|
|
456
|
+
<p class="header-subtitle">High-signal insights into your JavaScript bundle: size, composition, and optimization opportunities.</p>
|
|
457
|
+
<div class="badge-row">
|
|
458
|
+
<span class="badge badge-accent"><span class="badge-dot"></span> Bundle Health Overview</span>
|
|
459
|
+
<span class="badge">Metrics, duplicates, and tree-shaking diagnostics</span>
|
|
460
|
+
${baseline ? '<span class="badge">Baseline comparison enabled</span>' : ''}
|
|
461
|
+
</div>
|
|
462
|
+
</div>
|
|
463
|
+
<div class="timestamp-group">
|
|
464
|
+
<div>
|
|
465
|
+
<div class="timestamp-label">Current Run</div>
|
|
466
|
+
<div class="timestamp-value">${new Date(result.timestamp).toLocaleString()}</div>
|
|
467
|
+
</div>
|
|
468
|
+
${baseline
|
|
469
|
+
? `<div style="margin-top:8px;">
|
|
470
|
+
<div class="timestamp-label">Baseline</div>
|
|
471
|
+
<div class="timestamp-value">${new Date(baseline.timestamp).toLocaleString()}</div>
|
|
472
|
+
</div>`
|
|
473
|
+
: ''}
|
|
474
|
+
</div>
|
|
475
|
+
</div>
|
|
115
476
|
</header>
|
|
116
477
|
|
|
117
478
|
<div class="metrics-grid">
|
|
118
479
|
<div class="metric-card">
|
|
119
480
|
<div class="metric-label">Total Size</div>
|
|
120
481
|
<div class="metric-value">${(result.metrics.totalSize / 1024 / 1024).toFixed(2)} MB</div>
|
|
482
|
+
${formatDeltaHtmlMb(baseline?.metrics.totalSize, result.metrics.totalSize)}
|
|
121
483
|
</div>
|
|
122
484
|
<div class="metric-card">
|
|
123
485
|
<div class="metric-label">Gzip Size</div>
|
|
124
486
|
<div class="metric-value">${(result.metrics.totalGzipSize / 1024 / 1024).toFixed(2)} MB</div>
|
|
487
|
+
${formatDeltaHtmlMb(baseline?.metrics.totalGzipSize, result.metrics.totalGzipSize)}
|
|
125
488
|
</div>
|
|
126
489
|
<div class="metric-card">
|
|
127
490
|
<div class="metric-label">Modules</div>
|
|
128
491
|
<div class="metric-value">${result.metrics.moduleCount}</div>
|
|
492
|
+
${formatDeltaHtmlCount(baseline?.metrics.moduleCount, result.metrics.moduleCount)}
|
|
129
493
|
</div>
|
|
130
494
|
<div class="metric-card">
|
|
131
495
|
<div class="metric-label">Chunks</div>
|
|
132
496
|
<div class="metric-value">${result.metrics.chunkCount}</div>
|
|
497
|
+
${formatDeltaHtmlCount(baseline?.metrics.chunkCount, result.metrics.chunkCount)}
|
|
133
498
|
</div>
|
|
134
499
|
<div class="metric-card">
|
|
135
500
|
<div class="metric-label">Avg Module Size</div>
|
|
@@ -143,29 +508,81 @@ function generateHTML(result) {
|
|
|
143
508
|
|
|
144
509
|
${result.recommendations.length > 0 ? `
|
|
145
510
|
<div class="section">
|
|
146
|
-
<
|
|
147
|
-
|
|
511
|
+
<div class="section-inner">
|
|
512
|
+
<h2>
|
|
513
|
+
<span>๐ก Recommendations</span>
|
|
514
|
+
<span class="section-tag">Optimization guidance</span>
|
|
515
|
+
</h2>
|
|
516
|
+
${recommendations}
|
|
517
|
+
</div>
|
|
148
518
|
</div>
|
|
149
519
|
` : ''}
|
|
150
520
|
|
|
151
521
|
<div class="section">
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
<
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
522
|
+
<div class="section-inner">
|
|
523
|
+
<h2>
|
|
524
|
+
<span>๐ฆ Top 10 Modules by Size</span>
|
|
525
|
+
<span class="section-tag">Heaviest contributors</span>
|
|
526
|
+
</h2>
|
|
527
|
+
<table>
|
|
528
|
+
<thead>
|
|
529
|
+
<tr>
|
|
530
|
+
<th>Module Name</th>
|
|
531
|
+
<th>Size</th>
|
|
532
|
+
<th>Percentage</th>
|
|
533
|
+
</tr>
|
|
534
|
+
</thead>
|
|
535
|
+
<tbody>
|
|
536
|
+
${topModules}
|
|
537
|
+
</tbody>
|
|
538
|
+
</table>
|
|
539
|
+
</div>
|
|
540
|
+
</div>
|
|
541
|
+
|
|
542
|
+
<div class="section">
|
|
543
|
+
<div class="section-inner">
|
|
544
|
+
<h2>
|
|
545
|
+
<span>๐ Duplicate Modules</span>
|
|
546
|
+
<span class="section-tag">De-duplication opportunities</span>
|
|
547
|
+
</h2>
|
|
548
|
+
${result.duplicates.length === 0
|
|
549
|
+
? '<p>No duplicate modules detected.</p>'
|
|
550
|
+
: `
|
|
551
|
+
<table>
|
|
552
|
+
<thead>
|
|
553
|
+
<tr>
|
|
554
|
+
<th>Count</th>
|
|
555
|
+
<th>Total Size</th>
|
|
556
|
+
<th>Potential Savings</th>
|
|
557
|
+
<th>Example Names</th>
|
|
558
|
+
</tr>
|
|
559
|
+
</thead>
|
|
560
|
+
<tbody>
|
|
561
|
+
${duplicates}
|
|
562
|
+
</tbody>
|
|
563
|
+
</table>
|
|
564
|
+
`}
|
|
565
|
+
</div>
|
|
566
|
+
</div>
|
|
567
|
+
|
|
568
|
+
<div class="section">
|
|
569
|
+
<div class="section-inner">
|
|
570
|
+
<h2>
|
|
571
|
+
<span>๐ณ Tree-Shaking Issues</span>
|
|
572
|
+
<span class="section-tag">Modern module usage</span>
|
|
573
|
+
</h2>
|
|
574
|
+
${result.treeshakingIssues.length === 0
|
|
575
|
+
? '<p>No obvious tree-shaking issues detected.</p>'
|
|
576
|
+
: `
|
|
577
|
+
<ul>
|
|
578
|
+
${treeshakingIssues}
|
|
579
|
+
</ul>
|
|
580
|
+
`}
|
|
581
|
+
</div>
|
|
165
582
|
</div>
|
|
166
583
|
|
|
167
584
|
<footer>
|
|
168
|
-
<p>
|
|
585
|
+
<p><span>Packlyze</span> ยท Advanced JavaScript bundle analysis</p>
|
|
169
586
|
</footer>
|
|
170
587
|
</div>
|
|
171
588
|
</body>
|
|
@@ -182,4 +599,24 @@ function escapeHtml(text) {
|
|
|
182
599
|
};
|
|
183
600
|
return text.replace(/[&<>"']/g, char => map[char]);
|
|
184
601
|
}
|
|
602
|
+
function formatDeltaHtmlMb(baselineBytes, currentBytes) {
|
|
603
|
+
if (baselineBytes === undefined || currentBytes === undefined)
|
|
604
|
+
return '';
|
|
605
|
+
const diffMb = (currentBytes - baselineBytes) / 1024 / 1024;
|
|
606
|
+
if (Math.abs(diffMb) < 0.01)
|
|
607
|
+
return '';
|
|
608
|
+
const sign = diffMb > 0 ? '+' : '-';
|
|
609
|
+
const cls = diffMb > 0 ? 'delta-negative' : 'delta-positive';
|
|
610
|
+
return `<div class="metric-delta ${cls}">${sign}${Math.abs(diffMb).toFixed(2)} MB vs baseline</div>`;
|
|
611
|
+
}
|
|
612
|
+
function formatDeltaHtmlCount(baseline, current) {
|
|
613
|
+
if (baseline === undefined || current === undefined)
|
|
614
|
+
return '';
|
|
615
|
+
const diff = current - baseline;
|
|
616
|
+
if (diff === 0)
|
|
617
|
+
return '';
|
|
618
|
+
const sign = diff > 0 ? '+' : '-';
|
|
619
|
+
const cls = diff > 0 ? 'delta-negative' : 'delta-positive';
|
|
620
|
+
return `<div class="metric-delta ${cls}">${sign}${Math.abs(diff)} vs baseline</div>`;
|
|
621
|
+
}
|
|
185
622
|
//# sourceMappingURL=reports.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":";;;;;AAGA,gDAGC;AAND,4CAAoB;AAGpB,SAAgB,kBAAkB,CAAC,MAAsB,EAAE,UAAkB;
|
|
1
|
+
{"version":3,"file":"reports.js","sourceRoot":"","sources":["../../src/visualization/reports.ts"],"names":[],"mappings":"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"}
|