Skip to content

feat(bundle-size-tools): emit and consume analyzer.json for bundle size diff#27224

Open
ChumpChief wants to merge 3 commits intomicrosoft:mainfrom
ChumpChief:add-analyzer-json-output
Open

feat(bundle-size-tools): emit and consume analyzer.json for bundle size diff#27224
ChumpChief wants to merge 3 commits intomicrosoft:mainfrom
ChumpChief:add-analyzer-json-output

Conversation

@ChumpChief
Copy link
Copy Markdown
Contributor

@ChumpChief ChumpChief commented May 4, 2026

Description

webpack-bundle-analyzer's analyzerMode: "json" output (analyzer.json) is a much smaller, pre-summarized form of the per-asset data we use for bundle-size comparisons (~750KB vs ~3.7MB for bundleStats.msp.gz, the compressed raw stats we currently consume — and ~377MB raw). We use roughly 1% of what's in the full webpack stats. Switching to analyzer.json lets us drop the entire WebpackStatsProcessor pipeline (gunzip → msgpack-decode → walk → entry processor → total processor) and just read pre-summarized per-asset parsedSize directly.

Two commits, separable for review:

  1. Producer (examples/utils/bundle-size-tests/webpack.config.cjs): adds a second BundleAnalyzerPlugin instance with analyzerMode: "json", emitting bundleAnalysis/analyzer.json alongside the existing report.html/report.json/bundleStats.msp.gz. Existing outputs are unchanged — flub generate bundleStats sanity checks and the FF-internal telemetry handler keep working as-is.
  2. Consumer (bundle-size-tools): adds analyzer.json reader functions (getAnalyzerJsonFromZip, getAnalyzerJsonFromFileSystem), path discovery (getAnalyzerFilePathsFromFolder and the getAnalyzerPathsFrom* wrappers), and getBundleSummariesFromAnalyzer. ADOSizeComparator switches to the analyzer.json path internally. result.json shape and BundleMetric (parsedSize-only) are unchanged, and per-entrypoint metric names/values match between the two paths. One delta: the msp.gz path's synthesized per-bundle "Total Size" metric is no longer emitted (it's derivable from the per-asset metrics if a downstream consumer needs it).

The new readers use BundleAnalyzerPlugin.JsonReport from @types/webpack-bundle-analyzer (added as a devDep) so the type comes from the producer authoritatively rather than a hand-rolled subset.

