Skip to content

chore(claude): add an agent explaining bundle size changes - #1307

Merged
redfish4ktc merged 8 commits into
mainfrom
chore/add-bundle-impact-analyst-agent
Nov 2, 2026
Merged

redfish4ktc merged 8 commits into
mainfrom
chore/add-bundle-impact-analyst-agent

Conversation

@redfish4ktc

@redfish4ktc redfish4ktc commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

Overview

The pr-bundle-size skill says how much each example grew, never why. Finding the cause meant running build:analyze on two refs and comparing two reports in a browser, so a growth was often reported, or a size budget raised, without naming what grew.

This PR adds the bundle-impact-analyst agent, candidate 5 of analysis 003, and the machine-readable analysis it needs. Given one or more examples and a reference, it reports the modules that entered, left or changed size, and the chain of imports from the example that pulled each new module in.

A JSON mode for the bundle analysis

Both analyzers only started a report server, Rsdoctor for webpack and vite-bundle-analyzer for Vite. ANALYZE=json now writes dist/bundle-analysis.json and starts nothing. Like ANALYZE=true, it disables the size budget, since an analysis is a diagnostic. The regular npm run build is unchanged, and still enforces the budgets.

  • Vite: the analyzer has a JSON mode, giving each module's size in the minified chunk. The analysis switch moves to scripts/vite/bundle-analysis.mjs, shared by the three vite.config.js, which each held a copy of it.
  • webpack: the brief JSON report of Rsdoctor 1.6 came out with an empty module graph, and the webpack stats give the importers of top-level modules only, while most of @maxgraph/core is concatenated into a single module. A small plugin in scripts/webpack/bundle-analysis.cjs reads the module graph of the compilation instead. It keeps only the modules of the chunks, since the compilation also holds those that tree shaking dropped. Its sizes are before minification, so the real change is read on the output file.

The agent

.claude/agents/bundle-impact-analyst.md, Sonnet, Bash, Read, Glob, Grep.

  • Head: the current checkout, after checking the installed toolchain against the lock file with ci-bundle-sizes.sh local-toolchain. It never runs npm install there.
  • Reference: built in a temporary git worktree with its own npm ci, outside the repository so that no IDE indexes it, and always removed afterwards. The checkout of the user is never switched. A reference older than the JSON mode is refused rather than patched.
  • Comparison: .claude/shared/bundle-sizes/compare-bundle-analyses.mjs, a script next to ci-bundle-sizes.sh rather than code in the prompt, so that it can be run and tested alone. It handles both formats. vite-bundle-analyzer names importedBy the list of modules a module imports, so the script inverts it.
  • Reporting follows the reading rules of the shared README: raw minified kB, largest changes first, toolchain differences reported as part of the change.

The install and the builds take a few minutes and load the machine, so the agent's description asks the caller to warn the user first. The pr-bundle-size skill and the bundle size budgets rule point at the agent.

How it was verified

  • All six examples build with ANALYZE=json and write their file. A regular build writes neither the file nor source maps, and gives the same webpack bundle, same content hash.
  • The comparison script, run between *-without-defaults and *-selected-features, finds the plugins the latter registers, with chains matching their sources, such as src/index.js -> SelectionCellsHandler.js -> EdgeHandler.js.
  • A blind run of the agent, against an answer written before it: a scratch commit adding TooltipHandler to the plugins of js-example-selected-features and ts-example-selected-features, compared with the commit before it.
Expected Agent
TooltipHandler.js added, the largest change yes, in both examples
chain from the example src/index.js -> TooltipHandler.js, and src/main.ts (through the @maxgraph/core entry point) -> TooltipHandler.js
both examples grow by a few kB +3.37 kB (webpack), +3.78 kB (Vite)
no toolchain difference none
worktree removed, checkout untouched yes

35.8k tokens, 6 tool calls, 198 s, the npm ci and the six builds included.

The run, made before the last commit, left one change unexplained: util/styleUtils.js grew by 467 bytes in the Vite example although its source did not change. TooltipHandler imports fit and getScrollOrigin from it, so tree shaking kept two more functions. A later commit tells the agent to check for this case; it has not been run again since.

The fixes made after the CodeRabbit review came after that run too. The two fixes of the comparison script, the import chain searched through every path and the imports of a Vite module found in several output files, were checked on synthetic analyses against the previous version of the script. To tell a changed source from a tree shaking effect, the agent now compares the reference with the working tree, not with HEAD, and on the TypeScript source of the module rather than on its compiled .js name, which matched no file and made every source look unchanged.

Review comments not applied

Two comments of the CodeRabbit review on 4f906c7, posted outside the diff, were checked and not applied.

  • The Vite sizes are not bytes of the minified chunk. They are. On the ts-example report, the parsedSize of the modules of the maxgraph chunk add up to 426,170 bytes, and the minified file on disk is 426,184 bytes. What the sizes leave out is the bytes the source map attributes to no module, a few hundred per chunk (764 bytes in the small index chunk). The script header and the agent now say so, in 8c88de6 and 403e13b.
  • An EXIT trap to clean the work directory. Each Bash call of the agent runs in its own shell, so the trap would fire at the end of the call creating the directory and remove it before any build. The agent keeps its explicit cleanup step, run also when a step failed.

Notes

  • Independent of chore(claude): add an mxGraph archaeologist agent #1302, which adds the mxgraph-archaeologist agent.
  • package-lock.json on main is out of sync with the version ranges of some package.json files (^ against ~ for storybook and webpack-dev-server), so npm install rewrites it. The installed versions are not affected, and this PR does not change the lock file.

Summary by CodeRabbit

  • New Features
    • Supported build tools can generate JSON bundle reports with output-file sizes and module-level details.
    • Compare bundle reports across revisions to see size changes and import paths for added modules.
    • A bundle-impact workflow can build both revisions and summarize their differences, with user approval before lengthy builds.
  • Improvements
    • Bundle-size limits are consistently enforced across example builds when analysis is not enabled.
    • Development and analysis builds no longer trigger production bundle-size warnings.

The analysis of the examples could only be read in a browser: both build:analyze setups start a report server,
Rsdoctor for webpack and vite-bundle-analyzer for Vite. Comparing two builds, to find what made an example grow, meant
opening two reports and diffing them by eye, which a script or an agent cannot do.

ANALYZE=json now writes dist/bundle-analysis.json and starts nothing. Each module carries its size and the modules
that import it, which is what explaining a growth needs. Like ANALYZE=true, it disables the size budget, since an
analysis is a diagnostic.

- Vite: the analyzer has a json mode giving the size of each module in the minified chunk. The analysis switch moves
  to scripts/vite/bundle-analysis.mjs, shared by the three configurations, which each held a copy of it.
- webpack: the brief JSON report of Rsdoctor 1.6 came out with an empty module graph, and the webpack stats give the
  importers of top level modules only, while most of @maxgraph/core is concatenated into a single module. A small
  plugin reads the module graph of the compilation instead. It keeps the modules of the chunks only, as the
  compilation also holds those that tree shaking left out, and the imports that tree shaking kept. Its sizes are
  before minification.
The pr-bundle-size skill says how much each example changed, never why. Finding the cause meant building both refs by
hand and comparing their analyses, so a growth was often reported, or a size budget raised, without naming what grew.

bundle-impact-analyst builds the example on both refs with ANALYZE=json and compares the two analyses. It reports the
modules added, removed or resized and, for each new module, the chain of imports from the example that pulled it in.
The reference is built in a temporary git worktree with its own install, outside the repository so that no IDE
indexes it, and removed afterwards: the checkout of the user is never switched, and its dependencies never reinstalled.
That costs several minutes, so the agent asks the caller to warn the user first. Sonnet is enough: the work is running
builds and reading a comparison, with judgement only on what to report.

The comparison is a script next to ci-bundle-sizes.sh rather than code in the prompt of the agent, so that it can be
run and tested on its own. It handles both formats, and follows the reading rules of the shared README.
On its validation run, adding TooltipHandler to an example, the agent found every change but left one unexplained:
util/styleUtils.js grew by 467 bytes although its source was the same on both refs. The prompt only said that a
resized module of @maxgraph/core is a change of its code, which was false here. TooltipHandler imports fit and
getScrollOrigin from that module, so tree shaking kept two more functions of it.

The agent now checks whether the source of a resized module changed, and when it did not, looks for the added or
removed module that imports from it. A few bytes with no such import are the minifier renaming variables.
@redfish4ktc redfish4ktc added the chore Build, CI/CD or repository tasks (issues/PR maintenance, environments, ...) label Nov 2, 2026
@coderabbitai

coderabbitai Bot commented Nov 2, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Walkthrough

