@tomnieuwland/sls-bundle-analyser 1.1.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 (59) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +126 -0
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +54 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/commands/compare.d.ts +10 -0
  8. package/dist/commands/compare.d.ts.map +1 -0
  9. package/dist/commands/compare.js +82 -0
  10. package/dist/commands/compare.js.map +1 -0
  11. package/dist/commands/shared-modules.d.ts +6 -0
  12. package/dist/commands/shared-modules.d.ts.map +1 -0
  13. package/dist/commands/shared-modules.js +27 -0
  14. package/dist/commands/shared-modules.js.map +1 -0
  15. package/dist/commands/sizes.d.ts +6 -0
  16. package/dist/commands/sizes.d.ts.map +1 -0
  17. package/dist/commands/sizes.js +70 -0
  18. package/dist/commands/sizes.js.map +1 -0
  19. package/dist/commands/visualize.d.ts +11 -0
  20. package/dist/commands/visualize.d.ts.map +1 -0
  21. package/dist/commands/visualize.js +29 -0
  22. package/dist/commands/visualize.js.map +1 -0
  23. package/dist/compare.d.ts +47 -0
  24. package/dist/compare.d.ts.map +1 -0
  25. package/dist/compare.js +181 -0
  26. package/dist/compare.js.map +1 -0
  27. package/dist/config.d.ts +11 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/config.js +35 -0
  30. package/dist/config.js.map +1 -0
  31. package/dist/dependency-graph.d.ts +29 -0
  32. package/dist/dependency-graph.d.ts.map +1 -0
  33. package/dist/dependency-graph.js +87 -0
  34. package/dist/dependency-graph.js.map +1 -0
  35. package/dist/esbuild-config.d.ts +4 -0
  36. package/dist/esbuild-config.d.ts.map +1 -0
  37. package/dist/esbuild-config.js +20 -0
  38. package/dist/esbuild-config.js.map +1 -0
  39. package/dist/index.d.ts +8 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +28 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/parse-serverless.d.ts +53 -0
  44. package/dist/parse-serverless.d.ts.map +1 -0
  45. package/dist/parse-serverless.js +195 -0
  46. package/dist/parse-serverless.js.map +1 -0
  47. package/dist/report.d.ts +36 -0
  48. package/dist/report.d.ts.map +1 -0
  49. package/dist/report.js +154 -0
  50. package/dist/report.js.map +1 -0
  51. package/dist/shared-modules.d.ts +17 -0
  52. package/dist/shared-modules.d.ts.map +1 -0
  53. package/dist/shared-modules.js +104 -0
  54. package/dist/shared-modules.js.map +1 -0
  55. package/dist/visualize.d.ts +20 -0
  56. package/dist/visualize.d.ts.map +1 -0
  57. package/dist/visualize.js +139 -0
  58. package/dist/visualize.js.map +1 -0
  59. package/package.json +53 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Thomas Nieuwland
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,126 @@
1
+ # sls-bundle-analyser
2
+
3
+ CLI tool for analysing Lambda bundle sizes in Serverless Framework projects. It parses `serverless*.yml` files to discover handler entry points, bundles them with esbuild, and reports on size changes between branches.
4
+
5
+ To get started, run `npx @tomnieuwland/sls-bundle-analyser sizes` in the root of your project.
6
+
7
+ ## Commands
8
+
9
+ ### `sls-bundle-analyser compare`
10
+
11
+ Compares bundle sizes between the current branch and a base branch. Builds a dependency graph to determine which functions are affected by code changes, then reports size deltas.
12
+
13
+ | Flag | Description |
14
+ | ---------------------- | ------------------------------------------------------------------------------- |
15
+ | `--base <branch>` | Base branch to compare against (default: from config or `main`) |
16
+ | `--all` | Analyze all functions, not just those affected by changes |
17
+ | `--verbose` | Show per-module breakdown for each function |
18
+ | `--json` | Output raw JSON instead of a text table |
19
+ | `--threshold <bytes>` | Only show functions with delta above this threshold |
20
+ | `--fail-above <bytes>` | Exit with code 1 if any function grew more than this many bytes (useful for CI) |
21
+
22
+ ### `sls-bundle-analyser sizes`
23
+
24
+ Bundles all discovered functions and reports their sizes. No branch comparison — just a snapshot of current bundle sizes.
25
+
26
+ | Flag | Description |
27
+ | ---------------- | ----------------------------------------------------- |
28
+ | `--json` | Output raw JSON |
29
+ | `--sort <field>` | Sort order: `size` (default, largest first) or `name` |
30
+
31
+ ### `sls-bundle-analyser visualize <entry-point>`
32
+
33
+ Generates an interactive treemap (or sunburst/network diagram) for a single handler's bundle and opens it in the browser.
34
+
35
+ | Flag | Description |
36
+ | ------------------- | ---------------------------------------------------------------------------- |
37
+ | `--template <type>` | Visualization type: `treemap`, `sunburst`, or `network` (default: `treemap`) |
38
+ | `--no-third-party` | Exclude `node_modules` from the visualization |
39
+ | `--no-open` | Generate the file without opening it in the browser |
40
+ | `--top <n>` | Show only the N largest modules |
41
+ | `--output <path>` | Write HTML to this path instead of opening in the browser |
42
+ | `--diff` | Generate side-by-side visualizations comparing current branch against base |
43
+ | `--base <branch>` | Base branch for `--diff` (default: from config or `main`) |
44
+
45
+ ### `sls-bundle-analyser shared-modules`
46
+
47
+ Analyses which `node_modules` packages are bundled across multiple Lambda functions, helping identify candidates for a shared layer.
48
+
49
+ | Flag | Description |
50
+ | ----------- | ------------------------------------------- |
51
+ | `--json` | Output raw JSON instead of a text table |
52
+ | `--top <n>` | Show only the top N modules (default: `20`) |
53
+
54
+ ## Configuration
55
+
56
+ Configuration is loaded from the service directory (the directory you run the tool from). The tool checks two locations in order:
57
+
58
+ 1. **`.bundle-analyser.json`** — a standalone config file in the service directory
59
+ 2. **`package.json`** — a `"bundle-analyser"` key at the top level
60
+
61
+ If neither is found, defaults are used. All fields are optional.
62
+
63
+ ```json
64
+ {
65
+ "exclude": ["serverless.local-*.yml"],
66
+ "base": "main",
67
+ "esbuild": {}
68
+ }
69
+ ```
70
+
71
+ ### Fields
72
+
73
+ | Field | Type | Default | Description |
74
+ | --------- | ---------- | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
75
+ | `exclude` | `string[]` | `["serverless.local-*.yml"]` | Glob patterns for `serverless*.yml` files to skip. Useful for ignoring local dev overrides. |
76
+ | `base` | `string` | `"main"` | Default base branch for the `compare` and `visualize --diff` commands. Can be overridden per-invocation with `--base`. |
77
+ | `esbuild` | `object` | `{}` | esbuild [BuildOptions](https://esbuild.github.io/api/#build) overrides merged on top of the built-in defaults (`bundle`, `minify`, `platform: "node"`, `target: "node20"`, `cjs`). |
78
+
79
+ ### Example in `package.json`
80
+
81
+ ```json
82
+ {
83
+ "name": "my-service",
84
+ "bundle-analyser": {
85
+ "base": "develop",
86
+ "exclude": ["serverless.local-*.yml", "serverless.test.yml"],
87
+ "esbuild": {
88
+ "external": ["aws-sdk"]
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## Examples
95
+
96
+ ```bash
97
+ # Compare affected functions against main
98
+ sls-bundle-analyser compare
99
+
100
+ # Compare all functions against a specific branch
101
+ sls-bundle-analyser compare --all --base feature-branch
102
+
103
+ # CI gate: fail if any function grew by more than 50KB
104
+ sls-bundle-analyser compare --all --fail-above 51200
105
+
106
+ # JSON output for scripting
107
+ sls-bundle-analyser compare --all --json
108
+
109
+ # Report all bundle sizes (no comparison)
110
+ sls-bundle-analyser sizes
111
+
112
+ # Bundle sizes sorted alphabetically, as JSON
113
+ sls-bundle-analyser sizes --sort name --json
114
+
115
+ # Visualize a single handler
116
+ sls-bundle-analyser visualize src/handlers/someHandler.ts
117
+
118
+ # Visualize only first-party code, top 10 modules, save to file
119
+ sls-bundle-analyser visualize src/handlers/someHandler.ts --no-third-party --top 10 --output report.html
120
+
121
+ # Side-by-side diff visualization against main
122
+ sls-bundle-analyser visualize src/handlers/someHandler.ts --diff
123
+
124
+ # Find most widely shared node_modules packages
125
+ sls-bundle-analyser shared-modules --top 10
126
+ ```
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const commander_1 = require("commander");
5
+ const compare_js_1 = require("./commands/compare.js");
6
+ const shared_modules_js_1 = require("./commands/shared-modules.js");
7
+ const sizes_js_1 = require("./commands/sizes.js");
8
+ const visualize_js_1 = require("./commands/visualize.js");
9
+ const program = new commander_1.Command()
10
+ .name("sls-bundle-analyser")
11
+ .description("Analyze bundle size changes for Serverless Framework Lambda functions.");
12
+ program
13
+ .command("compare")
14
+ .description("compare bundle sizes between current branch and a base branch")
15
+ .option("--base <branch>", "base branch to compare against")
16
+ .option("--all", "analyze all functions, not just those affected by changes")
17
+ .option("--verbose", "show per-module breakdown for each function")
18
+ .option("--json", "output raw JSON instead of text")
19
+ .option("--threshold <bytes>", "only show functions with delta above threshold (in bytes)", "0")
20
+ .option("--fail-above <bytes>", "exit with code 1 if any function grew more than this many bytes")
21
+ .action(compare_js_1.compareAction);
22
+ program
23
+ .command("sizes")
24
+ .description("report bundle sizes for all functions (no branch comparison)")
25
+ .option("--json", "output raw JSON")
26
+ .addOption(new commander_1.Option("--sort <field>", "sort order")
27
+ .choices(["size", "name"])
28
+ .default("size"))
29
+ .action(sizes_js_1.sizesAction);
30
+ program
31
+ .command("visualize")
32
+ .description("generate an interactive bundle treemap for a single entry point")
33
+ .argument("<entry-point>", "handler file to visualize")
34
+ .addOption(new commander_1.Option("--template <type>", "visualization type")
35
+ .choices(["treemap", "sunburst", "network"])
36
+ .default("treemap"))
37
+ .option("--no-third-party", "exclude node_modules from the visualization")
38
+ .option("--no-open", "generate the file without opening it in the browser")
39
+ .option("--output <path>", "write HTML to this path instead of opening in browser")
40
+ .option("--top <n>", "show only the N largest modules")
41
+ .option("--diff", "compare visualization against base branch")
42
+ .option("--base <branch>", "base branch for --diff (default: from config)")
43
+ .action(visualize_js_1.visualizeAction);
44
+ program
45
+ .command("shared-modules")
46
+ .description("find node_modules packages bundled across multiple Lambda functions")
47
+ .option("--json", "output raw JSON")
48
+ .option("--top <n>", "show only the top N modules", "20")
49
+ .action(shared_modules_js_1.sharedModulesAction);
50
+ program.parseAsync().catch((err) => {
51
+ console.error("Error:", err instanceof Error ? err.message : err);
52
+ process.exit(1);
53
+ });
54
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAA2C;AAC3C,sDAAqD;AACrD,oEAAkE;AAClE,kDAAiD;AACjD,0DAAyD;AAEzD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE;KAC3B,IAAI,CAAC,qBAAqB,CAAC;KAC3B,WAAW,CACX,wEAAwE,CACxE,CAAA;AAEF,OAAO;KACL,OAAO,CAAC,SAAS,CAAC;KAClB,WAAW,CAAC,+DAA+D,CAAC;KAC5E,MAAM,CAAC,iBAAiB,EAAE,gCAAgC,CAAC;KAC3D,MAAM,CAAC,OAAO,EAAE,2DAA2D,CAAC;KAC5E,MAAM,CAAC,WAAW,EAAE,6CAA6C,CAAC;KAClE,MAAM,CAAC,QAAQ,EAAE,iCAAiC,CAAC;KACnD,MAAM,CACN,qBAAqB,EACrB,2DAA2D,EAC3D,GAAG,CACH;KACA,MAAM,CACN,sBAAsB,EACtB,iEAAiE,CACjE;KACA,MAAM,CAAC,0BAAa,CAAC,CAAA;AAEvB,OAAO;KACL,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,8DAA8D,CAAC;KAC3E,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;KACnC,SAAS,CACT,IAAI,kBAAM,CAAC,gBAAgB,EAAE,YAAY,CAAC;KACxC,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAU,CAAC;KAClC,OAAO,CAAC,MAAM,CAAC,CACjB;KACA,MAAM,CAAC,sBAAW,CAAC,CAAA;AAErB,OAAO;KACL,OAAO,CAAC,WAAW,CAAC;KACpB,WAAW,CACX,iEAAiE,CACjE;KACA,QAAQ,CAAC,eAAe,EAAE,2BAA2B,CAAC;KACtD,SAAS,CACT,IAAI,kBAAM,CAAC,mBAAmB,EAAE,oBAAoB,CAAC;KACnD,OAAO,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,SAAS,CAAU,CAAC;KACpD,OAAO,CAAC,SAAS,CAAC,CACpB;KACA,MAAM,CAAC,kBAAkB,EAAE,6CAA6C,CAAC;KACzE,MAAM,CAAC,WAAW,EAAE,qDAAqD,CAAC;KAC1E,MAAM,CACN,iBAAiB,EACjB,uDAAuD,CACvD;KACA,MAAM,CAAC,WAAW,EAAE,iCAAiC,CAAC;KACtD,MAAM,CAAC,QAAQ,EAAE,2CAA2C,CAAC;KAC7D,MAAM,CAAC,iBAAiB,EAAE,+CAA+C,CAAC;KAC1E,MAAM,CAAC,8BAAe,CAAC,CAAA;AAEzB,OAAO;KACL,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CACX,qEAAqE,CACrE;KACA,MAAM,CAAC,QAAQ,EAAE,iBAAiB,CAAC;KACnC,MAAM,CAAC,WAAW,EAAE,6BAA6B,EAAE,IAAI,CAAC;KACxD,MAAM,CAAC,uCAAmB,CAAC,CAAA;AAE7B,OAAO,CAAC,UAAU,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC3C,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,10 @@
1
+ export interface CompareOpts {
2
+ base?: string;
3
+ all?: boolean;
4
+ verbose?: boolean;
5
+ json?: boolean;
6
+ threshold: string;
7
+ failAbove?: string;
8
+ }
9
+ export declare function compareAction(opts: CompareOpts): Promise<void>;
10
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../../src/commands/compare.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,WAAW;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyGpE"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.compareAction = compareAction;
4
+ const node_path_1 = require("node:path");
5
+ const compare_js_1 = require("../compare.js");
6
+ const config_js_1 = require("../config.js");
7
+ const dependency_graph_js_1 = require("../dependency-graph.js");
8
+ const parse_serverless_js_1 = require("../parse-serverless.js");
9
+ const report_js_1 = require("../report.js");
10
+ async function compareAction(opts) {
11
+ const cwd = process.cwd();
12
+ const config = (0, config_js_1.loadConfig)(cwd);
13
+ const base = opts.base ?? config.base;
14
+ const all = opts.all === true;
15
+ const verbose = opts.verbose === true;
16
+ const json = opts.json === true;
17
+ const threshold = parseInt(opts.threshold, 10);
18
+ const failAbove = opts.failAbove ? parseInt(opts.failAbove, 10) : undefined;
19
+ // Step 1: Parse serverless files
20
+ process.stderr.write("Parsing serverless files...\n");
21
+ const parseResult = (0, parse_serverless_js_1.parseServerlessHandlers)(cwd, config.exclude);
22
+ if (parseResult.entries.size === 0) {
23
+ console.log("No serverless handler entry points found.");
24
+ return;
25
+ }
26
+ process.stderr.write(`Found ${parseResult.totalFunctions} functions (${parseResult.entries.size} unique entry points)\n`);
27
+ // Step 2: Build dependency graph
28
+ process.stderr.write("Building dependency graph...\n");
29
+ const graph = await (0, dependency_graph_js_1.buildDependencyGraph)(parseResult, config, cwd);
30
+ // Step 3: Determine affected entry points
31
+ const repoRoot = (0, compare_js_1.getRepoRoot)(cwd);
32
+ const changedFiles = (0, compare_js_1.getChangedFiles)(base, repoRoot);
33
+ const cwdRelative = (0, node_path_1.relative)(repoRoot, cwd);
34
+ // Filter changed files to those relevant to this service directory
35
+ const relevantChangedFiles = changedFiles.filter((f) => f.startsWith(`${cwdRelative}/`) || !cwdRelative);
36
+ let affectedEntryPoints;
37
+ if (all) {
38
+ affectedEntryPoints = new Set(Array.from(parseResult.entries.keys()).map((fp) => (0, node_path_1.relative)(cwd, fp)));
39
+ }
40
+ else {
41
+ // Changed files in the dependency graph are relative to cwd (how esbuild reports them)
42
+ // But git diff returns paths relative to repo root
43
+ // We need to match them — the reverse map keys are relative to cwd (esbuild's absWorkingDir)
44
+ affectedEntryPoints = (0, dependency_graph_js_1.getAffectedEntryPoints)(changedFiles, graph.reverseMap);
45
+ // Also check with paths relative to cwd
46
+ const cwdRelativeChangedFiles = relevantChangedFiles.map((f) => (0, node_path_1.relative)(cwdRelative, f));
47
+ const moreAffected = (0, dependency_graph_js_1.getAffectedEntryPoints)(cwdRelativeChangedFiles, graph.reverseMap);
48
+ for (const ep of moreAffected) {
49
+ affectedEntryPoints.add(ep);
50
+ }
51
+ }
52
+ if (affectedEntryPoints.size === 0) {
53
+ console.log("No affected functions — bundle sizes unchanged.");
54
+ return;
55
+ }
56
+ process.stderr.write(`${affectedEntryPoints.size} affected entry points, comparing against ${base}...\n`);
57
+ // Step 4: Compare bundles
58
+ const comparison = await (0, compare_js_1.compareBundles)(affectedEntryPoints, config, cwd);
59
+ // Step 5: Report
60
+ const reportData = (0, report_js_1.buildReportData)(comparison, relevantChangedFiles.length, parseResult.totalFunctions, cwd);
61
+ const reportOptions = {
62
+ verbose,
63
+ json,
64
+ threshold,
65
+ cwd,
66
+ };
67
+ if (json) {
68
+ console.log((0, report_js_1.formatJsonReport)(reportData));
69
+ }
70
+ else {
71
+ console.log((0, report_js_1.formatTextReport)(reportData, reportOptions));
72
+ }
73
+ // Step 6: Fail if any function grew more than the limit
74
+ if (failAbove != null) {
75
+ const exceeded = reportData.functions.some((f) => f.deltaBytes > failAbove);
76
+ if (exceeded) {
77
+ process.stderr.write(`One or more functions grew by more than ${failAbove} bytes.\n`);
78
+ process.exit(1);
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=compare.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.js","sourceRoot":"","sources":["../../src/commands/compare.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export interface SharedModulesOpts {
2
+ json?: boolean;
3
+ top: string;
4
+ }
5
+ export declare function sharedModulesAction(opts: SharedModulesOpts): Promise<void>;
6
+ //# sourceMappingURL=shared-modules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-modules.d.ts","sourceRoot":"","sources":["../../src/commands/shared-modules.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,iBAAiB;IACjC,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACX;AAED,wBAAsB,mBAAmB,CACxC,IAAI,EAAE,iBAAiB,GACrB,OAAO,CAAC,IAAI,CAAC,CA0Bf"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sharedModulesAction = sharedModulesAction;
4
+ const config_js_1 = require("../config.js");
5
+ const parse_serverless_js_1 = require("../parse-serverless.js");
6
+ const shared_modules_js_1 = require("../shared-modules.js");
7
+ async function sharedModulesAction(opts) {
8
+ const cwd = process.cwd();
9
+ const config = (0, config_js_1.loadConfig)(cwd);
10
+ process.stderr.write("Parsing serverless files...\n");
11
+ const parseResult = (0, parse_serverless_js_1.parseServerlessHandlers)(cwd, config.exclude);
12
+ if (parseResult.entries.size === 0) {
13
+ console.log("No serverless handler entry points found.");
14
+ return;
15
+ }
16
+ process.stderr.write(`Found ${parseResult.totalFunctions} functions (${parseResult.entries.size} unique entry points)\n`);
17
+ process.stderr.write("Analysing shared modules...\n");
18
+ const result = await (0, shared_modules_js_1.analyzeSharedModules)(parseResult, config, cwd);
19
+ const top = parseInt(opts.top, 10);
20
+ if (opts.json) {
21
+ console.log((0, shared_modules_js_1.formatSharedModulesJson)(result, top));
22
+ }
23
+ else {
24
+ console.log((0, shared_modules_js_1.formatSharedModulesText)(result, top));
25
+ }
26
+ }
27
+ //# sourceMappingURL=shared-modules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-modules.js","sourceRoot":"","sources":["../../src/commands/shared-modules.ts"],"names":[],"mappings":";;AAaA,kDA4BC;AAzCD,4CAAyC;AACzC,gEAAgE;AAChE,4DAI6B;AAOtB,KAAK,UAAU,mBAAmB,CACxC,IAAuB;IAEvB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,MAAM,MAAM,GAAG,IAAA,sBAAU,EAAC,GAAG,CAAC,CAAA;IAE9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;IACrD,MAAM,WAAW,GAAG,IAAA,6CAAuB,EAAC,GAAG,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;IAEhE,IAAI,WAAW,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;QACxD,OAAM;IACP,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,SAAS,WAAW,CAAC,cAAc,eAAe,WAAW,CAAC,OAAO,CAAC,IAAI,yBAAyB,CACnG,CAAA;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;IACrD,MAAM,MAAM,GAAG,MAAM,IAAA,wCAAoB,EAAC,WAAW,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IAEnE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAElC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,OAAO,CAAC,GAAG,CAAC,IAAA,2CAAuB,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;IAClD,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,IAAA,2CAAuB,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;IAClD,CAAC;AACF,CAAC"}
@@ -0,0 +1,6 @@
1
+ export interface SizesOpts {
2
+ json?: boolean;
3
+ sort: string;
4
+ }
5
+ export declare function sizesAction(opts: SizesOpts): Promise<void>;
6
+ //# sourceMappingURL=sizes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sizes.d.ts","sourceRoot":"","sources":["../../src/commands/sizes.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,SAAS;IACzB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;CACZ;AA6CD,wBAAsB,WAAW,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA4ChE"}
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sizesAction = sizesAction;
4
+ const node_path_1 = require("node:path");
5
+ const compare_js_1 = require("../compare.js");
6
+ const config_js_1 = require("../config.js");
7
+ const parse_serverless_js_1 = require("../parse-serverless.js");
8
+ const bold = (s) => `\x1b[1m${s}\x1b[0m`;
9
+ function formatBytes(bytes) {
10
+ if (bytes < 1024)
11
+ return `${bytes} B`;
12
+ if (bytes < 1024 * 1024)
13
+ return `${(bytes / 1024).toFixed(1)} KB`;
14
+ return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
15
+ }
16
+ function formatSizesText(functions, total) {
17
+ const lines = [];
18
+ lines.push(bold(`Bundle sizes — ${functions.length} of ${total} functions`));
19
+ lines.push("=".repeat(60));
20
+ if (functions.length === 0) {
21
+ lines.push("No functions found.");
22
+ return lines.join("\n");
23
+ }
24
+ const nameWidth = Math.max(30, ...functions.map((f) => f.entryPoint.length));
25
+ lines.push(` ${"Function".padEnd(nameWidth)} ${"Size".padStart(10)}`);
26
+ lines.push(` ${"─".repeat(nameWidth)} ${"─".repeat(10)}`);
27
+ for (const fn of functions) {
28
+ lines.push(` ${fn.entryPoint.padEnd(nameWidth)} ${formatBytes(fn.bytes).padStart(10)}`);
29
+ }
30
+ const totalBytes = functions.reduce((sum, f) => sum + f.bytes, 0);
31
+ lines.push("");
32
+ lines.push(` ${"Total".padEnd(nameWidth)} ${formatBytes(totalBytes).padStart(10)}`);
33
+ return lines.join("\n");
34
+ }
35
+ async function sizesAction(opts) {
36
+ const cwd = process.cwd();
37
+ const config = (0, config_js_1.loadConfig)(cwd);
38
+ process.stderr.write("Parsing serverless files...\n");
39
+ const parseResult = (0, parse_serverless_js_1.parseServerlessHandlers)(cwd, config.exclude);
40
+ if (parseResult.entries.size === 0) {
41
+ console.log("No serverless handler entry points found.");
42
+ return;
43
+ }
44
+ process.stderr.write(`Found ${parseResult.totalFunctions} functions (${parseResult.entries.size} unique entry points)\n`);
45
+ // Build entry points map
46
+ const entryPoints = {};
47
+ for (const [absPath] of parseResult.entries) {
48
+ const rel = (0, node_path_1.relative)(cwd, absPath);
49
+ entryPoints[rel] = (0, node_path_1.join)(cwd, rel);
50
+ }
51
+ process.stderr.write("Bundling...\n");
52
+ const sizes = await (0, compare_js_1.bundleAndMeasure)(entryPoints, config, cwd);
53
+ const functions = Array.from(sizes.entries()).map(([ep, size]) => ({
54
+ entryPoint: ep,
55
+ bytes: size.bytes,
56
+ }));
57
+ if (opts.sort === "name") {
58
+ functions.sort((a, b) => a.entryPoint.localeCompare(b.entryPoint));
59
+ }
60
+ else {
61
+ functions.sort((a, b) => b.bytes - a.bytes);
62
+ }
63
+ if (opts.json) {
64
+ console.log(JSON.stringify({ functions }, null, 2));
65
+ }
66
+ else {
67
+ console.log(formatSizesText(functions, parseResult.totalFunctions));
68
+ }
69
+ }
70
+ //# sourceMappingURL=sizes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sizes.js","sourceRoot":"","sources":["../../src/commands/sizes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface VisualizeOpts {
2
+ template: string;
3
+ thirdParty: boolean;
4
+ open: boolean;
5
+ output?: string;
6
+ top?: string;
7
+ diff?: boolean;
8
+ base?: string;
9
+ }
10
+ export declare function visualizeAction(entryPoint: string, opts: VisualizeOpts): Promise<void>;
11
+ //# sourceMappingURL=visualize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualize.d.ts","sourceRoot":"","sources":["../../src/commands/visualize.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;IACnB,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;CACb;AAED,wBAAsB,eAAe,CACpC,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,aAAa,GACjB,OAAO,CAAC,IAAI,CAAC,CAkCf"}
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.visualizeAction = visualizeAction;
4
+ const config_js_1 = require("../config.js");
5
+ const visualize_js_1 = require("../visualize.js");
6
+ async function visualizeAction(entryPoint, opts) {
7
+ const cwd = process.cwd();
8
+ const config = (0, config_js_1.loadConfig)(cwd);
9
+ const vizOptions = {
10
+ template: opts.template,
11
+ excludeThirdParty: !opts.thirdParty,
12
+ top: opts.top ? parseInt(opts.top, 10) : undefined,
13
+ outputPath: opts.output,
14
+ open: opts.open,
15
+ };
16
+ if (opts.diff) {
17
+ const base = opts.base ?? config.base;
18
+ process.stderr.write(`Bundling ${entryPoint} (current vs ${base})...\n`);
19
+ const { currentPath, basePath } = await (0, visualize_js_1.visualizeDiff)(entryPoint, config, cwd, base, vizOptions);
20
+ process.stderr.write(`Current: ${currentPath}\n`);
21
+ process.stderr.write(`Base: ${basePath}\n`);
22
+ }
23
+ else {
24
+ process.stderr.write(`Bundling ${entryPoint}...\n`);
25
+ const outPath = await (0, visualize_js_1.visualizeEntryPoint)(entryPoint, config, cwd, vizOptions);
26
+ process.stderr.write(`Written to ${outPath}\n`);
27
+ }
28
+ }
29
+ //# sourceMappingURL=visualize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visualize.js","sourceRoot":"","sources":["../../src/commands/visualize.ts"],"names":[],"mappings":";;AAiBA,0CAqCC;AAtDD,4CAAyC;AACzC,kDAIwB;AAYjB,KAAK,UAAU,eAAe,CACpC,UAAkB,EAClB,IAAmB;IAEnB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IACzB,MAAM,MAAM,GAAG,IAAA,sBAAU,EAAC,GAAG,CAAC,CAAA;IAE9B,MAAM,UAAU,GAAqB;QACpC,QAAQ,EAAE,IAAI,CAAC,QAA8C;QAC7D,iBAAiB,EAAE,CAAC,IAAI,CAAC,UAAU;QACnC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;QAClD,UAAU,EAAE,IAAI,CAAC,MAAM;QACvB,IAAI,EAAE,IAAI,CAAC,IAAI;KACf,CAAA;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,CAAA;QACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,UAAU,gBAAgB,IAAI,QAAQ,CAAC,CAAA;QACxE,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAA,4BAAa,EACpD,UAAU,EACV,MAAM,EACN,GAAG,EACH,IAAI,EACJ,UAAU,CACV,CAAA;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,WAAW,IAAI,CAAC,CAAA;QACjD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,QAAQ,IAAI,CAAC,CAAA;IAC/C,CAAC;SAAM,CAAC;QACP,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,YAAY,UAAU,OAAO,CAAC,CAAA;QACnD,MAAM,OAAO,GAAG,MAAM,IAAA,kCAAmB,EACxC,UAAU,EACV,MAAM,EACN,GAAG,EACH,UAAU,CACV,CAAA;QACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,cAAc,OAAO,IAAI,CAAC,CAAA;IAChD,CAAC;AACF,CAAC"}
@@ -0,0 +1,47 @@
1
+ import { type Metafile } from "esbuild";
2
+ import type { BundleAnalyserConfig } from "./config.js";
3
+ export interface BundleSize {
4
+ /** Total output bytes for this entry point */
5
+ bytes: number;
6
+ /** Per-input-module sizes */
7
+ modules: Map<string, number>;
8
+ }
9
+ export interface ComparisonResult {
10
+ /** Entry point key (relative path) -> sizes on current branch */
11
+ current: Map<string, BundleSize>;
12
+ /** Entry point key (relative path) -> sizes on base branch (missing = new function) */
13
+ base: Map<string, BundleSize>;
14
+ /** Entry points that exist on branch but not on base */
15
+ newEntryPoints: Set<string>;
16
+ /** Entry points that exist on base but not on branch */
17
+ removedEntryPoints: Set<string>;
18
+ }
19
+ /**
20
+ * Get files changed between the base branch and HEAD.
21
+ * Returns paths relative to the repo root.
22
+ */
23
+ export declare function getChangedFiles(base: string, repoRoot: string): string[];
24
+ /**
25
+ * Find the root of the git repository.
26
+ */
27
+ export declare function getRepoRoot(cwd: string): string;
28
+ /**
29
+ * Bundle the specified entry points and return their sizes from the metafile.
30
+ * Batches entry points to avoid overwhelming esbuild's IPC.
31
+ */
32
+ export declare function bundleAndMeasure(entryPoints: Record<string, string>, config: BundleAnalyserConfig, cwd: string): Promise<Map<string, BundleSize>>;
33
+ export declare function extractSizes(metafile: Metafile): Map<string, BundleSize>;
34
+ /**
35
+ * Compare bundle sizes between the current branch and the base branch.
36
+ *
37
+ * Uses git worktree to checkout the base branch without disturbing the working directory.
38
+ */
39
+ export declare function compareBundles(affectedEntryPoints: Set<string>, config: BundleAnalyserConfig, cwd: string): Promise<ComparisonResult>;
40
+ /**
41
+ * Run a function against a git worktree checked out at the given branch.
42
+ *
43
+ * Creates a temporary worktree, symlinks node_modules, calls `fn` with the
44
+ * worktree-equivalent of `cwd`, and cleans up afterwards.
45
+ */
46
+ export declare function withWorktree<T>(branch: string, cwd: string, fn: (worktreeCwd: string) => Promise<T>): Promise<T>;
47
+ //# sourceMappingURL=compare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare.d.ts","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGvD,MAAM,WAAW,UAAU;IAC1B,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAA;IACb,6BAA6B;IAC7B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAChC,iEAAiE;IACjE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAChC,uFAAuF;IACvF,IAAI,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IAC7B,wDAAwD;IACxD,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;IAC3B,wDAAwD;IACxD,kBAAkB,EAAE,GAAG,CAAC,MAAM,CAAC,CAAA;CAC/B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAcxE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK/C;AAID;;;GAGG;AACH,wBAAsB,gBAAgB,CACrC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CA4BlC;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAgBxE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CACnC,mBAAmB,EAAE,GAAG,CAAC,MAAM,CAAC,EAChC,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,gBAAgB,CAAC,CAyB3B;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,CAAC,EACnC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,MAAM,EACX,EAAE,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,CAAC,CAAC,CA4BZ"}