@perfonext/build-mcp 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -1
- package/dist/index.js +13 -1
- package/dist/index.js.map +1 -1
- package/dist/parser/analysis.d.ts +7 -1
- package/dist/parser/analysis.d.ts.map +1 -1
- package/dist/parser/analysis.js +202 -0
- package/dist/parser/analysis.js.map +1 -1
- package/dist/parser/types.d.ts +88 -0
- package/dist/parser/types.d.ts.map +1 -1
- package/dist/parser/webpack-stats.d.ts +30 -0
- package/dist/parser/webpack-stats.d.ts.map +1 -0
- package/dist/parser/webpack-stats.js +353 -0
- package/dist/parser/webpack-stats.js.map +1 -0
- package/dist/store.d.ts +3 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +7 -0
- package/dist/store.js.map +1 -1
- package/dist/tools/explain-shared-chunks.d.ts +3 -0
- package/dist/tools/explain-shared-chunks.d.ts.map +1 -0
- package/dist/tools/explain-shared-chunks.js +45 -0
- package/dist/tools/explain-shared-chunks.js.map +1 -0
- package/dist/tools/find-duplicates.d.ts +3 -0
- package/dist/tools/find-duplicates.d.ts.map +1 -0
- package/dist/tools/find-duplicates.js +43 -0
- package/dist/tools/find-duplicates.js.map +1 -0
- package/dist/tools/how-to-collect-stats.d.ts +3 -0
- package/dist/tools/how-to-collect-stats.d.ts.map +1 -0
- package/dist/tools/how-to-collect-stats.js +137 -0
- package/dist/tools/how-to-collect-stats.js.map +1 -0
- package/dist/tools/load-webpack-stats.d.ts +3 -0
- package/dist/tools/load-webpack-stats.d.ts.map +1 -0
- package/dist/tools/load-webpack-stats.js +51 -0
- package/dist/tools/load-webpack-stats.js.map +1 -0
- package/dist/tools/suggest-optimizations.d.ts +3 -0
- package/dist/tools/suggest-optimizations.d.ts.map +1 -0
- package/dist/tools/suggest-optimizations.js +46 -0
- package/dist/tools/suggest-optimizations.js.map +1 -0
- package/dist/tools/trace-import.d.ts +3 -0
- package/dist/tools/trace-import.d.ts.map +1 -0
- package/dist/tools/trace-import.js +41 -0
- package/dist/tools/trace-import.js.map +1 -0
- package/dist/tools/webpack-shared.d.ts +21 -0
- package/dist/tools/webpack-shared.d.ts.map +1 -0
- package/dist/tools/webpack-shared.js +33 -0
- package/dist/tools/webpack-shared.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
const NODE_MODULES_MARKER = 'node_modules/';
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return value !== null && typeof value === 'object';
|
|
6
|
+
}
|
|
7
|
+
function toFiniteNumber(value) {
|
|
8
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : 0;
|
|
9
|
+
}
|
|
10
|
+
function toStringArray(value) {
|
|
11
|
+
if (!Array.isArray(value)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
return value.filter((item) => typeof item === 'string');
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Resolve the npm package an emitted module belongs to. Uses the LAST `node_modules/` segment so
|
|
18
|
+
* nested installs (`a/node_modules/b`) attribute to the inner package, and preserves scoped names
|
|
19
|
+
* (`@org/pkg`). Returns null for first-party application code.
|
|
20
|
+
*/
|
|
21
|
+
export function extractPackageName(moduleName) {
|
|
22
|
+
// Webpack `name` uses POSIX separators, but the `identifier` fallback can carry
|
|
23
|
+
// Windows backslashes — normalize so attribution works on every platform.
|
|
24
|
+
const normalized = moduleName.replace(/\\/g, '/');
|
|
25
|
+
const markerIndex = normalized.lastIndexOf(NODE_MODULES_MARKER);
|
|
26
|
+
if (markerIndex === -1) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
const rest = normalized.slice(markerIndex + NODE_MODULES_MARKER.length);
|
|
30
|
+
const parts = rest.split('/').filter(Boolean);
|
|
31
|
+
if (parts.length === 0) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
if (parts[0].startsWith('@') && parts.length >= 2) {
|
|
35
|
+
return `${parts[0]}/${parts[1]}`;
|
|
36
|
+
}
|
|
37
|
+
return parts[0];
|
|
38
|
+
}
|
|
39
|
+
function normalizeReason(raw) {
|
|
40
|
+
if (!isRecord(raw)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
const moduleName = typeof raw.moduleName === 'string' ? raw.moduleName : null;
|
|
44
|
+
const userRequest = typeof raw.userRequest === 'string' ? raw.userRequest : null;
|
|
45
|
+
if (moduleName === null && userRequest === null) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
return { moduleName, userRequest };
|
|
49
|
+
}
|
|
50
|
+
function normalizeModule(raw) {
|
|
51
|
+
const name = typeof raw.name === 'string'
|
|
52
|
+
? raw.name
|
|
53
|
+
: typeof raw.identifier === 'string'
|
|
54
|
+
? raw.identifier
|
|
55
|
+
: null;
|
|
56
|
+
if (!name) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const chunkIds = Array.isArray(raw.chunks)
|
|
60
|
+
? raw.chunks.filter((id) => typeof id === 'string' || typeof id === 'number')
|
|
61
|
+
: [];
|
|
62
|
+
const reasons = Array.isArray(raw.reasons)
|
|
63
|
+
? raw.reasons
|
|
64
|
+
.map(normalizeReason)
|
|
65
|
+
.filter((reason) => reason !== null)
|
|
66
|
+
: [];
|
|
67
|
+
return {
|
|
68
|
+
name,
|
|
69
|
+
packageName: extractPackageName(name),
|
|
70
|
+
sizeBytes: toFiniteNumber(raw.size),
|
|
71
|
+
chunkIds,
|
|
72
|
+
reasons,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function normalizeChunk(raw) {
|
|
76
|
+
if (raw.id === undefined || (typeof raw.id !== 'string' && typeof raw.id !== 'number')) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
id: raw.id,
|
|
81
|
+
names: toStringArray(raw.names),
|
|
82
|
+
files: toStringArray(raw.files),
|
|
83
|
+
sizeBytes: toFiniteNumber(raw.size),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Parse a webpack module-stats JSON (`.next/stats.json`) into a compact, analysis-ready shape.
|
|
88
|
+
* Only the fields the attribution tools need are retained — raw source, asset maps, and other
|
|
89
|
+
* webpack noise are dropped so a multi-MB stats file stays small in memory.
|
|
90
|
+
*/
|
|
91
|
+
export async function parseWebpackStats(buildDirPath, buildId) {
|
|
92
|
+
const buildDir = resolve(buildDirPath);
|
|
93
|
+
const statsPath = join(buildDir, 'stats.json');
|
|
94
|
+
let content;
|
|
95
|
+
try {
|
|
96
|
+
content = await readFile(statsPath, 'utf-8');
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error.code === 'ENOENT') {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
throw error;
|
|
103
|
+
}
|
|
104
|
+
let raw;
|
|
105
|
+
try {
|
|
106
|
+
raw = JSON.parse(content);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
throw new Error(`Failed to parse webpack stats JSON at ${statsPath} (build "${buildId}"): ${error.message}`);
|
|
110
|
+
}
|
|
111
|
+
const rawModules = Array.isArray(raw.modules) ? raw.modules : [];
|
|
112
|
+
const rawChunks = Array.isArray(raw.chunks) ? raw.chunks : [];
|
|
113
|
+
const modules = rawModules
|
|
114
|
+
.map(module => normalizeModule(module))
|
|
115
|
+
.filter((module) => module !== null);
|
|
116
|
+
const chunks = rawChunks
|
|
117
|
+
.map(chunk => normalizeChunk(chunk))
|
|
118
|
+
.filter((chunk) => chunk !== null);
|
|
119
|
+
return {
|
|
120
|
+
buildId,
|
|
121
|
+
statsPath,
|
|
122
|
+
modules,
|
|
123
|
+
chunks,
|
|
124
|
+
moduleCount: rawModules.length,
|
|
125
|
+
parsedModuleCount: modules.length,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function buildModuleIndex(stats) {
|
|
129
|
+
const index = new Map();
|
|
130
|
+
for (const module of stats.modules) {
|
|
131
|
+
index.set(module.name, module);
|
|
132
|
+
}
|
|
133
|
+
return index;
|
|
134
|
+
}
|
|
135
|
+
function chunkFilesForModule(module, chunkById) {
|
|
136
|
+
const files = new Set();
|
|
137
|
+
for (const chunkId of module.chunkIds) {
|
|
138
|
+
const chunk = chunkById.get(chunkId);
|
|
139
|
+
for (const file of chunk?.files ?? []) {
|
|
140
|
+
files.add(file);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return Array.from(files).sort();
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Walk a module's `reasons` upward to the nearest entry to explain why it is bundled. Picks the
|
|
147
|
+
* first resolvable parent at each step, guards against cycles, and caps depth so a pathological
|
|
148
|
+
* graph cannot loop. Returns the chain ordered from entry → target.
|
|
149
|
+
*/
|
|
150
|
+
function buildImportChain(target, moduleIndex) {
|
|
151
|
+
const chain = [
|
|
152
|
+
{ moduleName: target.name, packageName: target.packageName },
|
|
153
|
+
];
|
|
154
|
+
const visited = new Set([target.name]);
|
|
155
|
+
let current = target;
|
|
156
|
+
const maxDepth = 25;
|
|
157
|
+
for (let depth = 0; depth < maxDepth; depth += 1) {
|
|
158
|
+
const parentReason = current.reasons.find(reason => reason.moduleName !== null && !visited.has(reason.moduleName));
|
|
159
|
+
if (!parentReason || parentReason.moduleName === null) {
|
|
160
|
+
break;
|
|
161
|
+
}
|
|
162
|
+
const parent = moduleIndex.get(parentReason.moduleName);
|
|
163
|
+
visited.add(parentReason.moduleName);
|
|
164
|
+
chain.push({
|
|
165
|
+
moduleName: parentReason.moduleName,
|
|
166
|
+
packageName: parent?.packageName ?? extractPackageName(parentReason.moduleName),
|
|
167
|
+
});
|
|
168
|
+
if (!parent || parent.reasons.length === 0) {
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
current = parent;
|
|
172
|
+
}
|
|
173
|
+
return chain.reverse();
|
|
174
|
+
}
|
|
175
|
+
export function traceImport(stats, moduleName, limit = 10) {
|
|
176
|
+
const query = moduleName.toLowerCase();
|
|
177
|
+
const moduleIndex = buildModuleIndex(stats);
|
|
178
|
+
const chunkById = new Map(stats.chunks.map(chunk => [chunk.id, chunk]));
|
|
179
|
+
const matches = stats.modules
|
|
180
|
+
.filter(module => module.name.toLowerCase().includes(query))
|
|
181
|
+
.sort((left, right) => right.sizeBytes - left.sizeBytes);
|
|
182
|
+
const traces = matches.slice(0, limit).map(module => ({
|
|
183
|
+
moduleName: module.name,
|
|
184
|
+
packageName: module.packageName,
|
|
185
|
+
sizeBytes: module.sizeBytes,
|
|
186
|
+
chunkFiles: chunkFilesForModule(module, chunkById),
|
|
187
|
+
importChain: buildImportChain(module, moduleIndex),
|
|
188
|
+
}));
|
|
189
|
+
return {
|
|
190
|
+
query: moduleName,
|
|
191
|
+
matchCount: matches.length,
|
|
192
|
+
traces,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function normalizeChunkFile(chunkPath) {
|
|
196
|
+
return chunkPath.replace(/^\//, '');
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Rank npm packages whose code is emitted into more than one chunk. Wasted bytes are the
|
|
200
|
+
* duplicated copies: `moduleBytes * (distinctChunkCount - 1)`, aggregated per package.
|
|
201
|
+
*/
|
|
202
|
+
export function findDuplicates(stats, limit = 20) {
|
|
203
|
+
const chunkById = new Map(stats.chunks.map(chunk => [chunk.id, chunk]));
|
|
204
|
+
const byPackage = new Map();
|
|
205
|
+
for (const module of stats.modules) {
|
|
206
|
+
if (!module.packageName) {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const distinctChunkIds = Array.from(new Set(module.chunkIds));
|
|
210
|
+
const entry = byPackage.get(module.packageName) ?? {
|
|
211
|
+
wastedBytes: 0,
|
|
212
|
+
totalBytes: 0,
|
|
213
|
+
chunkIds: new Set(),
|
|
214
|
+
chunkFiles: new Set(),
|
|
215
|
+
};
|
|
216
|
+
entry.totalBytes += module.sizeBytes;
|
|
217
|
+
if (distinctChunkIds.length > 1) {
|
|
218
|
+
entry.wastedBytes += module.sizeBytes * (distinctChunkIds.length - 1);
|
|
219
|
+
}
|
|
220
|
+
for (const chunkId of distinctChunkIds) {
|
|
221
|
+
entry.chunkIds.add(chunkId);
|
|
222
|
+
for (const file of chunkById.get(chunkId)?.files ?? []) {
|
|
223
|
+
entry.chunkFiles.add(file);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
byPackage.set(module.packageName, entry);
|
|
227
|
+
}
|
|
228
|
+
return Array.from(byPackage.entries())
|
|
229
|
+
.filter(([, entry]) => entry.wastedBytes > 0)
|
|
230
|
+
.map(([packageName, entry]) => ({
|
|
231
|
+
packageName,
|
|
232
|
+
wastedBytes: entry.wastedBytes,
|
|
233
|
+
totalBytes: entry.totalBytes,
|
|
234
|
+
// Distinct chunks, not files: one chunk can emit several files (.js + .css).
|
|
235
|
+
chunkCount: entry.chunkIds.size,
|
|
236
|
+
chunkFiles: Array.from(entry.chunkFiles).sort(),
|
|
237
|
+
}))
|
|
238
|
+
.sort((left, right) => right.wastedBytes - left.wastedBytes || left.packageName.localeCompare(right.packageName))
|
|
239
|
+
.slice(0, limit);
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Explain what dominates each shared chunk: join the manifest's shared chunks to the webpack
|
|
243
|
+
* module graph and rank the packages (and app code) by their byte share of the chunk.
|
|
244
|
+
*/
|
|
245
|
+
export function explainSharedChunks(build, stats, limit = 5, packagesPerChunk = 5) {
|
|
246
|
+
const chunkByFile = new Map();
|
|
247
|
+
for (const chunk of stats.chunks) {
|
|
248
|
+
for (const file of chunk.files) {
|
|
249
|
+
// Normalize on insert so the join stays symmetric with the manifest-path lookup below.
|
|
250
|
+
chunkByFile.set(normalizeChunkFile(file), chunk);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
const modulesByChunkId = new Map();
|
|
254
|
+
for (const module of stats.modules) {
|
|
255
|
+
for (const chunkId of new Set(module.chunkIds)) {
|
|
256
|
+
const list = modulesByChunkId.get(chunkId) ?? [];
|
|
257
|
+
list.push(module);
|
|
258
|
+
modulesByChunkId.set(chunkId, list);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
// build.chunks is pre-sorted by sizeBytes desc, so the first `limit` shared chunks are the largest.
|
|
262
|
+
const sharedChunks = build.chunks.filter(chunk => chunk.isShared).slice(0, limit);
|
|
263
|
+
return sharedChunks.map(chunk => {
|
|
264
|
+
const webpackChunk = chunkByFile.get(normalizeChunkFile(chunk.chunkPath));
|
|
265
|
+
const modules = webpackChunk ? modulesByChunkId.get(webpackChunk.id) ?? [] : [];
|
|
266
|
+
const bytesByPackage = new Map();
|
|
267
|
+
let chunkModuleBytes = 0;
|
|
268
|
+
for (const module of modules) {
|
|
269
|
+
const label = module.packageName ?? '(app code)';
|
|
270
|
+
bytesByPackage.set(label, (bytesByPackage.get(label) ?? 0) + module.sizeBytes);
|
|
271
|
+
chunkModuleBytes += module.sizeBytes;
|
|
272
|
+
}
|
|
273
|
+
const topPackages = Array.from(bytesByPackage.entries())
|
|
274
|
+
.map(([packageName, bytes]) => ({
|
|
275
|
+
packageName,
|
|
276
|
+
bytes,
|
|
277
|
+
shareOfChunk: chunkModuleBytes === 0 ? 0 : bytes / chunkModuleBytes,
|
|
278
|
+
}))
|
|
279
|
+
.sort((left, right) => right.bytes - left.bytes || left.packageName.localeCompare(right.packageName))
|
|
280
|
+
.slice(0, packagesPerChunk);
|
|
281
|
+
return {
|
|
282
|
+
chunkPath: chunk.chunkPath,
|
|
283
|
+
sizeBytes: chunk.sizeBytes,
|
|
284
|
+
routeCount: chunk.routeCount,
|
|
285
|
+
sharedByRoutes: chunk.sharedByRoutes,
|
|
286
|
+
topPackages,
|
|
287
|
+
};
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Aggregate emitted module bytes per npm package, joined to the manifest so each package reports
|
|
292
|
+
* which routes pay for it and how its bytes split between shared and route-exclusive chunks.
|
|
293
|
+
*/
|
|
294
|
+
export function getPackageCosts(build, stats, limit = 20) {
|
|
295
|
+
const chunkById = new Map(stats.chunks.map(chunk => [chunk.id, chunk]));
|
|
296
|
+
const buildChunkByFile = new Map();
|
|
297
|
+
for (const chunk of build.chunks) {
|
|
298
|
+
buildChunkByFile.set(normalizeChunkFile(chunk.chunkPath), chunk);
|
|
299
|
+
}
|
|
300
|
+
const byPackage = new Map();
|
|
301
|
+
for (const module of stats.modules) {
|
|
302
|
+
if (!module.packageName) {
|
|
303
|
+
continue;
|
|
304
|
+
}
|
|
305
|
+
const acc = byPackage.get(module.packageName) ?? {
|
|
306
|
+
totalBytes: 0,
|
|
307
|
+
moduleCount: 0,
|
|
308
|
+
sharedBytes: 0,
|
|
309
|
+
exclusiveBytes: 0,
|
|
310
|
+
chunkFiles: new Set(),
|
|
311
|
+
routes: new Set(),
|
|
312
|
+
};
|
|
313
|
+
acc.totalBytes += module.sizeBytes;
|
|
314
|
+
acc.moduleCount += 1;
|
|
315
|
+
// Any shared placement counts wholly as shared; a duplicate exclusive copy is find_duplicates' job.
|
|
316
|
+
let livesInSharedChunk = false;
|
|
317
|
+
for (const chunkId of new Set(module.chunkIds)) {
|
|
318
|
+
for (const file of chunkById.get(chunkId)?.files ?? []) {
|
|
319
|
+
const buildChunk = buildChunkByFile.get(normalizeChunkFile(file));
|
|
320
|
+
if (!buildChunk) {
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
acc.chunkFiles.add(buildChunk.chunkPath);
|
|
324
|
+
for (const route of buildChunk.sharedByRoutes) {
|
|
325
|
+
acc.routes.add(route);
|
|
326
|
+
}
|
|
327
|
+
if (buildChunk.isShared) {
|
|
328
|
+
livesInSharedChunk = true;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (livesInSharedChunk) {
|
|
333
|
+
acc.sharedBytes += module.sizeBytes;
|
|
334
|
+
}
|
|
335
|
+
else {
|
|
336
|
+
acc.exclusiveBytes += module.sizeBytes;
|
|
337
|
+
}
|
|
338
|
+
byPackage.set(module.packageName, acc);
|
|
339
|
+
}
|
|
340
|
+
return Array.from(byPackage.entries())
|
|
341
|
+
.map(([packageName, acc]) => ({
|
|
342
|
+
packageName,
|
|
343
|
+
totalBytes: acc.totalBytes,
|
|
344
|
+
moduleCount: acc.moduleCount,
|
|
345
|
+
chunkCount: acc.chunkFiles.size,
|
|
346
|
+
sharedBytes: acc.sharedBytes,
|
|
347
|
+
exclusiveBytes: acc.exclusiveBytes,
|
|
348
|
+
routeCount: acc.routes.size,
|
|
349
|
+
}))
|
|
350
|
+
.sort((left, right) => right.totalBytes - left.totalBytes || left.packageName.localeCompare(right.packageName))
|
|
351
|
+
.slice(0, limit);
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=webpack-stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webpack-stats.js","sourceRoot":"","sources":["../../src/parser/webpack-stats.ts"],"names":[],"mappings":"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"}
|
package/dist/store.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { ParsedBuildStats } from './parser/types.js';
|
|
1
|
+
import type { ParsedBuildStats, ParsedWebpackStats } from './parser/types.js';
|
|
2
2
|
export declare function storeBuildStats(build: ParsedBuildStats): void;
|
|
3
3
|
export declare function getBuildStats(id: string): ParsedBuildStats | undefined;
|
|
4
|
+
export declare function storeWebpackStats(stats: ParsedWebpackStats): void;
|
|
5
|
+
export declare function getWebpackStats(buildId: string): ParsedWebpackStats | undefined;
|
|
4
6
|
export declare function listBuildStats(): Array<{
|
|
5
7
|
id: string;
|
|
6
8
|
buildDir: string;
|
package/dist/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAK9E,wBAAgB,eAAe,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAE7D;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,gBAAgB,GAAG,SAAS,CAEtE;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,kBAAkB,GAAG,IAAI,CAEjE;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAE/E;AAED,wBAAgB,cAAc,IAAI,KAAK,CAAC;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,CAAC,CASD"}
|
package/dist/store.js
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
const builds = new Map();
|
|
2
|
+
const webpackStats = new Map();
|
|
2
3
|
export function storeBuildStats(build) {
|
|
3
4
|
builds.set(build.id, build);
|
|
4
5
|
}
|
|
5
6
|
export function getBuildStats(id) {
|
|
6
7
|
return builds.get(id);
|
|
7
8
|
}
|
|
9
|
+
export function storeWebpackStats(stats) {
|
|
10
|
+
webpackStats.set(stats.buildId, stats);
|
|
11
|
+
}
|
|
12
|
+
export function getWebpackStats(buildId) {
|
|
13
|
+
return webpackStats.get(buildId);
|
|
14
|
+
}
|
|
8
15
|
export function listBuildStats() {
|
|
9
16
|
return Array.from(builds.values()).map(build => ({
|
|
10
17
|
id: build.id,
|
package/dist/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAAG,IAAI,GAAG,EAA4B,CAAC;AACnD,MAAM,YAAY,GAAG,IAAI,GAAG,EAA8B,CAAC;AAE3D,MAAM,UAAU,eAAe,CAAC,KAAuB;IACrD,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,EAAU;IACtC,OAAO,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IACzD,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,cAAc;IAQ5B,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC/C,EAAE,EAAE,KAAK,CAAC,EAAE;QACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;QAC/B,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM;QAC/B,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,WAAW,EAAE,KAAK,CAAC,WAAW;KAC/B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain-shared-chunks.d.ts","sourceRoot":"","sources":["../../src/tools/explain-shared-chunks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,wBAAgB,2BAA2B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAyCnE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { formatBytes, formatPct } from '../format.js';
|
|
3
|
+
import { explainSharedChunks } from '../parser/webpack-stats.js';
|
|
4
|
+
import { getBuildStats } from '../store.js';
|
|
5
|
+
import { resolveWebpackStats, statsTextResult } from './webpack-shared.js';
|
|
6
|
+
export function registerExplainSharedChunks(server) {
|
|
7
|
+
server.registerTool('explain_shared_chunks', {
|
|
8
|
+
title: 'Explain Shared Chunks',
|
|
9
|
+
description: 'Show which npm packages and app code dominate the shared chunks loaded by many routes, to identify ' +
|
|
10
|
+
'what bloats common bundles. Requires load_build_stats and load_webpack_stats first.',
|
|
11
|
+
inputSchema: {
|
|
12
|
+
buildId: z.string().describe('Build ID returned by load_build_stats'),
|
|
13
|
+
limit: z.number().int().positive().max(20).optional().describe('Maximum shared chunks to analyse. Defaults to 5.'),
|
|
14
|
+
},
|
|
15
|
+
}, async ({ buildId, limit }) => {
|
|
16
|
+
const build = getBuildStats(buildId);
|
|
17
|
+
if (!build) {
|
|
18
|
+
throw new Error(`Build "${buildId}" not found. Call load_build_stats first.`);
|
|
19
|
+
}
|
|
20
|
+
const resolved = resolveWebpackStats(buildId);
|
|
21
|
+
if ('breadcrumb' in resolved) {
|
|
22
|
+
return statsTextResult(resolved.breadcrumb);
|
|
23
|
+
}
|
|
24
|
+
const compositions = explainSharedChunks(build, resolved.stats, limit ?? 5);
|
|
25
|
+
return statsTextResult({
|
|
26
|
+
buildId,
|
|
27
|
+
sharedChunkCount: compositions.length,
|
|
28
|
+
sharedChunks: compositions.map(chunk => ({
|
|
29
|
+
chunkPath: chunk.chunkPath,
|
|
30
|
+
sizeBytes: chunk.sizeBytes,
|
|
31
|
+
sizeBytesText: formatBytes(chunk.sizeBytes),
|
|
32
|
+
routeCount: chunk.routeCount,
|
|
33
|
+
sharedByRoutes: chunk.sharedByRoutes,
|
|
34
|
+
topPackages: chunk.topPackages.map(pkg => ({
|
|
35
|
+
packageName: pkg.packageName,
|
|
36
|
+
bytes: pkg.bytes,
|
|
37
|
+
bytesText: formatBytes(pkg.bytes),
|
|
38
|
+
shareOfChunk: pkg.shareOfChunk,
|
|
39
|
+
shareOfChunkText: formatPct(pkg.shareOfChunk),
|
|
40
|
+
})),
|
|
41
|
+
})),
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=explain-shared-chunks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"explain-shared-chunks.js","sourceRoot":"","sources":["../../src/tools/explain-shared-chunks.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3E,MAAM,UAAU,2BAA2B,CAAC,MAAiB;IAC3D,MAAM,CAAC,YAAY,CAAC,uBAAuB,EAAE;QAC3C,KAAK,EAAE,uBAAuB;QAC9B,WAAW,EACT,qGAAqG;YACrG,qFAAqF;QACvF,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YACrE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kDAAkD,CAAC;SACnH;KACF,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,2CAA2C,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;YAC7B,OAAO,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,YAAY,GAAG,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC;QAC5E,OAAO,eAAe,CAAC;YACrB,OAAO;YACP,gBAAgB,EAAE,YAAY,CAAC,MAAM;YACrC,YAAY,EAAE,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACvC,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,aAAa,EAAE,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC;gBAC3C,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,WAAW,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;oBACzC,WAAW,EAAE,GAAG,CAAC,WAAW;oBAC5B,KAAK,EAAE,GAAG,CAAC,KAAK;oBAChB,SAAS,EAAE,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC;oBACjC,YAAY,EAAE,GAAG,CAAC,YAAY;oBAC9B,gBAAgB,EAAE,SAAS,CAAC,GAAG,CAAC,YAAY,CAAC;iBAC9C,CAAC,CAAC;aACJ,CAAC,CAAC;SACJ,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-duplicates.d.ts","sourceRoot":"","sources":["../../src/tools/find-duplicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAQpE,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAwC9D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { formatBytes } from '../format.js';
|
|
3
|
+
import { findDuplicates } from '../parser/webpack-stats.js';
|
|
4
|
+
import { getBuildStats } from '../store.js';
|
|
5
|
+
import { resolveWebpackStats, statsTextResult } from './webpack-shared.js';
|
|
6
|
+
export function registerFindDuplicates(server) {
|
|
7
|
+
server.registerTool('find_duplicates', {
|
|
8
|
+
title: 'Find Duplicate Packages',
|
|
9
|
+
description: 'Find npm packages whose code is bundled into more than one chunk, wasting bytes, ranked by wasted ' +
|
|
10
|
+
'bytes. Requires load_webpack_stats first.',
|
|
11
|
+
inputSchema: {
|
|
12
|
+
buildId: z.string().describe('Build ID returned by load_build_stats'),
|
|
13
|
+
limit: z.number().int().positive().max(50).optional().describe('Maximum duplicate packages to return. Defaults to 20.'),
|
|
14
|
+
},
|
|
15
|
+
}, async ({ buildId, limit }) => {
|
|
16
|
+
const build = getBuildStats(buildId);
|
|
17
|
+
if (!build) {
|
|
18
|
+
throw new Error(`Build "${buildId}" not found. Call load_build_stats first.`);
|
|
19
|
+
}
|
|
20
|
+
const resolved = resolveWebpackStats(buildId);
|
|
21
|
+
if ('breadcrumb' in resolved) {
|
|
22
|
+
return statsTextResult(resolved.breadcrumb);
|
|
23
|
+
}
|
|
24
|
+
const duplicates = findDuplicates(resolved.stats, limit ?? 20);
|
|
25
|
+
return statsTextResult({
|
|
26
|
+
buildId,
|
|
27
|
+
duplicateCount: duplicates.length,
|
|
28
|
+
duplicates: duplicates.map(entry => ({
|
|
29
|
+
packageName: entry.packageName,
|
|
30
|
+
wastedBytes: entry.wastedBytes,
|
|
31
|
+
wastedBytesText: formatBytes(entry.wastedBytes),
|
|
32
|
+
totalBytes: entry.totalBytes,
|
|
33
|
+
totalBytesText: formatBytes(entry.totalBytes),
|
|
34
|
+
chunkCount: entry.chunkCount,
|
|
35
|
+
chunkFiles: entry.chunkFiles,
|
|
36
|
+
})),
|
|
37
|
+
nextStep: duplicates.length > 0
|
|
38
|
+
? 'Dedupe with `npm dedupe`, align versions, or move the package into a single shared chunk.'
|
|
39
|
+
: 'No duplicated packages detected across chunks.',
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=find-duplicates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"find-duplicates.js","sourceRoot":"","sources":["../../src/tools/find-duplicates.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3E,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CAAC,iBAAiB,EAAE;QACrC,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT,oGAAoG;YACpG,2CAA2C;QAC7C,WAAW,EAAE;YACX,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,uCAAuC,CAAC;YACrE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,uDAAuD,CAAC;SACxH;KACF,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE;QAC9B,MAAM,KAAK,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,UAAU,OAAO,2CAA2C,CAAC,CAAC;QAChF,CAAC;QAED,MAAM,QAAQ,GAAG,mBAAmB,CAAC,OAAO,CAAC,CAAC;QAC9C,IAAI,YAAY,IAAI,QAAQ,EAAE,CAAC;YAC7B,OAAO,eAAe,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC/D,OAAO,eAAe,CAAC;YACrB,OAAO;YACP,cAAc,EAAE,UAAU,CAAC,MAAM;YACjC,UAAU,EAAE,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBACnC,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,eAAe,EAAE,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC;gBAC/C,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,cAAc,EAAE,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC;gBAC7C,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B,CAAC,CAAC;YACH,QAAQ,EACN,UAAU,CAAC,MAAM,GAAG,CAAC;gBACnB,CAAC,CAAC,2FAA2F;gBAC7F,CAAC,CAAC,gDAAgD;SACvD,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"how-to-collect-stats.d.ts","sourceRoot":"","sources":["../../src/tools/how-to-collect-stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AA4HpE,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CA8BjE"}
|