The PR adds JSON bundle-analysis modes for webpack and Vite, a script to compare their reports, and an agent workflow that builds and compares named examples across refs. The Vite example configurations now use a shared helper to select analysis or size-limit behavior.

Changes

Bundle analysis and comparison

Layer / File(s) Summary
Generate bundle-analysis output
scripts/webpack/bundle-analysis.cjs, scripts/vite/bundle-analysis.mjs, packages/ts-example*/vite.config.js, packages/ts-example-selected-features/vite.config.js, .claude/rules/tooling/bundle-size-budgets.md
Webpack and Vite add JSON analysis modes. The three Vite example configurations use a shared helper for analysis and size-limit plugin selection. The budget guidance describes analysis modes and enforcement behavior.
Compare analysis files
.claude/shared/bundle-sizes/compare-bundle-analyses.mjs
The script compares output-file and module sizes from webpack or Vite reports and lists import chains for added modules.
Build and explain changes
.claude/agents/bundle-impact-analyst.md, .claude/skills/pr-bundle-size/SKILL.md, .claude/shared/bundle-sizes/README.md, .claude/rules/tooling/bundle-size-budgets.md
The agent instructions describe building examples on the working tree and a reference worktree, comparing reports, and reporting results after cleanup. The skill, README, and budget guidance describe using the agent to investigate size changes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant Analyst as bundle-impact-analyst
  participant Head as Working-tree build
  participant Reference as Reference-worktree build
  participant Compare as compare-bundle-analyses.mjs
  Analyst->>Head: Build examples and produce analysis JSON
  Analyst->>Reference: Build examples in temporary worktree and produce analysis JSON
  Head->>Compare: Provide working-tree analysis
  Reference->>Compare: Provide reference analysis
  Compare-->>Analyst: Return size differences, module changes, and import chains
Loading

Possibly related PRs

  • maxGraph/maxGraph#1296: Changes bundle-size limits that flow into the Vite and webpack budget paths updated here.
Merge Risk: Moderate · up to 4f906

The new bundle-analysis workflow can produce misleading or incomplete comparisons and leave temporary worktrees after failures; these issues should be corrected before merging.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Description check Warning The description provides a detailed and relevant overview, implementation summary, verification results, and notes. However, it omits the required PR Checklist section and does not explicitly address … Add the repository PR Checklist with each item checked or explained. State whether an issue is addressed, whether maintainers assigned the work, whether screenshots or videos are relevant, and whether documentation changes are complete. Pro…
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title is concise, follows Conventional Commits syntax, and clearly identifies the main change: adding an agent that explains bundle size changes.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 6 files. (1 skipped: 1 unsupported.)

Full details: Description check

Explanation

The description provides a detailed and relevant overview, implementation summary, verification results, and notes. However, it omits the required PR Checklist section and does not explicitly address issue linkage, maintainer assignment, screenshots or videos, documentation status, or the Conventional Commits title requirement.

Resolution

Add the repository PR Checklist with each item checked or explained. State whether an issue is addressed, whether maintainers assigned the work, whether screenshots or videos are relevant, and whether documentation changes are complete. Provide or confirm a Conventional Commits-compliant PR title.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@coderabbitai coderabbitai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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


Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 13355d37-920b-497f-9ef7-d4efa8450f91
Commits

Reviewing files that changed from the base of the PR and between 56dafd6 and 4dd4459.

Files selected for processing: 10
  • .claude/agents/bundle-impact-analyst.md
  • .claude/rules/tooling/bundle-size-budgets.md
  • .claude/shared/bundle-sizes/README.md
  • .claude/shared/bundle-sizes/compare-bundle-analyses.mjs
  • .claude/skills/pr-bundle-size/SKILL.md
  • packages/ts-example-selected-features/vite.config.js
  • packages/ts-example-without-defaults/vite.config.js
  • packages/ts-example/vite.config.js
  • scripts/vite/bundle-analysis.mjs
  • scripts/webpack/bundle-analysis.cjs

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 3 remain after this review.

Comment thread .claude/agents/bundle-impact-analyst.md Resolved
The search of the import chain stopped at the first module of @maxgraph/core that nothing in the bundle imports, and
reported the @maxgraph/core entry point as the origin. When the same module was also reachable from a module of the
example, that more precise chain was never found. The importer-free chain is now kept only as a fallback, used when no
path reaches the example.