Public-API surface is purely additive — the prior msp.gz reader path (getStatsFileFromZip, getStatsFileFromFileSystem, getBundleSummaries with its original args, getBundleFilePathsFromFolder's msp.gz detection, DefaultStatsProcessors, etc.) remains exported and functional. It just goes unused by ADOSizeComparator after this change.

A follow-up PR will clean up the now-dead code (the msp.gz reader path, the WebpackStatsProcessor infrastructure, and related types). It was left out of this PR to keep the review focused on the swap itself.

Part of AB#56981 (re-enable PR bundle size comparison) — this is one of several incremental PRs that will follow PR #27158.

ChumpChief and others added 2 commits May 4, 2026 10:06
Adds a second BundleAnalyzerPlugin instance with analyzerMode: "json"
alongside the existing static-mode (HTML) instance. The new
bundleAnalysis/analyzer.json is what `flub generate bundleSizeDiff`
consumes for the comparison: per-asset statSize/parsedSize/gzipSize,
much smaller (741KB) and more useful than the raw webpack stats.

The existing report.json (raw stats) and bundleStats.msp.gz (msgpack-
compressed stats) outputs remain unchanged — they're consumed by
`flub generate bundleStats` sanity checks and by the FF-internal
telemetry handler outside this repo, neither of which we want to
risk breaking.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The producer (previous commit) now emits webpack-bundle-analyzer's
analyzer.json alongside the existing bundleStats.msp.gz. Wire the consumer
to read the new format internally, while keeping the prior msp.gz reader
path on the public-API surface for backward compatibility.

New (used internally by ADOSizeComparator):
- getAnalyzerJsonFromZip / getAnalyzerJsonFromFileSystem read and parse
  analyzer.json. Typed with BundleAnalyzerPlugin.JsonReport from
  @types/webpack-bundle-analyzer (added as a devDep) so we get the
  producer's shape authoritatively rather than maintaining a hand-rolled
  subset.
- getAnalyzerFilePathsFromFolder, getAnalyzerPathsFromZipObject,
  getAnalyzerPathsFromFileSystem — analyzer.json path discovery,
  paralleling the existing bundle-paths helpers.
- getBundleSummariesFromAnalyzer + GetBundleSummariesFromAnalyzerArgs
  walk analyzer.json's pre-summarized per-asset data directly, with no
  WebpackStatsProcessor pipeline needed.

Preserved (still exported, still functional, no longer used by
ADOSizeComparator):
- getStatsFileFromZip / getStatsFileFromFileSystem — the msp.gz readers.
- getBundleFilePathsFromFolder still detects *.msp.gz +
  bundleBuddyConfig.json.
- getBundleSummaries with its original (statsProcessors, getStatsFile,
  getBundleBuddyConfigFile) args.
- DefaultStatsProcessors and the stats-processor library remain available.

Output is byte-equivalent to today: BundleMetric remains parsedSize-only;
no JSON-shape changes for downstream consumers (build-cli's
bundleSizeDiff command, the FF-internal telemetry handler).

Net effect on the public-API surface: additions only — no removed or
modified exports.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

Hi! Thank you for opening this PR. Want me to review it?

Based on the diff (235 lines, 11 files), I've queued these reviewers:

  • Correctness — logic errors, race conditions, lifecycle issues
  • Security — vulnerabilities, secret exposure, injection
  • API Compatibility — breaking changes, release tags, type design
  • Performance — algorithmic regressions, memory leaks
  • Testing — coverage gaps, hollow tests

How this works

  • Adjust the reviewer set by ticking/unticking boxes above. Reviewer toggles alone don't trigger anything.

  • Tick Start review below to dispatch the review fleet.

  • After review finishes, tick Start review again to request another run — it auto-resets after each dispatch.

  • This comment updates as new commits land; your reviewer selections are preserved.

  • Start review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

On it! Starting review with: Correctness, Security, API Compatibility

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 4, 2026

🔭 PR Review Fleet Report

Note

This report is generated by an experimental AI review fleet and is provided as a beta feature. Findings are a starting point for discussion, not a gate. Use your own judgement.

Verdict: ❌ Request Changes

0 Exterminate, 1 Squash, 2 Investigate

Findings

Sev # Area File What Fix
🦟 Squash H1 API Compatibility build-tools/packages/bundle-size-tools/package.json:57 BundleAnalyzerPlugin.JsonReport from @types/webpack-bundle-analyzer is exposed directly in three public API signatures — the return types of getAnalyzerJsonFromFileSystem and getAnalyzerJsonFromZip, and the getAnalyzerJson property type of GetBundleSummariesFromAnalyzerArgs. However, @types/webpack-bundle-analyzer is listed only in devDependencies, so it will not be installed when a consumer installs this package. Any TypeScript consumer that references these APIs will fail to resolve the BundleAnalyzerPlugin namespace, producing compile errors. Either move @types/webpack-bundle-analyzer from devDependencies to dependencies, or avoid leaking the external type in the public surface by defining a local structural alias (e.g. export type AnalyzerJsonReport = { label: string; parsedSize: number; isAsset?: boolean; ... }[]) and using that in the public signatures instead.
🐜 Investigate M1 API Compatibility build-tools/packages/bundle-size-tools/src/ADO/getBundleFilePathsFromFolder.ts:60 getAnalyzerFilePathsFromFolder returns BundleFileData[] and populates the relativePathToStatsFile field with paths to analyzer.json files. The field name relativePathToStatsFile implies webpack stats output, not webpack-bundle-analyzer JSON output. Consumers reading IntelliSense on the returned objects will be misled about what the field contains, especially since getBundleSummariesFromAnalyzer then passes bundle.relativePathToStatsFile directly to getAnalyzerJson, hiding the semantic mismatch behind an unrelated field name. Add a dedicated field to BundleFileData (e.g. relativePathToAnalyzerFile?: string) for analyzer.json paths, or introduce a separate AnalyzerFileData type. This keeps the data shape self-documenting and avoids conflating two different file formats under one field name.
🐜 Investigate M2 API Compatibility build-tools/packages/bundle-size-tools/src/ADO/getBundleSummaries.ts:297 GetBundleSummariesFromAnalyzerArgs is @public (undocumented) — neither the interface nor its two properties (bundlePaths, getAnalyzerJson) carry JSDoc. A consumer reading IntelliSense on getBundleSummariesFromAnalyzer cannot tell what contract getAnalyzerJson must satisfy (error handling, whether the path is relative or absolute, expected JSON shape) or what bundlePaths should contain. Add JSDoc to the interface and both properties, documenting the path convention (relative vs. absolute), the expected JSON shape, and error-handling expectations. This is consistent with how the existing GetBundleSummariesArgs should also be documented, but the new interface should not add to the undocumented surface.

View workflow run

@ChumpChief ChumpChief marked this pull request as ready for review May 4, 2026 21:54
@ChumpChief
Copy link
Copy Markdown
Contributor Author

I'm planning to skip the Fleet feedback as these will all become internal and/or change further in the followups. Primary goal of this PR is just to start producing the analyzer.json which is more generally useful.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the bundle size diff pipeline to produce and consume webpack-bundle-analyzer’s analyzerMode: "json" output (analyzer.json) as a smaller, pre-summarized input for bundle size comparisons, while keeping the legacy bundleStats.msp.gz path exported for now.

Changes:

  • Emit bundleAnalysis/analyzer.json during bundle-size test builds (alongside existing HTML/JSON stats outputs).
  • Add analyzer.json discovery + readers and a new getBundleSummariesFromAnalyzer() path in @fluidframework/bundle-size-tools.
  • Switch ADOSizeComparator to use analyzer.json summaries instead of the bundleStats.msp.gz/stats-processor pipeline.

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
examples/utils/bundle-size-tests/webpack.config.cjs Adds a second BundleAnalyzerPlugin instance to emit analyzer.json alongside existing artifacts.
build-tools/pnpm-lock.yaml Locks the newly added @types/webpack-bundle-analyzer dependency.
build-tools/packages/bundle-size-tools/src/index.ts Re-exports new analyzer.json APIs from the package entrypoint.
build-tools/packages/bundle-size-tools/src/ADO/index.ts Re-exports new analyzer.json APIs from the ADO sub-entrypoint.
build-tools/packages/bundle-size-tools/src/ADO/getBundleSummaries.ts Introduces getBundleSummariesFromAnalyzer() and related args type.
build-tools/packages/bundle-size-tools/src/ADO/getBundleFilePathsFromFolder.ts Adds getAnalyzerFilePathsFromFolder() for analyzer.json discovery.
build-tools/packages/bundle-size-tools/src/ADO/FileSystemBundleFileProvider.ts Adds filesystem path discovery + JSON parsing for analyzer.json.
build-tools/packages/bundle-size-tools/src/ADO/AdoSizeComparator.ts Switches comparator implementation to analyzer.json-based summaries.
build-tools/packages/bundle-size-tools/src/ADO/AdoArtifactFileProvider.ts Adds zip path discovery + JSON parsing for analyzer.json.
build-tools/packages/bundle-size-tools/package.json Adds @types/webpack-bundle-analyzer (devDependency).
build-tools/packages/bundle-size-tools/api-report/bundle-size-tools.api.md Updates API report to include newly exported analyzer.json APIs/types.
Files not reviewed (1)
  • build-tools/pnpm-lock.yaml: Language not supported

Comment thread examples/utils/bundle-size-tests/webpack.config.cjs Outdated
After this PR's consumer migration, `flub generate bundleSizeDiff` reads
analyzer.json instead of bundleStats.msp.gz. The producer-only commit was
cherry-picked from a state where only the producer was changing, so it
intentionally avoided naming `flub generate bundleSizeDiff` as a consumer
of analyzer.json (true at the time) and listed it among consumers of
bundleStats.msp.gz (also true at the time). Both claims become inverted
once the consumer commit is in.

- analyzer.json block: now names `flub generate bundleSizeDiff` as the
  concrete consumer.
- bundleStats.msp.gz block: drops `flub generate bundleSizeDiff` from the
  consumer list, leaving the FF-internal telemetry handler as the sole
  remaining consumer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants