@node-cli/bundlecheck 1.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/LICENSE +21 -0
- package/README.md +154 -0
- package/dist/bundlecheck.d.ts +2 -0
- package/dist/bundlecheck.js +137 -0
- package/dist/bundlecheck.js.map +1 -0
- package/dist/bundler.d.ts +57 -0
- package/dist/bundler.js +455 -0
- package/dist/bundler.js.map +1 -0
- package/dist/defaults.d.ts +9 -0
- package/dist/defaults.js +14 -0
- package/dist/defaults.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/parse.d.ts +21 -0
- package/dist/parse.js +118 -0
- package/dist/parse.js.map +1 -0
- package/dist/trend.d.ts +27 -0
- package/dist/trend.js +118 -0
- package/dist/trend.js.map +1 -0
- package/dist/versions.d.ts +9 -0
- package/dist/versions.js +66 -0
- package/dist/versions.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) Arno Versini
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# @node-cli/bundlecheck
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+
|
|
5
|
+
A CLI tool to check the bundle size of npm packages, similar to [bundlephobia.com](https://bundlephobia.com/).
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- Check bundle size of any npm package
|
|
10
|
+
- Support for specific package versions (e.g., `lodash@4.17.0`)
|
|
11
|
+
- Interactive version selection with `--versions` flag
|
|
12
|
+
- Bundle size trend analysis with `--trend` flag (bar graph across versions)
|
|
13
|
+
- Support for checking specific exports (tree-shaking)
|
|
14
|
+
- Automatic externalization of React and React-DOM
|
|
15
|
+
- Raw and gzip sizes with configurable compression level
|
|
16
|
+
- Fast bundling using esbuild (with pnpm support)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install -g @node-cli/bundlecheck
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Or use with npx:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx @node-cli/bundlecheck <package-name>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
### Check entire package
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
bundlecheck lodash
|
|
36
|
+
bundlecheck @mantine/core
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Check a specific version
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
bundlecheck lodash@4.17.0
|
|
43
|
+
bundlecheck @versini/ui-panel@1.0.0
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Choose version interactively
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
bundlecheck lodash --versions
|
|
50
|
+
bundlecheck @mantine/core --versions
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This will fetch available versions from npm and let you select one from a list.
|
|
54
|
+
|
|
55
|
+
### Show bundle size trend
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
bundlecheck lodash --trend # default: 5 versions
|
|
59
|
+
bundlecheck clsx --trend 3 # custom: 3 versions
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This analyzes recent versions and displays a bar graph showing how the bundle size has evolved:
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
Bundle Size Trend: clsx
|
|
66
|
+
────────────────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
Gzip Size:
|
|
69
|
+
2.1.1 ██████████████████████████████ 331 B
|
|
70
|
+
2.0.0 █████████████████████████████ 321 B
|
|
71
|
+
1.2.0 █████████████████████████████ 318 B
|
|
72
|
+
1.0.4 ████████████████████████████ 308 B
|
|
73
|
+
1.0.1 ██████████████████████████ 285 B
|
|
74
|
+
|
|
75
|
+
Raw Size:
|
|
76
|
+
2.1.1 ██████████████████████████████ 527 B
|
|
77
|
+
...
|
|
78
|
+
|
|
79
|
+
────────────────────────────────────────────────────────────
|
|
80
|
+
Change from 1.0.1 to 2.1.1:
|
|
81
|
+
Gzip: +46 B (+16.1%)
|
|
82
|
+
Raw: +108 B (+25.8%)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Check specific exports (tree-shaking)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
bundlecheck @mantine/core "ScrollArea,Button"
|
|
89
|
+
bundlecheck lodash "debounce,throttle"
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Options
|
|
93
|
+
|
|
94
|
+
| Flag | Short | Description |
|
|
95
|
+
| ------------------- | ----------- | ------------------------------------------------------- |
|
|
96
|
+
| `--help` | `-h` | Display help instructions |
|
|
97
|
+
| `--version` | `-v` | Output the current version |
|
|
98
|
+
| `--versions` | `-V` | Choose from available package versions interactively |
|
|
99
|
+
| `--trend [N]` | `-t [N]` | Show bundle size trend for N versions (default: 5) |
|
|
100
|
+
| `--boring` | `-b` | Do not use color output |
|
|
101
|
+
| `--gzipLevel <n>` | `-g <n>` | Gzip compression level (1-9, default: 5) |
|
|
102
|
+
| `--external <pkgs>` | `-e <pkgs>` | Comma-separated additional packages to mark as external |
|
|
103
|
+
| `--noExternal` | `-n` | Do not mark any packages as external |
|
|
104
|
+
|
|
105
|
+
### Examples
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# Check the entire lodash package
|
|
109
|
+
bundlecheck lodash
|
|
110
|
+
|
|
111
|
+
# Check a specific version
|
|
112
|
+
bundlecheck lodash@4.17.0
|
|
113
|
+
bundlecheck @versini/ui-panel@1.0.0
|
|
114
|
+
|
|
115
|
+
# Check specific exports from @mantine/core
|
|
116
|
+
bundlecheck @mantine/core "ScrollArea,Button"
|
|
117
|
+
|
|
118
|
+
# Check react itself (without marking it as external)
|
|
119
|
+
bundlecheck react -n
|
|
120
|
+
|
|
121
|
+
# Add vue and svelte as additional externals
|
|
122
|
+
bundlecheck some-package --external "vue,svelte"
|
|
123
|
+
|
|
124
|
+
# Use a different gzip compression level
|
|
125
|
+
bundlecheck lodash --gzipLevel 6
|
|
126
|
+
|
|
127
|
+
# Choose version interactively
|
|
128
|
+
bundlecheck lodash --versions
|
|
129
|
+
|
|
130
|
+
# Show bundle size trend (default: 5 versions)
|
|
131
|
+
bundlecheck lodash --trend
|
|
132
|
+
|
|
133
|
+
# Show bundle size trend for 3 versions
|
|
134
|
+
bundlecheck lodash --trend 3
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## How It Works
|
|
138
|
+
|
|
139
|
+
1. Creates a temporary directory
|
|
140
|
+
2. Installs the specified npm package
|
|
141
|
+
3. Creates an entry file importing the package/exports
|
|
142
|
+
4. Bundles with esbuild (minified, tree-shaken)
|
|
143
|
+
5. Reports raw and gzip sizes
|
|
144
|
+
6. Cleans up temporary files
|
|
145
|
+
|
|
146
|
+
## Default Externals
|
|
147
|
+
|
|
148
|
+
By default, `react` and `react-dom` are marked as external (not included in the bundle size) since most React-based packages expect these as peer dependencies. This matches how these packages would typically be used in a real application.
|
|
149
|
+
|
|
150
|
+
To include React/React-DOM in the bundle size calculation, use the `--no-external` flag.
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT - see [LICENSE](./LICENSE) for details.
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/* istanbul ignore file */ import { Logger } from "@node-cli/logger";
|
|
3
|
+
import kleur from "kleur";
|
|
4
|
+
import { checkBundleSize, formatBytes, parsePackageSpecifier } from "./bundler.js";
|
|
5
|
+
import { TREND_VERSION_COUNT } from "./defaults.js";
|
|
6
|
+
import { config } from "./parse.js";
|
|
7
|
+
import { analyzeTrend, renderTrendGraph, selectTrendVersions } from "./trend.js";
|
|
8
|
+
import { fetchPackageVersions, promptForVersion } from "./versions.js";
|
|
9
|
+
const flags = config.flags;
|
|
10
|
+
const parameters = config.parameters;
|
|
11
|
+
// Disable kleur colors when --boring flag is set
|
|
12
|
+
kleur.enabled = !flags?.boring;
|
|
13
|
+
const log = new Logger({
|
|
14
|
+
boring: flags?.boring
|
|
15
|
+
});
|
|
16
|
+
async function main() {
|
|
17
|
+
let packageName = parameters?.["0"];
|
|
18
|
+
if (!packageName) {
|
|
19
|
+
log.error("Package name is required");
|
|
20
|
+
config.showHelp?.();
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
// Parse additional externals if provided (comma-separated)
|
|
24
|
+
let additionalExternals;
|
|
25
|
+
if (flags?.external) {
|
|
26
|
+
additionalExternals = flags.external.split(",").map((e)=>e.trim()).filter(Boolean);
|
|
27
|
+
}
|
|
28
|
+
// Parse exports if provided (comma-separated)
|
|
29
|
+
let exports;
|
|
30
|
+
const exportsArg = parameters?.["1"];
|
|
31
|
+
if (exportsArg) {
|
|
32
|
+
exports = exportsArg.split(",").map((e)=>e.trim()).filter(Boolean);
|
|
33
|
+
}
|
|
34
|
+
// If --trend flag is set, show bundle size trend across versions
|
|
35
|
+
// --trend alone uses default (5), --trend N uses N versions
|
|
36
|
+
const trendValue = flags?.trend;
|
|
37
|
+
if (trendValue !== undefined) {
|
|
38
|
+
const parsedCount = Number.parseInt(trendValue, 10);
|
|
39
|
+
const versionCount = !Number.isNaN(parsedCount) && parsedCount > 0 ? parsedCount : TREND_VERSION_COUNT;
|
|
40
|
+
try {
|
|
41
|
+
const { name, subpath } = parsePackageSpecifier(packageName);
|
|
42
|
+
// Construct the full package path including subpath if present
|
|
43
|
+
const fullPackagePath = subpath ? `${name}/${subpath}` : name;
|
|
44
|
+
log.info(`\nFetching available versions for ${name}...`);
|
|
45
|
+
const { versions } = await fetchPackageVersions(packageName);
|
|
46
|
+
if (versions.length === 0) {
|
|
47
|
+
log.error("No versions found for this package");
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
// Select versions for trend
|
|
51
|
+
const trendVersions = selectTrendVersions(versions, versionCount);
|
|
52
|
+
log.info(`Analyzing ${trendVersions.length} versions: ${trendVersions.join(", ")}`);
|
|
53
|
+
log.info("");
|
|
54
|
+
const results = await analyzeTrend({
|
|
55
|
+
packageName: fullPackagePath,
|
|
56
|
+
versions: trendVersions,
|
|
57
|
+
exports,
|
|
58
|
+
additionalExternals,
|
|
59
|
+
noExternal: flags?.noExternal,
|
|
60
|
+
gzipLevel: flags?.gzipLevel,
|
|
61
|
+
boring: flags?.boring
|
|
62
|
+
});
|
|
63
|
+
if (results.length === 0) {
|
|
64
|
+
log.error("Failed to analyze any versions");
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
// Render and display the trend graph
|
|
68
|
+
const graphLines = renderTrendGraph(fullPackagePath, results, flags?.boring);
|
|
69
|
+
for (const line of graphLines){
|
|
70
|
+
log.log(line);
|
|
71
|
+
}
|
|
72
|
+
process.exit(0);
|
|
73
|
+
} catch (error) {
|
|
74
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
75
|
+
log.error(`Failed to analyze trend: ${errorMessage}`);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// If --versions flag is set, fetch and prompt for version selection
|
|
80
|
+
if (flags?.versions) {
|
|
81
|
+
try {
|
|
82
|
+
const { name, subpath } = parsePackageSpecifier(packageName);
|
|
83
|
+
log.info(`\nFetching available versions for ${name}...`);
|
|
84
|
+
const { versions, tags } = await fetchPackageVersions(packageName);
|
|
85
|
+
if (versions.length === 0) {
|
|
86
|
+
log.error("No versions found for this package");
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
const selectedVersion = await promptForVersion(name, versions, tags);
|
|
90
|
+
// Rebuild specifier preserving any subpath
|
|
91
|
+
packageName = subpath ? `${name}/${subpath}@${selectedVersion}` : `${name}@${selectedVersion}`;
|
|
92
|
+
log.info(`\nSelected: ${packageName}`);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
95
|
+
log.error(`Failed to fetch versions: ${errorMessage}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
log.info(`\nAnalyzing bundle size for: ${packageName}`);
|
|
100
|
+
if (exports && exports.length > 0) {
|
|
101
|
+
log.info(`Exports: { ${exports.join(", ")} }`);
|
|
102
|
+
}
|
|
103
|
+
log.info("Please wait, installing and bundling...\n");
|
|
104
|
+
try {
|
|
105
|
+
const result = await checkBundleSize({
|
|
106
|
+
packageName,
|
|
107
|
+
exports,
|
|
108
|
+
additionalExternals,
|
|
109
|
+
noExternal: flags?.noExternal,
|
|
110
|
+
gzipLevel: flags?.gzipLevel
|
|
111
|
+
});
|
|
112
|
+
const blue = kleur.blue;
|
|
113
|
+
const green = kleur.green;
|
|
114
|
+
// Display results
|
|
115
|
+
log.printBox([
|
|
116
|
+
`${blue("Package:")} ${result.packageName} (${blue("version:")} ${result.packageVersion})`,
|
|
117
|
+
result.exports.length > 0 ? `${blue("Exports:")} { ${result.exports.join(", ")} }` : `${blue("Exports:")} * (entire package)`,
|
|
118
|
+
"",
|
|
119
|
+
`${blue("Raw size:")} ${formatBytes(result.rawSize)}`,
|
|
120
|
+
`${blue("Gzip size:")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`,
|
|
121
|
+
"",
|
|
122
|
+
result.externals.length > 0 ? `${blue("Externals:")} ${result.externals.join(", ")}` : `${blue("Externals:")} ${green("none")}`,
|
|
123
|
+
result.dependencies.length > 0 ? `${blue("Dependencies:")} ${result.dependencies.join(", ")}` : `${blue("Dependencies:")} ${green("none")}`
|
|
124
|
+
], {
|
|
125
|
+
borderStyle: "round",
|
|
126
|
+
align: "left"
|
|
127
|
+
});
|
|
128
|
+
process.exit(0);
|
|
129
|
+
} catch (error) {
|
|
130
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
131
|
+
log.error(`Failed to analyze bundle size: ${errorMessage}`);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
main();
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=bundlecheck.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/bundlecheck.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/* istanbul ignore file */\n\nimport { Logger } from \"@node-cli/logger\";\nimport kleur from \"kleur\";\nimport {\n\tcheckBundleSize,\n\tformatBytes,\n\tparsePackageSpecifier,\n} from \"./bundler.js\";\nimport { TREND_VERSION_COUNT } from \"./defaults.js\";\nimport { config } from \"./parse.js\";\nimport {\n\tanalyzeTrend,\n\trenderTrendGraph,\n\tselectTrendVersions,\n} from \"./trend.js\";\nimport { fetchPackageVersions, promptForVersion } from \"./versions.js\";\n\nconst flags = config.flags;\nconst parameters = config.parameters;\n\n// Disable kleur colors when --boring flag is set\nkleur.enabled = !flags?.boring;\n\nconst log = new Logger({\n\tboring: flags?.boring,\n});\n\nasync function main() {\n\tlet packageName = parameters?.[\"0\"];\n\n\tif (!packageName) {\n\t\tlog.error(\"Package name is required\");\n\t\tconfig.showHelp?.();\n\t\tprocess.exit(1);\n\t}\n\n\t// Parse additional externals if provided (comma-separated)\n\tlet additionalExternals: string[] | undefined;\n\tif (flags?.external) {\n\t\tadditionalExternals = flags.external\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// Parse exports if provided (comma-separated)\n\tlet exports: string[] | undefined;\n\tconst exportsArg = parameters?.[\"1\"];\n\tif (exportsArg) {\n\t\texports = exportsArg\n\t\t\t.split(\",\")\n\t\t\t.map((e) => e.trim())\n\t\t\t.filter(Boolean);\n\t}\n\n\t// If --trend flag is set, show bundle size trend across versions\n\t// --trend alone uses default (5), --trend N uses N versions\n\tconst trendValue = flags?.trend;\n\tif (trendValue !== undefined) {\n\t\tconst parsedCount = Number.parseInt(trendValue, 10);\n\t\tconst versionCount =\n\t\t\t!Number.isNaN(parsedCount) && parsedCount > 0\n\t\t\t\t? parsedCount\n\t\t\t\t: TREND_VERSION_COUNT;\n\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\t// Construct the full package path including subpath if present\n\t\t\tconst fullPackagePath = subpath ? `${name}/${subpath}` : name;\n\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions } = await fetchPackageVersions(packageName);\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Select versions for trend\n\t\t\tconst trendVersions = selectTrendVersions(versions, versionCount);\n\n\t\t\tlog.info(\n\t\t\t\t`Analyzing ${trendVersions.length} versions: ${trendVersions.join(\", \")}`,\n\t\t\t);\n\t\t\tlog.info(\"\");\n\n\t\t\tconst results = await analyzeTrend({\n\t\t\t\tpackageName: fullPackagePath,\n\t\t\t\tversions: trendVersions,\n\t\t\t\texports,\n\t\t\t\tadditionalExternals,\n\t\t\t\tnoExternal: flags?.noExternal,\n\t\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t\t\tboring: flags?.boring,\n\t\t\t});\n\n\t\t\tif (results.length === 0) {\n\t\t\t\tlog.error(\"Failed to analyze any versions\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\t// Render and display the trend graph\n\t\t\tconst graphLines = renderTrendGraph(\n\t\t\t\tfullPackagePath,\n\t\t\t\tresults,\n\t\t\t\tflags?.boring,\n\t\t\t);\n\t\t\tfor (const line of graphLines) {\n\t\t\t\tlog.log(line);\n\t\t\t}\n\n\t\t\tprocess.exit(0);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to analyze trend: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\t// If --versions flag is set, fetch and prompt for version selection\n\tif (flags?.versions) {\n\t\ttry {\n\t\t\tconst { name, subpath } = parsePackageSpecifier(packageName);\n\t\t\tlog.info(`\\nFetching available versions for ${name}...`);\n\n\t\t\tconst { versions, tags } = await fetchPackageVersions(packageName);\n\n\t\t\tif (versions.length === 0) {\n\t\t\t\tlog.error(\"No versions found for this package\");\n\t\t\t\tprocess.exit(1);\n\t\t\t}\n\n\t\t\tconst selectedVersion = await promptForVersion(name, versions, tags);\n\t\t\t// Rebuild specifier preserving any subpath\n\t\t\tpackageName = subpath\n\t\t\t\t? `${name}/${subpath}@${selectedVersion}`\n\t\t\t\t: `${name}@${selectedVersion}`;\n\t\t\tlog.info(`\\nSelected: ${packageName}`);\n\t\t} catch (error) {\n\t\t\tconst errorMessage =\n\t\t\t\terror instanceof Error ? error.message : String(error);\n\t\t\tlog.error(`Failed to fetch versions: ${errorMessage}`);\n\t\t\tprocess.exit(1);\n\t\t}\n\t}\n\n\tlog.info(`\\nAnalyzing bundle size for: ${packageName}`);\n\tif (exports && exports.length > 0) {\n\t\tlog.info(`Exports: { ${exports.join(\", \")} }`);\n\t}\n\tlog.info(\"Please wait, installing and bundling...\\n\");\n\n\ttry {\n\t\tconst result = await checkBundleSize({\n\t\t\tpackageName,\n\t\t\texports,\n\t\t\tadditionalExternals,\n\t\t\tnoExternal: flags?.noExternal,\n\t\t\tgzipLevel: flags?.gzipLevel,\n\t\t});\n\n\t\tconst blue = kleur.blue;\n\t\tconst green = kleur.green;\n\n\t\t// Display results\n\t\tlog.printBox(\n\t\t\t[\n\t\t\t\t`${blue(\"Package:\")} ${result.packageName} (${blue(\"version:\")} ${result.packageVersion})`,\n\t\t\t\tresult.exports.length > 0\n\t\t\t\t\t? `${blue(\"Exports:\")} { ${result.exports.join(\", \")} }`\n\t\t\t\t\t: `${blue(\"Exports:\")} * (entire package)`,\n\t\t\t\t\"\",\n\t\t\t\t`${blue(\"Raw size:\")} ${formatBytes(result.rawSize)}`,\n\t\t\t\t`${blue(\"Gzip size:\")} ${formatBytes(result.gzipSize)} (level ${result.gzipLevel})`,\n\t\t\t\t\"\",\n\t\t\t\tresult.externals.length > 0\n\t\t\t\t\t? `${blue(\"Externals:\")} ${result.externals.join(\", \")}`\n\t\t\t\t\t: `${blue(\"Externals:\")} ${green(\"none\")}`,\n\t\t\t\tresult.dependencies.length > 0\n\t\t\t\t\t? `${blue(\"Dependencies:\")} ${result.dependencies.join(\", \")}`\n\t\t\t\t\t: `${blue(\"Dependencies:\")} ${green(\"none\")}`,\n\t\t\t],\n\t\t\t{\n\t\t\t\tborderStyle: \"round\",\n\t\t\t\talign: \"left\",\n\t\t\t},\n\t\t);\n\n\t\tprocess.exit(0);\n\t} catch (error) {\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tlog.error(`Failed to analyze bundle size: ${errorMessage}`);\n\t\tprocess.exit(1);\n\t}\n}\n\nmain();\n"],"names":["Logger","kleur","checkBundleSize","formatBytes","parsePackageSpecifier","TREND_VERSION_COUNT","config","analyzeTrend","renderTrendGraph","selectTrendVersions","fetchPackageVersions","promptForVersion","flags","parameters","enabled","boring","log","main","packageName","error","showHelp","process","exit","additionalExternals","external","split","map","e","trim","filter","Boolean","exports","exportsArg","trendValue","trend","undefined","parsedCount","Number","parseInt","versionCount","isNaN","name","subpath","fullPackagePath","info","versions","length","trendVersions","join","results","noExternal","gzipLevel","graphLines","line","errorMessage","Error","message","String","tags","selectedVersion","result","blue","green","printBox","packageVersion","rawSize","gzipSize","externals","dependencies","borderStyle","align"],"mappings":";AAEA,wBAAwB,GAExB,SAASA,MAAM,QAAQ,mBAAmB;AAC1C,OAAOC,WAAW,QAAQ;AAC1B,SACCC,eAAe,EACfC,WAAW,EACXC,qBAAqB,QACf,eAAe;AACtB,SAASC,mBAAmB,QAAQ,gBAAgB;AACpD,SAASC,MAAM,QAAQ,aAAa;AACpC,SACCC,YAAY,EACZC,gBAAgB,EAChBC,mBAAmB,QACb,aAAa;AACpB,SAASC,oBAAoB,EAAEC,gBAAgB,QAAQ,gBAAgB;AAEvE,MAAMC,QAAQN,OAAOM,KAAK;AAC1B,MAAMC,aAAaP,OAAOO,UAAU;AAEpC,iDAAiD;AACjDZ,MAAMa,OAAO,GAAG,CAACF,OAAOG;AAExB,MAAMC,MAAM,IAAIhB,OAAO;IACtBe,QAAQH,OAAOG;AAChB;AAEA,eAAeE;IACd,IAAIC,cAAcL,YAAY,CAAC,IAAI;IAEnC,IAAI,CAACK,aAAa;QACjBF,IAAIG,KAAK,CAAC;QACVb,OAAOc,QAAQ;QACfC,QAAQC,IAAI,CAAC;IACd;IAEA,2DAA2D;IAC3D,IAAIC;IACJ,IAAIX,OAAOY,UAAU;QACpBD,sBAAsBX,MAAMY,QAAQ,CAClCC,KAAK,CAAC,KACNC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,IACjBC,MAAM,CAACC;IACV;IAEA,8CAA8C;IAC9C,IAAIC;IACJ,MAAMC,aAAanB,YAAY,CAAC,IAAI;IACpC,IAAImB,YAAY;QACfD,UAAUC,WACRP,KAAK,CAAC,KACNC,GAAG,CAAC,CAACC,IAAMA,EAAEC,IAAI,IACjBC,MAAM,CAACC;IACV;IAEA,iEAAiE;IACjE,4DAA4D;IAC5D,MAAMG,aAAarB,OAAOsB;IAC1B,IAAID,eAAeE,WAAW;QAC7B,MAAMC,cAAcC,OAAOC,QAAQ,CAACL,YAAY;QAChD,MAAMM,eACL,CAACF,OAAOG,KAAK,CAACJ,gBAAgBA,cAAc,IACzCA,cACA/B;QAEJ,IAAI;YACH,MAAM,EAAEoC,IAAI,EAAEC,OAAO,EAAE,GAAGtC,sBAAsBc;YAChD,+DAA+D;YAC/D,MAAMyB,kBAAkBD,UAAU,GAAGD,KAAK,CAAC,EAAEC,SAAS,GAAGD;YAEzDzB,IAAI4B,IAAI,CAAC,CAAC,kCAAkC,EAAEH,KAAK,GAAG,CAAC;YAEvD,MAAM,EAAEI,QAAQ,EAAE,GAAG,MAAMnC,qBAAqBQ;YAEhD,IAAI2B,SAASC,MAAM,KAAK,GAAG;gBAC1B9B,IAAIG,KAAK,CAAC;gBACVE,QAAQC,IAAI,CAAC;YACd;YAEA,4BAA4B;YAC5B,MAAMyB,gBAAgBtC,oBAAoBoC,UAAUN;YAEpDvB,IAAI4B,IAAI,CACP,CAAC,UAAU,EAAEG,cAAcD,MAAM,CAAC,WAAW,EAAEC,cAAcC,IAAI,CAAC,OAAO;YAE1EhC,IAAI4B,IAAI,CAAC;YAET,MAAMK,UAAU,MAAM1C,aAAa;gBAClCW,aAAayB;gBACbE,UAAUE;gBACVhB;gBACAR;gBACA2B,YAAYtC,OAAOsC;gBACnBC,WAAWvC,OAAOuC;gBAClBpC,QAAQH,OAAOG;YAChB;YAEA,IAAIkC,QAAQH,MAAM,KAAK,GAAG;gBACzB9B,IAAIG,KAAK,CAAC;gBACVE,QAAQC,IAAI,CAAC;YACd;YAEA,qCAAqC;YACrC,MAAM8B,aAAa5C,iBAClBmC,iBACAM,SACArC,OAAOG;YAER,KAAK,MAAMsC,QAAQD,WAAY;gBAC9BpC,IAAIA,GAAG,CAACqC;YACT;YAEAhC,QAAQC,IAAI,CAAC;QACd,EAAE,OAAOH,OAAO;YACf,MAAMmC,eACLnC,iBAAiBoC,QAAQpC,MAAMqC,OAAO,GAAGC,OAAOtC;YACjDH,IAAIG,KAAK,CAAC,CAAC,yBAAyB,EAAEmC,cAAc;YACpDjC,QAAQC,IAAI,CAAC;QACd;IACD;IAEA,oEAAoE;IACpE,IAAIV,OAAOiC,UAAU;QACpB,IAAI;YACH,MAAM,EAAEJ,IAAI,EAAEC,OAAO,EAAE,GAAGtC,sBAAsBc;YAChDF,IAAI4B,IAAI,CAAC,CAAC,kCAAkC,EAAEH,KAAK,GAAG,CAAC;YAEvD,MAAM,EAAEI,QAAQ,EAAEa,IAAI,EAAE,GAAG,MAAMhD,qBAAqBQ;YAEtD,IAAI2B,SAASC,MAAM,KAAK,GAAG;gBAC1B9B,IAAIG,KAAK,CAAC;gBACVE,QAAQC,IAAI,CAAC;YACd;YAEA,MAAMqC,kBAAkB,MAAMhD,iBAAiB8B,MAAMI,UAAUa;YAC/D,2CAA2C;YAC3CxC,cAAcwB,UACX,GAAGD,KAAK,CAAC,EAAEC,QAAQ,CAAC,EAAEiB,iBAAiB,GACvC,GAAGlB,KAAK,CAAC,EAAEkB,iBAAiB;YAC/B3C,IAAI4B,IAAI,CAAC,CAAC,YAAY,EAAE1B,aAAa;QACtC,EAAE,OAAOC,OAAO;YACf,MAAMmC,eACLnC,iBAAiBoC,QAAQpC,MAAMqC,OAAO,GAAGC,OAAOtC;YACjDH,IAAIG,KAAK,CAAC,CAAC,0BAA0B,EAAEmC,cAAc;YACrDjC,QAAQC,IAAI,CAAC;QACd;IACD;IAEAN,IAAI4B,IAAI,CAAC,CAAC,6BAA6B,EAAE1B,aAAa;IACtD,IAAIa,WAAWA,QAAQe,MAAM,GAAG,GAAG;QAClC9B,IAAI4B,IAAI,CAAC,CAAC,WAAW,EAAEb,QAAQiB,IAAI,CAAC,MAAM,EAAE,CAAC;IAC9C;IACAhC,IAAI4B,IAAI,CAAC;IAET,IAAI;QACH,MAAMgB,SAAS,MAAM1D,gBAAgB;YACpCgB;YACAa;YACAR;YACA2B,YAAYtC,OAAOsC;YACnBC,WAAWvC,OAAOuC;QACnB;QAEA,MAAMU,OAAO5D,MAAM4D,IAAI;QACvB,MAAMC,QAAQ7D,MAAM6D,KAAK;QAEzB,kBAAkB;QAClB9C,IAAI+C,QAAQ,CACX;YACC,GAAGF,KAAK,YAAY,CAAC,EAAED,OAAO1C,WAAW,CAAC,EAAE,EAAE2C,KAAK,YAAY,CAAC,EAAED,OAAOI,cAAc,CAAC,CAAC,CAAC;YAC1FJ,OAAO7B,OAAO,CAACe,MAAM,GAAG,IACrB,GAAGe,KAAK,YAAY,GAAG,EAAED,OAAO7B,OAAO,CAACiB,IAAI,CAAC,MAAM,EAAE,CAAC,GACtD,GAAGa,KAAK,YAAY,mBAAmB,CAAC;YAC3C;YACA,GAAGA,KAAK,aAAa,EAAE,EAAE1D,YAAYyD,OAAOK,OAAO,GAAG;YACtD,GAAGJ,KAAK,cAAc,CAAC,EAAE1D,YAAYyD,OAAOM,QAAQ,EAAE,QAAQ,EAAEN,OAAOT,SAAS,CAAC,CAAC,CAAC;YACnF;YACAS,OAAOO,SAAS,CAACrB,MAAM,GAAG,IACvB,GAAGe,KAAK,cAAc,CAAC,EAAED,OAAOO,SAAS,CAACnB,IAAI,CAAC,OAAO,GACtD,GAAGa,KAAK,cAAc,CAAC,EAAEC,MAAM,SAAS;YAC3CF,OAAOQ,YAAY,CAACtB,MAAM,GAAG,IAC1B,GAAGe,KAAK,iBAAiB,CAAC,EAAED,OAAOQ,YAAY,CAACpB,IAAI,CAAC,OAAO,GAC5D,GAAGa,KAAK,iBAAiB,CAAC,EAAEC,MAAM,SAAS;SAC9C,EACD;YACCO,aAAa;YACbC,OAAO;QACR;QAGDjD,QAAQC,IAAI,CAAC;IACd,EAAE,OAAOH,OAAO;QACf,MAAMmC,eAAenC,iBAAiBoC,QAAQpC,MAAMqC,OAAO,GAAGC,OAAOtC;QACrEH,IAAIG,KAAK,CAAC,CAAC,+BAA+B,EAAEmC,cAAc;QAC1DjC,QAAQC,IAAI,CAAC;IACd;AACD;AAEAL"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export type ParsedPackage = {
|
|
2
|
+
name: string;
|
|
3
|
+
version: string;
|
|
4
|
+
subpath?: string;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Parse a package specifier to extract name, version, and subpath
|
|
8
|
+
* Handles:
|
|
9
|
+
* - @scope/package@1.0.0
|
|
10
|
+
* - @scope/package/subpath@1.0.0
|
|
11
|
+
* - @scope/package/subpath
|
|
12
|
+
* - package/subpath@1.0.0
|
|
13
|
+
*/
|
|
14
|
+
export declare function parsePackageSpecifier(specifier: string): ParsedPackage;
|
|
15
|
+
export type BundleOptions = {
|
|
16
|
+
packageName: string;
|
|
17
|
+
exports?: string[];
|
|
18
|
+
additionalExternals?: string[];
|
|
19
|
+
noExternal?: boolean;
|
|
20
|
+
gzipLevel?: number;
|
|
21
|
+
};
|
|
22
|
+
export type BundleResult = {
|
|
23
|
+
packageName: string;
|
|
24
|
+
packageVersion: string;
|
|
25
|
+
exports: string[];
|
|
26
|
+
rawSize: number;
|
|
27
|
+
gzipSize: number;
|
|
28
|
+
gzipLevel: number;
|
|
29
|
+
externals: string[];
|
|
30
|
+
dependencies: string[];
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Format bytes to human-readable string
|
|
34
|
+
*/
|
|
35
|
+
export declare function formatBytes(bytes: number): string;
|
|
36
|
+
export type EntryContentOptions = {
|
|
37
|
+
packageName: string;
|
|
38
|
+
subpath?: string;
|
|
39
|
+
exports?: string[];
|
|
40
|
+
allSubpaths?: string[];
|
|
41
|
+
exportToSubpath?: Map<string, string>;
|
|
42
|
+
};
|
|
43
|
+
export type PackageExports = Record<string, string | {
|
|
44
|
+
import?: string;
|
|
45
|
+
types?: string;
|
|
46
|
+
}>;
|
|
47
|
+
export type PackageInfo = {
|
|
48
|
+
version: string;
|
|
49
|
+
dependencies: Record<string, string>;
|
|
50
|
+
peerDependencies: Record<string, string>;
|
|
51
|
+
exports: PackageExports | null;
|
|
52
|
+
hasMainEntry: boolean;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Check the bundle size of an npm package
|
|
56
|
+
*/
|
|
57
|
+
export declare function checkBundleSize(options: BundleOptions): Promise<BundleResult>;
|