A Vite module found in several output files kept the imports of its last leaf only, which could drop the import that
brought a new module in, and leave it with no importer at all. The imports of all its leaves are now merged, as the
sizes already were.
The head build includes the uncommitted edits of the working tree, but the check telling a changed source from a tree
shaking effect compared the reference with HEAD, which excludes them. A module resized by an uncommitted edit was then
attributed to tree shaking. Comparing the reference with the working tree covers both.
Comment thread .claude/agents/bundle-impact-analyst.md Resolved
The comparison names a module of @maxgraph/core by its compiled file, core/lib/esm/util/styleUtils.js, and the agent
passed that path under packages/core/src unchanged. git diff on a file that does not exist prints nothing, exactly as
for an unchanged source, so a real source edit could be blamed on tree shaking. The agent now maps the prefix and the
extension to the TypeScript source, and checks that the file exists before reading an empty diff as no change.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to GitHub limitations.

⚠️ Outside diff range comments (5)

Minor · Normalize webpack asset names before comparing them. · compare-bundle-analyses.mjs:58-60

.claude/shared/bundle-sizes/compare-bundle-analyses.mjs:58-60
Minor · Functional Correctness · Quick win

Normalize webpack asset names before comparing them.

The webpack reader copies [contenthash] into each asset name. When an asset changes, exact-name matching reports separate N/A rows instead of the asset size delta. Remove the hash segment when reading webpack assets.

Suggested fix
-  const files = json.assets.map(({ name, size }) => ({ name, size }));
+  const files = json.assets.map(({ name, size }) => ({
+    name: name.replace(/\.[a-f\d]+\.(?=[^.]+$)/, '.'),
+    size,
+  }));
Minor · Use the parsed-size meaning consistently in the Vite… · compare-bundle-analyses.mjs:103-110

.claude/shared/bundle-sizes/compare-bundle-analyses.mjs:103-110
Minor · Functional Correctness · Quick win

Use the parsed-size meaning consistently in the Vite comparison.

vite-bundle-analyzer@1.3.9 reports uncompressed bytes attributed through source maps. It does not report the bytes physically occupied by a minified chunk. Update both the comparator label and the bundle-impact-analyst instructions, or the agent can still describe the corrected value as raw minified output.

Suggested fix
-// Vite, ... each with its size in the minified chunk, 'parsedSize'.
+// Vite, ... each with its uncompressed parsed bytes attributed through source maps, 'parsedSize'.
...
-    sizeUnit: 'bytes in the minified chunk',
+    sizeUnit: 'uncompressed parsed bytes attributed to the chunk',

Update the corresponding Vite descriptions in .claude/agents/bundle-impact-analyst.md to use the same parsed-byte meaning.

Minor · Check the Vite and webpack helpers independently. · bundle-impact-analyst.md:45-49

.claude/agents/bundle-impact-analyst.md:45-49
Minor · Functional Correctness · Quick win

Check the Vite and webpack helpers independently.

The combined gate passes when only one helper supports ANALYZE=json. The agent then runs the unsupported bundler and can fail while copying its missing dist/bundle-analysis.json. Check each helper separately and stop when either check fails.

Suggested fix
-   git grep -q "'json'" <reference> -- scripts/vite/bundle-analysis.mjs scripts/webpack/bundle-analysis.cjs
+   git grep -q "'json'" <reference> -- scripts/vite/bundle-analysis.mjs
+   git grep -q "'json'" <reference> -- scripts/webpack/bundle-analysis.cjs
Minor · Stop on build failure and require a fresh analysis report… · bundle-impact-analyst.md:56-65

.claude/agents/bundle-impact-analyst.md:56-65
Minor · Stability & Availability · Quick win

Stop on build failure and require a fresh analysis report before copying.

A Vite example can fail during tsc before vite build writes bundle-analysis.json. The next unconditional cp can then copy an older report from dist or fail without identifying that the build produced no report. Remove the old report before the build, chain the copy to a successful build, and check that the new report is non-empty.

Suggested fix
-   ANALYZE=json npm run build -w packages/<example>
-   cp packages/<example>/dist/bundle-analysis.json <work dir>/head-<example>.json
+   rm -f packages/<example>/dist/bundle-analysis.json &&
+     ANALYZE=json npm run build -w packages/<example> &&
+     test -s packages/<example>/dist/bundle-analysis.json &&
+     cp packages/<example>/dist/bundle-analysis.json <work dir>/head-<example>.json
Minor · Install cleanup at work-directory creation. · bundle-impact-analyst.md:50-80

.claude/agents/bundle-impact-analyst.md:50-80
Minor · Stability & Availability · Quick win

