@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.
- package/LICENSE.md +21 -0
- package/README.md +126 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +54 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/compare.d.ts +10 -0
- package/dist/commands/compare.d.ts.map +1 -0
- package/dist/commands/compare.js +82 -0
- package/dist/commands/compare.js.map +1 -0
- package/dist/commands/shared-modules.d.ts +6 -0
- package/dist/commands/shared-modules.d.ts.map +1 -0
- package/dist/commands/shared-modules.js +27 -0
- package/dist/commands/shared-modules.js.map +1 -0
- package/dist/commands/sizes.d.ts +6 -0
- package/dist/commands/sizes.d.ts.map +1 -0
- package/dist/commands/sizes.js +70 -0
- package/dist/commands/sizes.js.map +1 -0
- package/dist/commands/visualize.d.ts +11 -0
- package/dist/commands/visualize.d.ts.map +1 -0
- package/dist/commands/visualize.js +29 -0
- package/dist/commands/visualize.js.map +1 -0
- package/dist/compare.d.ts +47 -0
- package/dist/compare.d.ts.map +1 -0
- package/dist/compare.js +181 -0
- package/dist/compare.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +35 -0
- package/dist/config.js.map +1 -0
- package/dist/dependency-graph.d.ts +29 -0
- package/dist/dependency-graph.d.ts.map +1 -0
- package/dist/dependency-graph.js +87 -0
- package/dist/dependency-graph.js.map +1 -0
- package/dist/esbuild-config.d.ts +4 -0
- package/dist/esbuild-config.d.ts.map +1 -0
- package/dist/esbuild-config.js +20 -0
- package/dist/esbuild-config.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/parse-serverless.d.ts +53 -0
- package/dist/parse-serverless.d.ts.map +1 -0
- package/dist/parse-serverless.js +195 -0
- package/dist/parse-serverless.js.map +1 -0
- package/dist/report.d.ts +36 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +154 -0
- package/dist/report.js.map +1 -0
- package/dist/shared-modules.d.ts +17 -0
- package/dist/shared-modules.d.ts.map +1 -0
- package/dist/shared-modules.js +104 -0
- package/dist/shared-modules.js.map +1 -0
- package/dist/visualize.d.ts +20 -0
- package/dist/visualize.d.ts.map +1 -0
- package/dist/visualize.js +139 -0
- package/dist/visualize.js.map +1 -0
- package/package.json +53 -0
package/dist/compare.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getChangedFiles = getChangedFiles;
|
|
4
|
+
exports.getRepoRoot = getRepoRoot;
|
|
5
|
+
exports.bundleAndMeasure = bundleAndMeasure;
|
|
6
|
+
exports.extractSizes = extractSizes;
|
|
7
|
+
exports.compareBundles = compareBundles;
|
|
8
|
+
exports.withWorktree = withWorktree;
|
|
9
|
+
const node_child_process_1 = require("node:child_process");
|
|
10
|
+
const node_fs_1 = require("node:fs");
|
|
11
|
+
const node_os_1 = require("node:os");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
const esbuild_1 = require("esbuild");
|
|
14
|
+
const esbuild_config_js_1 = require("./esbuild-config.js");
|
|
15
|
+
/**
|
|
16
|
+
* Get files changed between the base branch and HEAD.
|
|
17
|
+
* Returns paths relative to the repo root.
|
|
18
|
+
*/
|
|
19
|
+
function getChangedFiles(base, repoRoot) {
|
|
20
|
+
try {
|
|
21
|
+
const output = (0, node_child_process_1.execSync)(`git diff --name-only ${base}...HEAD`, {
|
|
22
|
+
cwd: repoRoot,
|
|
23
|
+
encoding: "utf-8",
|
|
24
|
+
});
|
|
25
|
+
return output
|
|
26
|
+
.trim()
|
|
27
|
+
.split("\n")
|
|
28
|
+
.filter((f) => f.length > 0);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// If the base branch doesn't exist or there's no common ancestor, return empty
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Find the root of the git repository.
|
|
37
|
+
*/
|
|
38
|
+
function getRepoRoot(cwd) {
|
|
39
|
+
return (0, node_child_process_1.execSync)("git rev-parse --show-toplevel", {
|
|
40
|
+
cwd,
|
|
41
|
+
encoding: "utf-8",
|
|
42
|
+
}).trim();
|
|
43
|
+
}
|
|
44
|
+
const BATCH_SIZE = 10;
|
|
45
|
+
/**
|
|
46
|
+
* Bundle the specified entry points and return their sizes from the metafile.
|
|
47
|
+
* Batches entry points to avoid overwhelming esbuild's IPC.
|
|
48
|
+
*/
|
|
49
|
+
async function bundleAndMeasure(entryPoints, config, cwd) {
|
|
50
|
+
const keys = Object.keys(entryPoints);
|
|
51
|
+
if (keys.length === 0) {
|
|
52
|
+
return new Map();
|
|
53
|
+
}
|
|
54
|
+
const allSizes = new Map();
|
|
55
|
+
for (let i = 0; i < keys.length; i += BATCH_SIZE) {
|
|
56
|
+
const batchKeys = keys.slice(i, i + BATCH_SIZE);
|
|
57
|
+
const batch = {};
|
|
58
|
+
for (const key of batchKeys) {
|
|
59
|
+
batch[key] = entryPoints[key];
|
|
60
|
+
}
|
|
61
|
+
const options = (0, esbuild_config_js_1.buildEsbuildOptions)(batch, config);
|
|
62
|
+
const result = await (0, esbuild_1.build)({ ...options, absWorkingDir: cwd });
|
|
63
|
+
if (!result.metafile) {
|
|
64
|
+
throw new Error("esbuild did not produce a metafile");
|
|
65
|
+
}
|
|
66
|
+
for (const [k, v] of extractSizes(result.metafile)) {
|
|
67
|
+
allSizes.set(k, v);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return allSizes;
|
|
71
|
+
}
|
|
72
|
+
function extractSizes(metafile) {
|
|
73
|
+
const sizes = new Map();
|
|
74
|
+
for (const [, outputMeta] of Object.entries(metafile.outputs)) {
|
|
75
|
+
const { entryPoint } = outputMeta;
|
|
76
|
+
if (entryPoint) {
|
|
77
|
+
const modules = new Map();
|
|
78
|
+
for (const [inputPath, inputMeta] of Object.entries(outputMeta.inputs)) {
|
|
79
|
+
modules.set(inputPath, inputMeta.bytesInOutput);
|
|
80
|
+
}
|
|
81
|
+
sizes.set(entryPoint, { bytes: outputMeta.bytes, modules });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return sizes;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Compare bundle sizes between the current branch and the base branch.
|
|
88
|
+
*
|
|
89
|
+
* Uses git worktree to checkout the base branch without disturbing the working directory.
|
|
90
|
+
*/
|
|
91
|
+
async function compareBundles(affectedEntryPoints, config, cwd) {
|
|
92
|
+
// Build entry points map for affected functions
|
|
93
|
+
const entryPoints = {};
|
|
94
|
+
for (const ep of affectedEntryPoints) {
|
|
95
|
+
entryPoints[ep] = (0, node_path_1.join)(cwd, ep);
|
|
96
|
+
}
|
|
97
|
+
// Bundle on current branch
|
|
98
|
+
const current = await bundleAndMeasure(entryPoints, config, cwd);
|
|
99
|
+
// Bundle on base branch using git worktree
|
|
100
|
+
const base = await bundleOnBase(affectedEntryPoints, config, cwd, config.base);
|
|
101
|
+
// Determine new and removed entry points
|
|
102
|
+
const newEntryPoints = new Set();
|
|
103
|
+
const removedEntryPoints = new Set();
|
|
104
|
+
for (const ep of current.keys()) {
|
|
105
|
+
if (!base.has(ep))
|
|
106
|
+
newEntryPoints.add(ep);
|
|
107
|
+
}
|
|
108
|
+
for (const ep of base.keys()) {
|
|
109
|
+
if (!current.has(ep))
|
|
110
|
+
removedEntryPoints.add(ep);
|
|
111
|
+
}
|
|
112
|
+
return { current, base, newEntryPoints, removedEntryPoints };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Run a function against a git worktree checked out at the given branch.
|
|
116
|
+
*
|
|
117
|
+
* Creates a temporary worktree, symlinks node_modules, calls `fn` with the
|
|
118
|
+
* worktree-equivalent of `cwd`, and cleans up afterwards.
|
|
119
|
+
*/
|
|
120
|
+
async function withWorktree(branch, cwd, fn) {
|
|
121
|
+
const repoRoot = getRepoRoot(cwd);
|
|
122
|
+
const cwdRelative = (0, node_path_1.relative)(repoRoot, cwd);
|
|
123
|
+
const worktreePath = (0, node_path_1.join)((0, node_os_1.tmpdir)(), `sls-bundle-analyser-${Date.now()}`);
|
|
124
|
+
try {
|
|
125
|
+
(0, node_child_process_1.execSync)(`git worktree add "${worktreePath}" "${branch}" --detach`, {
|
|
126
|
+
cwd: repoRoot,
|
|
127
|
+
encoding: "utf-8",
|
|
128
|
+
stdio: "pipe",
|
|
129
|
+
});
|
|
130
|
+
const worktreeCwd = (0, node_path_1.join)(worktreePath, cwdRelative);
|
|
131
|
+
symlinkNodeModules(cwd, worktreeCwd, repoRoot, worktreePath);
|
|
132
|
+
return await fn(worktreeCwd);
|
|
133
|
+
}
|
|
134
|
+
finally {
|
|
135
|
+
try {
|
|
136
|
+
(0, node_child_process_1.execSync)(`git worktree remove "${worktreePath}" --force`, {
|
|
137
|
+
cwd: repoRoot,
|
|
138
|
+
encoding: "utf-8",
|
|
139
|
+
stdio: "pipe",
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
// Best effort cleanup
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
async function bundleOnBase(entryPoints, config, cwd, branch) {
|
|
148
|
+
return withWorktree(branch, cwd, async (worktreeCwd) => {
|
|
149
|
+
const worktreeEntryPoints = {};
|
|
150
|
+
for (const ep of entryPoints) {
|
|
151
|
+
const worktreeFile = (0, node_path_1.join)(worktreeCwd, ep);
|
|
152
|
+
if ((0, node_fs_1.existsSync)(worktreeFile)) {
|
|
153
|
+
worktreeEntryPoints[ep] = worktreeFile;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return bundleAndMeasure(worktreeEntryPoints, config, worktreeCwd);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Symlink node_modules directories so the worktree can resolve dependencies
|
|
161
|
+
* without running npm install.
|
|
162
|
+
*
|
|
163
|
+
* We symlink both the service-level node_modules and the repo root node_modules
|
|
164
|
+
* since some packages may be hoisted.
|
|
165
|
+
*/
|
|
166
|
+
function symlinkNodeModules(cwd, worktreeCwd, repoRoot, worktreePath) {
|
|
167
|
+
// Service-level node_modules
|
|
168
|
+
const srcModules = (0, node_path_1.join)(cwd, "node_modules");
|
|
169
|
+
const destModules = (0, node_path_1.join)(worktreeCwd, "node_modules");
|
|
170
|
+
if ((0, node_fs_1.existsSync)(srcModules) && !(0, node_fs_1.existsSync)(destModules)) {
|
|
171
|
+
(0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(destModules), { recursive: true });
|
|
172
|
+
(0, node_fs_1.symlinkSync)(srcModules, destModules, "dir");
|
|
173
|
+
}
|
|
174
|
+
// Root-level node_modules (for hoisted packages)
|
|
175
|
+
const rootSrcModules = (0, node_path_1.join)(repoRoot, "node_modules");
|
|
176
|
+
const rootDestModules = (0, node_path_1.join)(worktreePath, "node_modules");
|
|
177
|
+
if ((0, node_fs_1.existsSync)(rootSrcModules) && !(0, node_fs_1.existsSync)(rootDestModules)) {
|
|
178
|
+
(0, node_fs_1.symlinkSync)(rootSrcModules, rootDestModules, "dir");
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=compare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compare.js","sourceRoot":"","sources":["../src/compare.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BuildOptions } from "esbuild";
|
|
2
|
+
export interface BundleAnalyserConfig {
|
|
3
|
+
/** Glob patterns for serverless files to exclude */
|
|
4
|
+
exclude: string[];
|
|
5
|
+
/** esbuild BuildOptions overrides merged with defaults */
|
|
6
|
+
esbuild: Partial<BuildOptions>;
|
|
7
|
+
/** Base branch to compare against */
|
|
8
|
+
base: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function loadConfig(cwd: string): BundleAnalyserConfig;
|
|
11
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAE3C,MAAM,WAAW,oBAAoB;IACpC,oDAAoD;IACpD,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,0DAA0D;IAC1D,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAA;CACZ;AAQD,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAiC5D"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadConfig = loadConfig;
|
|
4
|
+
const node_fs_1 = require("node:fs");
|
|
5
|
+
const node_path_1 = require("node:path");
|
|
6
|
+
const DEFAULT_CONFIG = {
|
|
7
|
+
exclude: ["serverless.local-*.yml"],
|
|
8
|
+
esbuild: {},
|
|
9
|
+
base: "main",
|
|
10
|
+
};
|
|
11
|
+
function loadConfig(cwd) {
|
|
12
|
+
const configPath = (0, node_path_1.join)(cwd, ".bundle-analyser.json");
|
|
13
|
+
if ((0, node_fs_1.existsSync)(configPath)) {
|
|
14
|
+
const raw = JSON.parse((0, node_fs_1.readFileSync)(configPath, "utf-8"));
|
|
15
|
+
return {
|
|
16
|
+
exclude: raw.exclude ?? DEFAULT_CONFIG.exclude,
|
|
17
|
+
esbuild: { ...DEFAULT_CONFIG.esbuild, ...raw.esbuild },
|
|
18
|
+
base: raw.base ?? DEFAULT_CONFIG.base,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
const pkgPath = (0, node_path_1.join)(cwd, "package.json");
|
|
22
|
+
if ((0, node_fs_1.existsSync)(pkgPath)) {
|
|
23
|
+
const pkg = JSON.parse((0, node_fs_1.readFileSync)(pkgPath, "utf-8"));
|
|
24
|
+
const raw = pkg["bundle-analyser"];
|
|
25
|
+
if (raw) {
|
|
26
|
+
return {
|
|
27
|
+
exclude: raw.exclude ?? DEFAULT_CONFIG.exclude,
|
|
28
|
+
esbuild: { ...DEFAULT_CONFIG.esbuild, ...raw.esbuild },
|
|
29
|
+
base: raw.base ?? DEFAULT_CONFIG.base,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { ...DEFAULT_CONFIG };
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAmBA,gCAiCC;AApDD,qCAAkD;AAClD,yCAAgC;AAYhC,MAAM,cAAc,GAAyB;IAC5C,OAAO,EAAE,CAAC,wBAAwB,CAAC;IACnC,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,MAAM;CACZ,CAAA;AAED,SAAgB,UAAU,CAAC,GAAW;IACrC,MAAM,UAAU,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,uBAAuB,CAAC,CAAA;IAErD,IAAI,IAAA,oBAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CACrB,IAAA,sBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CACA,CAAA;QAClC,OAAO;YACN,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;YAC9C,OAAO,EAAE,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;YACtD,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI;SACrC,CAAA;IACF,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,gBAAI,EAAC,GAAG,EAAE,cAAc,CAAC,CAAA;IACzC,IAAI,IAAA,oBAAU,EAAC,OAAO,CAAC,EAAE,CAAC;QACzB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,OAAO,EAAE,OAAO,CAAC,CAGpD,CAAA;QACD,MAAM,GAAG,GAAG,GAAG,CAAC,iBAAiB,CAErB,CAAA;QACZ,IAAI,GAAG,EAAE,CAAC;YACT,OAAO;gBACN,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,cAAc,CAAC,OAAO;gBAC9C,OAAO,EAAE,EAAE,GAAG,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,OAAO,EAAE;gBACtD,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI;aACrC,CAAA;QACF,CAAC;IACF,CAAC;IAED,OAAO,EAAE,GAAG,cAAc,EAAE,CAAA;AAC7B,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Metafile } from "esbuild";
|
|
2
|
+
import type { BundleAnalyserConfig } from "./config.js";
|
|
3
|
+
import type { ParseResult } from "./parse-serverless.js";
|
|
4
|
+
export interface DependencyGraph {
|
|
5
|
+
/** For each source file (relative to cwd), which entry point keys depend on it */
|
|
6
|
+
reverseMap: Map<string, Set<string>>;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build a reverse dependency map using esbuild's metafile.
|
|
10
|
+
*
|
|
11
|
+
* Batches entry points to avoid overwhelming esbuild's IPC with huge metafiles.
|
|
12
|
+
*/
|
|
13
|
+
export declare function buildDependencyGraph(parseResult: ParseResult, config: BundleAnalyserConfig, cwd: string): Promise<DependencyGraph>;
|
|
14
|
+
/**
|
|
15
|
+
* Extract reverse dependency info from a metafile and merge into an existing map.
|
|
16
|
+
*
|
|
17
|
+
* esbuild's metafile.outputs has entries like:
|
|
18
|
+
* "dist/src/handlers/foo.js": { entryPoint: "src/handlers/foo.ts", inputs: { "src/services/bar.ts": ... } }
|
|
19
|
+
*
|
|
20
|
+
* We invert this to get:
|
|
21
|
+
* "src/services/bar.ts" -> Set(["src/handlers/foo.ts"])
|
|
22
|
+
*/
|
|
23
|
+
export declare function mergeReverseMap(reverseMap: Map<string, Set<string>>, metafile: Metafile): void;
|
|
24
|
+
/**
|
|
25
|
+
* Given a set of changed files and a reverse dependency map,
|
|
26
|
+
* return the entry points that are affected.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getAffectedEntryPoints(changedFiles: string[], reverseMap: Map<string, Set<string>>): Set<string>;
|
|
29
|
+
//# sourceMappingURL=dependency-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-graph.d.ts","sourceRoot":"","sources":["../src/dependency-graph.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,QAAQ,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAIxD,MAAM,WAAW,eAAe;IAC/B,kFAAkF;IAClF,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAA;CACpC;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACzC,WAAW,EAAE,WAAW,EACxB,MAAM,EAAE,oBAAoB,EAC5B,GAAG,EAAE,MAAM,GACT,OAAO,CAAC,eAAe,CAAC,CAsC1B;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAC9B,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,EACpC,QAAQ,EAAE,QAAQ,GAChB,IAAI,CAcN;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACrC,YAAY,EAAE,MAAM,EAAE,EACtB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAClC,GAAG,CAAC,MAAM,CAAC,CAab"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildDependencyGraph = buildDependencyGraph;
|
|
4
|
+
exports.mergeReverseMap = mergeReverseMap;
|
|
5
|
+
exports.getAffectedEntryPoints = getAffectedEntryPoints;
|
|
6
|
+
const node_path_1 = require("node:path");
|
|
7
|
+
const esbuild_1 = require("esbuild");
|
|
8
|
+
const esbuild_config_js_1 = require("./esbuild-config.js");
|
|
9
|
+
const BATCH_SIZE = 10;
|
|
10
|
+
/**
|
|
11
|
+
* Build a reverse dependency map using esbuild's metafile.
|
|
12
|
+
*
|
|
13
|
+
* Batches entry points to avoid overwhelming esbuild's IPC with huge metafiles.
|
|
14
|
+
*/
|
|
15
|
+
async function buildDependencyGraph(parseResult, config, cwd) {
|
|
16
|
+
const allEntryPoints = {};
|
|
17
|
+
for (const [filePath] of parseResult.entries) {
|
|
18
|
+
const key = (0, node_path_1.relative)(cwd, filePath);
|
|
19
|
+
allEntryPoints[key] = filePath;
|
|
20
|
+
}
|
|
21
|
+
const keys = Object.keys(allEntryPoints);
|
|
22
|
+
if (keys.length === 0) {
|
|
23
|
+
return { reverseMap: new Map() };
|
|
24
|
+
}
|
|
25
|
+
const reverseMap = new Map();
|
|
26
|
+
// Process in batches to avoid esbuild IPC overflow
|
|
27
|
+
for (let i = 0; i < keys.length; i += BATCH_SIZE) {
|
|
28
|
+
const batchKeys = keys.slice(i, i + BATCH_SIZE);
|
|
29
|
+
const batchEntryPoints = {};
|
|
30
|
+
for (const key of batchKeys) {
|
|
31
|
+
batchEntryPoints[key] = allEntryPoints[key];
|
|
32
|
+
}
|
|
33
|
+
const options = (0, esbuild_config_js_1.buildEsbuildOptions)(batchEntryPoints, config);
|
|
34
|
+
// For dependency graph, skip minification — we only need the input list, not accurate sizes
|
|
35
|
+
const result = await (0, esbuild_1.build)({
|
|
36
|
+
...options,
|
|
37
|
+
absWorkingDir: cwd,
|
|
38
|
+
minify: false,
|
|
39
|
+
});
|
|
40
|
+
if (!result.metafile) {
|
|
41
|
+
throw new Error("esbuild did not produce a metafile");
|
|
42
|
+
}
|
|
43
|
+
mergeReverseMap(reverseMap, result.metafile);
|
|
44
|
+
}
|
|
45
|
+
return { reverseMap };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Extract reverse dependency info from a metafile and merge into an existing map.
|
|
49
|
+
*
|
|
50
|
+
* esbuild's metafile.outputs has entries like:
|
|
51
|
+
* "dist/src/handlers/foo.js": { entryPoint: "src/handlers/foo.ts", inputs: { "src/services/bar.ts": ... } }
|
|
52
|
+
*
|
|
53
|
+
* We invert this to get:
|
|
54
|
+
* "src/services/bar.ts" -> Set(["src/handlers/foo.ts"])
|
|
55
|
+
*/
|
|
56
|
+
function mergeReverseMap(reverseMap, metafile) {
|
|
57
|
+
for (const [, outputMeta] of Object.entries(metafile.outputs)) {
|
|
58
|
+
const { entryPoint } = outputMeta;
|
|
59
|
+
if (entryPoint) {
|
|
60
|
+
for (const inputPath of Object.keys(outputMeta.inputs)) {
|
|
61
|
+
let entries = reverseMap.get(inputPath);
|
|
62
|
+
if (!entries) {
|
|
63
|
+
entries = new Set();
|
|
64
|
+
reverseMap.set(inputPath, entries);
|
|
65
|
+
}
|
|
66
|
+
entries.add(entryPoint);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Given a set of changed files and a reverse dependency map,
|
|
73
|
+
* return the entry points that are affected.
|
|
74
|
+
*/
|
|
75
|
+
function getAffectedEntryPoints(changedFiles, reverseMap) {
|
|
76
|
+
const affected = new Set();
|
|
77
|
+
for (const file of changedFiles) {
|
|
78
|
+
const entries = reverseMap.get(file);
|
|
79
|
+
if (entries) {
|
|
80
|
+
for (const entry of entries) {
|
|
81
|
+
affected.add(entry);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return affected;
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=dependency-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dependency-graph.js","sourceRoot":"","sources":["../src/dependency-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { BuildOptions } from "esbuild";
|
|
2
|
+
import type { BundleAnalyserConfig } from "./config.js";
|
|
3
|
+
export declare function buildEsbuildOptions(entryPoints: Record<string, string>, config: BundleAnalyserConfig): BuildOptions;
|
|
4
|
+
//# sourceMappingURL=esbuild-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esbuild-config.d.ts","sourceRoot":"","sources":["../src/esbuild-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAEvD,wBAAgB,mBAAmB,CAClC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACnC,MAAM,EAAE,oBAAoB,GAC1B,YAAY,CAed"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildEsbuildOptions = buildEsbuildOptions;
|
|
4
|
+
function buildEsbuildOptions(entryPoints, config) {
|
|
5
|
+
return {
|
|
6
|
+
entryPoints,
|
|
7
|
+
bundle: true,
|
|
8
|
+
minify: true,
|
|
9
|
+
platform: "node",
|
|
10
|
+
target: "node20",
|
|
11
|
+
format: "cjs",
|
|
12
|
+
sourcemap: false,
|
|
13
|
+
metafile: true,
|
|
14
|
+
write: false,
|
|
15
|
+
outdir: "dist",
|
|
16
|
+
logLevel: "silent",
|
|
17
|
+
...config.esbuild,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=esbuild-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"esbuild-config.js","sourceRoot":"","sources":["../src/esbuild-config.ts"],"names":[],"mappings":";;AAGA,kDAkBC;AAlBD,SAAgB,mBAAmB,CAClC,WAAmC,EACnC,MAA4B;IAE5B,OAAO;QACN,WAAW;QACX,MAAM,EAAE,IAAI;QACZ,MAAM,EAAE,IAAI;QACZ,QAAQ,EAAE,MAAM;QAChB,MAAM,EAAE,QAAQ;QAChB,MAAM,EAAE,KAAK;QACb,SAAS,EAAE,KAAK;QAChB,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,KAAK;QACZ,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE,QAAQ;QAClB,GAAG,MAAM,CAAC,OAAO;KACjB,CAAA;AACF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { type BundleSize, bundleAndMeasure, type ComparisonResult, compareBundles, getChangedFiles, getRepoRoot, withWorktree, } from "./compare.js";
|
|
2
|
+
export { type BundleAnalyserConfig, loadConfig } from "./config.js";
|
|
3
|
+
export { buildDependencyGraph, type DependencyGraph, getAffectedEntryPoints, } from "./dependency-graph.js";
|
|
4
|
+
export { type HandlerEntry, type ParseResult, parseServerlessHandlers, } from "./parse-serverless.js";
|
|
5
|
+
export { buildReportData, formatJsonReport, formatTextReport, type ReportData, } from "./report.js";
|
|
6
|
+
export { analyzeSharedModules, formatSharedModulesJson, formatSharedModulesText, type SharedModule, type SharedModulesResult, } from "./shared-modules.js";
|
|
7
|
+
export { type VisualizeOptions, visualizeDiff, visualizeEntryPoint, } from "./visualize.js";
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,gBAAgB,EACrB,cAAc,EACd,eAAe,EACf,WAAW,EACX,YAAY,GACZ,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,KAAK,oBAAoB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACnE,OAAO,EACN,oBAAoB,EACpB,KAAK,eAAe,EACpB,sBAAsB,GACtB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,uBAAuB,GACvB,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EACN,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,UAAU,GACf,MAAM,aAAa,CAAA;AACpB,OAAO,EACN,oBAAoB,EACpB,uBAAuB,EACvB,uBAAuB,EACvB,KAAK,YAAY,EACjB,KAAK,mBAAmB,GACxB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EACN,KAAK,gBAAgB,EACrB,aAAa,EACb,mBAAmB,GACnB,MAAM,gBAAgB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.visualizeEntryPoint = exports.visualizeDiff = exports.formatSharedModulesText = exports.formatSharedModulesJson = exports.analyzeSharedModules = exports.formatTextReport = exports.formatJsonReport = exports.buildReportData = exports.parseServerlessHandlers = exports.getAffectedEntryPoints = exports.buildDependencyGraph = exports.loadConfig = exports.withWorktree = exports.getRepoRoot = exports.getChangedFiles = exports.compareBundles = exports.bundleAndMeasure = void 0;
|
|
4
|
+
var compare_js_1 = require("./compare.js");
|
|
5
|
+
Object.defineProperty(exports, "bundleAndMeasure", { enumerable: true, get: function () { return compare_js_1.bundleAndMeasure; } });
|
|
6
|
+
Object.defineProperty(exports, "compareBundles", { enumerable: true, get: function () { return compare_js_1.compareBundles; } });
|
|
7
|
+
Object.defineProperty(exports, "getChangedFiles", { enumerable: true, get: function () { return compare_js_1.getChangedFiles; } });
|
|
8
|
+
Object.defineProperty(exports, "getRepoRoot", { enumerable: true, get: function () { return compare_js_1.getRepoRoot; } });
|
|
9
|
+
Object.defineProperty(exports, "withWorktree", { enumerable: true, get: function () { return compare_js_1.withWorktree; } });
|
|
10
|
+
var config_js_1 = require("./config.js");
|
|
11
|
+
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return config_js_1.loadConfig; } });
|
|
12
|
+
var dependency_graph_js_1 = require("./dependency-graph.js");
|
|
13
|
+
Object.defineProperty(exports, "buildDependencyGraph", { enumerable: true, get: function () { return dependency_graph_js_1.buildDependencyGraph; } });
|
|
14
|
+
Object.defineProperty(exports, "getAffectedEntryPoints", { enumerable: true, get: function () { return dependency_graph_js_1.getAffectedEntryPoints; } });
|
|
15
|
+
var parse_serverless_js_1 = require("./parse-serverless.js");
|
|
16
|
+
Object.defineProperty(exports, "parseServerlessHandlers", { enumerable: true, get: function () { return parse_serverless_js_1.parseServerlessHandlers; } });
|
|
17
|
+
var report_js_1 = require("./report.js");
|
|
18
|
+
Object.defineProperty(exports, "buildReportData", { enumerable: true, get: function () { return report_js_1.buildReportData; } });
|
|
19
|
+
Object.defineProperty(exports, "formatJsonReport", { enumerable: true, get: function () { return report_js_1.formatJsonReport; } });
|
|
20
|
+
Object.defineProperty(exports, "formatTextReport", { enumerable: true, get: function () { return report_js_1.formatTextReport; } });
|
|
21
|
+
var shared_modules_js_1 = require("./shared-modules.js");
|
|
22
|
+
Object.defineProperty(exports, "analyzeSharedModules", { enumerable: true, get: function () { return shared_modules_js_1.analyzeSharedModules; } });
|
|
23
|
+
Object.defineProperty(exports, "formatSharedModulesJson", { enumerable: true, get: function () { return shared_modules_js_1.formatSharedModulesJson; } });
|
|
24
|
+
Object.defineProperty(exports, "formatSharedModulesText", { enumerable: true, get: function () { return shared_modules_js_1.formatSharedModulesText; } });
|
|
25
|
+
var visualize_js_1 = require("./visualize.js");
|
|
26
|
+
Object.defineProperty(exports, "visualizeDiff", { enumerable: true, get: function () { return visualize_js_1.visualizeDiff; } });
|
|
27
|
+
Object.defineProperty(exports, "visualizeEntryPoint", { enumerable: true, get: function () { return visualize_js_1.visualizeEntryPoint; } });
|
|
28
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,2CAQqB;AANpB,8GAAA,gBAAgB,OAAA;AAEhB,4GAAA,cAAc,OAAA;AACd,6GAAA,eAAe,OAAA;AACf,yGAAA,WAAW,OAAA;AACX,0GAAA,YAAY,OAAA;AAEb,yCAAmE;AAA/B,uGAAA,UAAU,OAAA;AAC9C,6DAI8B;AAH7B,2HAAA,oBAAoB,OAAA;AAEpB,6HAAA,sBAAsB,OAAA;AAEvB,6DAI8B;AAD7B,8HAAA,uBAAuB,OAAA;AAExB,yCAKoB;AAJnB,4GAAA,eAAe,OAAA;AACf,6GAAA,gBAAgB,OAAA;AAChB,6GAAA,gBAAgB,OAAA;AAGjB,yDAM4B;AAL3B,yHAAA,oBAAoB,OAAA;AACpB,4HAAA,uBAAuB,OAAA;AACvB,4HAAA,uBAAuB,OAAA;AAIxB,+CAIuB;AAFtB,6GAAA,aAAa,OAAA;AACb,mHAAA,mBAAmB,OAAA"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface HandlerEntry {
|
|
2
|
+
/** Absolute path to the handler source file */
|
|
3
|
+
filePath: string;
|
|
4
|
+
/** Export name (e.g. "handler") */
|
|
5
|
+
exportName: string;
|
|
6
|
+
/** Function names in serverless config that use this handler */
|
|
7
|
+
functionNames: string[];
|
|
8
|
+
/** Which serverless file defined this handler */
|
|
9
|
+
serverlessFile: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ParseResult {
|
|
12
|
+
/** Map of absolute file path -> handler entry (deduplicated by file) */
|
|
13
|
+
entries: Map<string, HandlerEntry>;
|
|
14
|
+
/** Total number of function definitions (before deduplication) */
|
|
15
|
+
totalFunctions: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Extract all Lambda handler entry points from serverless*.yml files in a directory.
|
|
19
|
+
*
|
|
20
|
+
* Uses regex-based extraction to avoid issues with Serverless Framework's
|
|
21
|
+
* custom ${...} variable interpolation syntax that breaks standard YAML parsers.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseServerlessHandlers(cwd: string, excludePatterns: string[]): ParseResult;
|
|
24
|
+
export declare function matchesAnyPattern(filename: string, patterns: string[]): boolean;
|
|
25
|
+
interface RawHandler {
|
|
26
|
+
functionName: string;
|
|
27
|
+
handlerPath: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Extract handler: lines from YAML content.
|
|
31
|
+
*
|
|
32
|
+
* We look for lines matching the pattern:
|
|
33
|
+
* handler: src/path/to/file.exportName
|
|
34
|
+
*
|
|
35
|
+
* We track function names by looking for top-level keys under `functions:`
|
|
36
|
+
* that are followed by a `handler:` property.
|
|
37
|
+
*/
|
|
38
|
+
export declare function extractHandlerLines(content: string): RawHandler[];
|
|
39
|
+
/**
|
|
40
|
+
* Extract handler lines from JavaScript serverless config files.
|
|
41
|
+
*
|
|
42
|
+
* Scans for `handler: 'src/path/to/file.exportName'` patterns and looks
|
|
43
|
+
* backwards from each match to find the enclosing function name key.
|
|
44
|
+
*/
|
|
45
|
+
export declare function extractHandlerLinesFromJs(content: string): RawHandler[];
|
|
46
|
+
/**
|
|
47
|
+
* Find ${file(...)} references within the functions: block.
|
|
48
|
+
* e.g. `functions: ${file(./some-other-file.yml):functions}`
|
|
49
|
+
* or individual function definitions loaded via file()
|
|
50
|
+
*/
|
|
51
|
+
export declare function extractFunctionFileRefs(content: string, ymlFile: string): string[];
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=parse-serverless.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-serverless.d.ts","sourceRoot":"","sources":["../src/parse-serverless.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC5B,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAA;IAChB,mCAAmC;IACnC,UAAU,EAAE,MAAM,CAAA;IAClB,gEAAgE;IAChE,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,iDAAiD;IACjD,cAAc,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC3B,wEAAwE;IACxE,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAClC,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAA;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACtC,GAAG,EAAE,MAAM,EACX,eAAe,EAAE,MAAM,EAAE,GACvB,WAAW,CAqBb;AAWD,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAAE,GAChB,OAAO,CAOT;AAED,UAAU,UAAU;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;CACnB;AAqCD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAmCjE;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CA2BvE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACb,MAAM,EAAE,CAmBV"}
|