Install cleanup at work-directory creation.

The temporary directory is created before the toolchain check, and the reference worktree is created before npm ci, builds, and comparisons. If any command fails and the agent stops before step 7, the temporary directory remains. Failures after git worktree add can also leave Git worktree metadata. Install an idempotent EXIT cleanup boundary so cleanup runs on both success and failure.

Suggested fix
-2. **Create a work directory outside the repository**, so that no IDE indexes the second install:
-   `mktemp -d`. Note its path, you need it in every later call.
+2. **Create a work directory outside the repository**, so that no IDE indexes the second install:
+   ```bash
+   work_dir="$(mktemp -d)"
+   cleanup() {
+     git worktree remove --force "$work_dir/reference" 2>/dev/null || true
+     rm -rf -- "$work_dir"
+   }
+   trap cleanup EXIT
+   ```
+   Use `$work_dir` in every later call.
...
-7. **Remove the worktree and the work directory, always**, also when a step above failed, before reporting:
-   `git worktree remove --force <work dir>/reference; rm -rf <work dir>; git worktree list`
+7. **Before reporting, check the worktree list if needed.** The `EXIT` trap performs cleanup on both success and failure.

Review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 300a3bb4-500f-42fe-83c7-5b83c1225dc4
Commits

Reviewing files that changed from the base of the PR and between 05254bf and 4f906c7.

Files selected for processing: 1
  • .claude/agents/bundle-impact-analyst.md

Included review availability: This review used your included allowance. Your plan provides up to 4 included reviews per hour; 1 remain after this review.

webpack names the bundle main.<contenthash>.js, and the hash changes with the content, which is the case under
analysis. The reference and head bundles never matched, so the output file table showed two N/A rows instead of the
change, although for webpack it is the only figure measured after minification. The hash is now removed from the
name, as it already was for Vite. Images named by their hash alone keep it, since nothing would be left of their name.

The comments also say what the Vite sizes leave out: the bytes the source map attributes to no module, a few hundred
per chunk, are counted in no module and in no output file.
- The check that the reference supports ANALYZE=json ran git grep on both helpers at once, which passes as soon as
  one of them matches: a reference where only one bundler had the mode got through, and its other builds wrote no
  report. Each helper is now checked on its own.
- A build failing before writing its report, in the tsc step of a Vite example for instance, left the report of an
  earlier build in dist, and the next cp copied it as if it were new. The report is now removed before the build and
  copied only after a successful build that wrote a non-empty one.
- The Vite sizes leave out the bytes mapped to no module, so the agent knows the output file table can be a few
  hundred bytes below the file on disk.

An EXIT trap cleaning the work directory was suggested and not added: each Bash call of the agent runs in its own
shell, so the trap would fire at the end of the call creating the directory and remove it before any build.
@redfish4ktc

Copy link
Copy Markdown
Member Author

@coderabbitai Answers to the 5 comments posted outside the diff in your review of 4f906c7:

  • Normalize webpack asset names: agreed, fixed in 8c88de6. Images named by their hash alone keep it, since nothing would be left of their name.
  • Check the Vite and webpack helpers independently: agreed, fixed in 403e13b.
  • Stop on build failure and require a fresh report: agreed, fixed in 403e13b. The report is removed before the build and copied only after a successful build that wrote a non-empty one.
  • Parsed-size meaning: not applied as suggested, the sizes are bytes of the minified chunk. The bytes mapped to no module are now documented. Details in the "Review comments not applied" section of the description.
  • EXIT trap cleanup: not applied, each Bash call of the agent runs in its own shell, so the trap would remove the work directory right after creating it. Details in the same section.

@sonarqubecloud

sonarqubecloud Bot commented Nov 2, 2026

Copy link
Copy Markdown

@coderabbitai

coderabbitai Bot commented Nov 2, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

Analysis chain

Script executed:

#!/bin/bash
set -euo pipefail
gh pr view 1307 --repo maxGraph/maxGraph --json body --jq .body
ast-grep outline .claude/shared/bundle-sizes/compare-bundle-analyses.mjs
sed -n '1,280p' .claude/shared/bundle-sizes/compare-bundle-analyses.mjs
sed -n '1,260p' .claude/agents/bundle-impact-analyst.md

Length of output: 25732


@redfish4ktc Thanks for the fixes and explanations. I checked the current script, agent instructions, and PR description.

The three fixes address the concerns:

  • Webpack asset names: named assets lose their content hash for comparison. Hash-only image names remain unchanged.
  • Reference support: the agent checks the Vite and webpack helpers separately.
  • Report freshness: the head report is removed before building. The agent copies it only after a successful build produces a non-empty report. Build failures lead to cleanup and error reporting.

I withdraw the other two suggestions:

  • Parsed-size meaning: my claim was incorrect. Vite reports minified bytes attributed through source maps. The documentation now explains the omitted, unattributed bytes and when to check the file on disk.
  • EXIT trap: a trap in the directory-creation call would run before later Bash calls could use the directory. Explicit cleanup across calls is appropriate here.

This was a source inspection. I did not rerun builds or the agent.


Learnings used
Learnt from: CR
Repo: maxGraph/maxGraph PR: 0
File: .claude/rules/tooling/bundle-size-budgets.md:0-0
Timestamp: 2026-10-27T10:31:31.483Z
Learning: Applies to packages/*-example*/vite.config.js : Source excerpt:
# Bundle Size Budgets

## Where the guard applies

Vite does not. `chunkSizeWarningLimit` only makes it log a warning, and the build still exits 0, so a regression ends up
as one line in a CI log that nobody reads. `scripts/vite/chunk-size-limit.mjs` therefore fails the build and names the
chunk and both sizes. Declare the limit once, in a `chunkSizeLimitInKB` constant, and pass it to both
`chunkSizeWarningLimit` and the plugin, so the two thresholds cannot be set to different values. That plugin is
registered instead of the analyzer, never alongside it: the analyzer is a post plugin, so the guard's error would abort
the build before any report is written.
Learnt from: CR
Repo: maxGraph/maxGraph PR: 0
File: .claude/rules/tooling/bundle-size-budgets.md:0-0
Timestamp: 2026-10-27T10:31:31.483Z
Learning: Applies to {packages/*-example*/vite.config.js,scripts/vite/chunk-size-limit.mjs} : Source excerpt:
# Bundle Size Budgets

## Where the guard applies

Vite does not. `chunkSizeWarningLimit` only makes it log a warning, and the build still exits 0, so a regression ends up
as one line in a CI log that nobody reads. `scripts/vite/chunk-size-limit.mjs` therefore fails the build and names the
chunk and both sizes. Declare the limit once, in a `chunkSizeLimitInKB` constant, and pass it to both
`chunkSizeWarningLimit` and the plugin, so the two thresholds cannot be set to different values. That plugin is
registered instead of the analyzer, never alongside it: the analyzer is a post plugin, so the guard's error would abort
the build before any report is written.
Learnt from: CR
Repo: maxGraph/maxGraph PR: 0
File: .claude/rules/tooling/bundle-size-budgets.md:0-0
Timestamp: 2026-10-27T10:31:31.483Z
Learning: Applies to scripts/vite/chunk-size-limit.mjs : Source excerpt:
# Bundle Size Budgets

## Where the guard applies

Vite does not. `chunkSizeWarningLimit` only makes it log a warning, and the build still exits 0, so a regression ends up
as one line in a CI log that nobody reads. `scripts/vite/chunk-size-limit.mjs` therefore fails the build and names the
chunk and both sizes. Declare the limit once, in a `chunkSizeLimitInKB` constant, and pass it to both
`chunkSizeWarningLimit` and the plugin, so the two thresholds cannot be set to different values. That plugin is
registered instead of the analyzer, never alongside it: the analyzer is a post plugin, so the guard's error would abort
the build before any report is written.
Learnt from: CR
Repo: maxGraph/maxGraph PR: 0
File: .claude/rules/tooling/bundle-size-budgets.md:0-0
Timestamp: 2026-10-27T10:31:31.483Z
Learning: Applies to scripts/webpack/bundle-analysis.cjs : Source excerpt:
# Bundle Size Budgets

## Where the guard applies

webpack fails the build on its own, so `scripts/webpack/bundle-analysis.cjs` keeps `hints` at `'error'` only when
neither exemption applies, `isDevMode || isBundleAnalysisEnabled ? false : 'error'`.

If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

You are interacting with an AI system.

@redfish4ktc
redfish4ktc merged commit a90eba9 into main Nov 2, 2026
12 checks passed
@redfish4ktc
redfish4ktc deleted the chore/add-bundle-impact-analyst-agent branch November 2, 2026 10:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

chore Build, CI/CD or repository tasks (issues/PR maintenance, environments, ...)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant