Skip to content

Fix "Size-limit action shows "—" diff instead of percentage in Version Packages PR"#363

Merged
yamcodes merged 3 commits intomainfrom
cursor/respond-to-github-message-02d4
Nov 11, 2025
Merged

Fix "Size-limit action shows "—" diff instead of percentage in Version Packages PR"#363
yamcodes merged 3 commits intomainfrom
cursor/respond-to-github-message-02d4

Conversation

@yamcodes
Copy link
Owner

@yamcodes yamcodes commented Nov 10, 2025

Extract size data from failed size-limit checks and mark Node.js built-in modules as external to fix '—' output and bundling errors.

The "—" output occurred because the action would exit early if size-limit failed, preventing the extraction of size data needed for comparison. By parsing the JSON output even on failure, we can still get the size information. The bundling errors were due to size-limit (using esbuild) attempting to bundle Node.js core modules, which are external to browser/frontend bundles. Explicitly marking them as external resolves this.

Closes #362


Open in Cursor Open in Web

Summary by CodeRabbit

  • Bug Fixes

    • Size checks now attempt to parse and return results even if the check process exits with an error; clearer per-result and error logging prevents silent failures.
    • Added a robust fallback parsing path to handle varied output formats.
  • Improvements

    • Enhanced default size-check configuration to better ignore built-in modules and enforce consistent bundling behavior for Node packages.

Co-authored-by: yamyam263 <yamyam263@gmail.com>
@cursor
Copy link

cursor bot commented Nov 10, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@changeset-bot
Copy link

changeset-bot bot commented Nov 10, 2025

⚠️ No Changeset found

Latest commit: 179c9b1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Nov 10, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
arkenv Ready Ready Preview Comment Nov 11, 2025 3:36pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Enhanced size-limit runner: when webpack isn't enabled, derive an enhanced config forcing esbuild and marking Node.js built-ins as external/ignored; replace the temp package.json size-limit entry with this config; run size-limit while attempting JSON parse of stdout/stderr even on non-zero exit, fallback to text parsing, log results and return any found results, preserving cleanup.

Changes

Cohort / File(s) Summary
Size-limit action implementation
\.github/actions/size-limit/src/size-limit/package\.ts
Derive and inject an enhanced size-limit config when webpack is not enabled (force esbuild / webpack: false), extend the Node.js builtins ignore/external list, replace the temporary package.json size-limit entry with the enhanced config, run size-limit tolerating non-zero exits, attempt JSON parsing from stdout/stderr first and fall back to text parsing, log per-result details and return results even if the process exited non-zero; maintain existing restore/cleanup steps.

Sequence Diagram(s)

sequenceDiagram
    participant Action
    participant CLI as size-limit CLI
    participant Parser as Output Parser
    participant Logger

    rect rgba(220,240,200,0.20)
    Note over Action,CLI: Build enhanced config (esbuild, builtins externals) and replace temp package.json entry
    Action->>CLI: spawn size-limit with temp package.json using enhanced config
    CLI-->>Action: exit code (0 or non-zero) + output (stdout/stderr)
    end

    rect rgba(200,220,240,0.16)
    Note over Action,Parser: Parse outputs regardless of exit code
    Action->>Parser: try parse JSON from stdout and stderr
    alt JSON parsed
        Parser-->>Action: results[]
        Action->>Logger: log per-result details (even if exit ≠ 0)
        Action-->>Action: return results
    else JSON fail
        Action->>Parser: fallback to text parsing
        Parser-->>Action: results[] or []
        Action->>Logger: log outcome / errors
        Action-->>Action: return results or []
    end
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Pay attention to:
    • JSON parsing from both stdout and stderr and mixed-content edge cases
    • The code that replaces the temp package.json size-limit entry with the enhanced config
    • The expanded Node.js builtins external/ignore list correctness for Node-targeted packages
    • Logging behavior for non-zero exits to ensure useful diagnostics without sensitive output

Suggested labels

infra

Poem

🐇 I nudged the config, chose esbuild for the run,
I told builtins to hide so bundling's not undone.
When the CLI grumbles, I still read what it said,
I gather results bravely, even when exit bled.
Hop — baseline kept, no diff left unread.

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main fix: resolving the "—" diff display issue in Version Packages PR size-limit checks, which is the core problem addressed in the PR.
Linked Issues check ✅ Passed The PR successfully addresses all three coding objectives from #362: parsing JSON output on size-limit failure to extract size data for baseline comparison, preventing Node.js core module resolution errors by marking them as external, and improving error handling to distinguish failed checks from no results.
Out of Scope Changes check ✅ Passed All changes in .github/actions/size-limit/src/size-limit/package.ts are directly scoped to the linked issue requirements: enhanced config generation for Node.js built-ins, JSON output parsing on failure, and post-parse result handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch cursor/respond-to-github-message-02d4

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7cdc0e0 and 179c9b1.

📒 Files selected for processing (1)
  • .github/actions/size-limit/src/size-limit/package.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
.github/actions/size-limit/src/size-limit/package.ts (2)
.github/actions/size-limit/src/types.ts (1)
  • SizeLimitResult (1-8)
.github/actions/size-limit/src/utils/parser.ts (1)
  • parseSizeLimitOutput (6-233)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: test-e2e (a11y)
🔇 Additional comments (2)
.github/actions/size-limit/src/size-limit/package.ts (2)

95-111: The ignore array handling correctly preserves existing values.

The enhancement logic properly normalizes config.ignore by:

  • Spreading arrays as-is
  • Wrapping non-array values (strings, RegExp) in an array
  • Handling undefined with an empty array

This ensures existing ignore configurations are preserved regardless of type before adding Node.js built-ins.


201-252: The fallback parsing logic correctly extracts size data from failed checks.

The implementation now:

  1. Attempts JSON parsing from stdout regardless of exit code, since size-limit returns valid JSON even when limits are exceeded (passed: false)
  2. Falls back to text parsing if JSON parsing fails
  3. Returns extracted results even when exit code is non-zero, enabling baseline comparisons
  4. Logs results and errors appropriately for debugging

This directly addresses the PR objective of preventing "—" diffs by extracting size data from failed checks.


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

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions bot added the github actions Pull requests that update GitHub Actions code label Nov 10, 2025
@yamcodes yamcodes marked this pull request as ready for review November 10, 2025 19:48
@yamcodes
Copy link
Owner Author

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Nov 10, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@yamcodes yamcodes changed the title Respond to github message Fix "Size-limit action shows "—" diff instead of percentage in Version Packages PR" Nov 10, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 56f434f and 6917dcd.

📒 Files selected for processing (1)
  • .github/actions/size-limit/src/size-limit/package.ts (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
.github/actions/size-limit/src/size-limit/package.ts (2)
.github/actions/size-limit/src/types.ts (1)
  • SizeLimitResult (1-8)
.github/actions/size-limit/src/utils/parser.ts (1)
  • parseSizeLimitOutput (6-233)
🔇 Additional comments (3)
.github/actions/size-limit/src/size-limit/package.ts (3)

122-122: LGTM!

Correctly uses the enhanced configuration with Node.js externals.


197-248: Excellent error handling for non-zero exit codes!

The implementation correctly addresses the PR objective by extracting size data even when size-limit fails. The flow is logical:

  1. Parse JSON output regardless of exit code
  2. Fallback to text parsing if JSON fails
  3. Return results when available, even with non-zero exit
  4. Log detailed information for debugging

The concatenation of stdout + stderr on line 221 for text parsing is a reasonable fallback, though the order of interleaved output might vary.


51-93: I need the actual complete module lists from Node.js v22 and v23 to compare. Let me search for these:

The review comment is based on a misunderstanding of Node.js module architecture.

The official Node.js documentation notes that the module.builtinModules list doesn't contain prefix-only modules like node:test, and this is by design. The node:sqlite module must be imported using the node: prefix, and node:sea is accessed via require('node:sea') for Single Executable Applications.

Some built-in modules must be requested with the node: prefix to prevent newly introduced built-in modules from conflicting with userland packages that already took the name. The list in the code (lines 51-93) contains modules that can be required without the prefix, which semantically aligns with how module.builtinModules works.

The modules you mentioned (node:test, node:sqlite, node:sea) are deliberately excluded from such lists because they require the prefix and are never accessible without it. Including them would be architecturally incorrect.

Likely an incorrect or invalid review comment.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 40 to 105
// Enhance size-limit config to mark Node.js built-in modules as external
// This prevents bundling errors when size-limit tries to bundle Node.js built-in modules
const enhancedSizeLimitConfig = sizeLimitConfig.map((config) => {
// If webpack is already configured, preserve it
if (config.webpack !== undefined) {
return config;
}

// For Node.js packages, configure esbuild to mark Node.js built-in modules as external
// This prevents esbuild from trying to bundle node:path, node:fs, etc.
// size-limit uses esbuild when webpack: false, and we can configure externals
const nodeBuiltinModules = [
"assert",
"async_hooks",
"buffer",
"child_process",
"cluster",
"console",
"constants",
"crypto",
"dgram",
"diagnostics_channel",
"dns",
"domain",
"events",
"fs",
"http",
"http2",
"https",
"inspector",
"module",
"net",
"os",
"path",
"perf_hooks",
"process",
"punycode",
"querystring",
"readline",
"repl",
"stream",
"string_decoder",
"sys",
"timers",
"tls",
"trace_events",
"tty",
"url",
"util",
"v8",
"vm",
"worker_threads",
"zlib",
];

return {
...config,
webpack: false, // Use esbuild instead of webpack
// Configure esbuild to mark Node.js built-in modules as external
// This tells esbuild not to try to bundle these modules
// size-limit passes this to esbuild's external option
ignore: [
...(Array.isArray(config.ignore) ? config.ignore : []),
...nodeBuiltinModules.map((m) => `node:${m}`),
...nodeBuiltinModules,
],

Choose a reason for hiding this comment

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

P1 Badge Preserve existing ignore values when enhancing config

The new mapping only keeps config.ignore when it is already an array. size-limit accepts ignore as a string or RegExp as well, and several configs in the ecosystem rely on that shorthand. With the current logic any non‑array value is dropped entirely, so previously ignored packages will suddenly be bundled and counted in the size calculation, defeating the original configuration. Normalise single values (e.g. wrap in an array) rather than clearing them.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

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

@coderabbitai is this solved?

Copy link
Contributor

Choose a reason for hiding this comment

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

@yamcodes No, this issue is not solved in the current code.

Looking at lines 102-106 of the file, the code currently does:

ignore: [
    ...(Array.isArray(config.ignore) ? config.ignore : []),
    ...nodeBuiltinModules.map((m) => `node:${m}`),
    ...nodeBuiltinModules,
],

This drops any non-array ignore values (strings, RegExp, etc.). The fix should normalize single values by wrapping them in an array:

ignore: [
    ...(config.ignore 
        ? (Array.isArray(config.ignore) ? config.ignore : [config.ignore]) 
        : []
    ),
    ...nodeBuiltinModules.map((m) => `node:${m}`),
    ...nodeBuiltinModules,
],

This ensures that:

  • If config.ignore is an array → use it as-is
  • If config.ignore is a string or RegExp → wrap it in an array
  • If config.ignore is undefined → use an empty array

This preserves the original ignore configuration regardless of its type.

Comment on lines 40 to 107
// Enhance size-limit config to mark Node.js built-in modules as external
// This prevents bundling errors when size-limit tries to bundle Node.js built-in modules
const enhancedSizeLimitConfig = sizeLimitConfig.map((config) => {
// If webpack is already configured, preserve it
if (config.webpack !== undefined) {
return config;
}

// For Node.js packages, configure esbuild to mark Node.js built-in modules as external
// This prevents esbuild from trying to bundle node:path, node:fs, etc.
// size-limit uses esbuild when webpack: false, and we can configure externals
const nodeBuiltinModules = [
"assert",
"async_hooks",
"buffer",
"child_process",
"cluster",
"console",
"constants",
"crypto",
"dgram",
"diagnostics_channel",
"dns",
"domain",
"events",
"fs",
"http",
"http2",
"https",
"inspector",
"module",
"net",
"os",
"path",
"perf_hooks",
"process",
"punycode",
"querystring",
"readline",
"repl",
"stream",
"string_decoder",
"sys",
"timers",
"tls",
"trace_events",
"tty",
"url",
"util",
"v8",
"vm",
"worker_threads",
"zlib",
];

return {
...config,
webpack: false, // Use esbuild instead of webpack
// Configure esbuild to mark Node.js built-in modules as external
// This tells esbuild not to try to bundle these modules
// size-limit passes this to esbuild's external option
ignore: [
...(Array.isArray(config.ignore) ? config.ignore : []),
...nodeBuiltinModules.map((m) => `node:${m}`),
...nodeBuiltinModules,
],
};
});

Choose a reason for hiding this comment

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

P1 Badge Do not unconditionally switch size-limit bundles to esbuild

When no webpack property is provided, the code now forces webpack: false, which means size-limit will run with the esbuild plugin even for packages whose default preset is webpack (e.g. those depending on @size-limit/preset-small-lib). That change drops webpack-specific behaviour such as Babel loaders or aliases and can produce different bundle contents or outright bundling failures unrelated to the original issue. If the goal is only to externalise Node built-ins, consider extending the existing configuration without changing the bundler, or restrict the change to configs that were already using esbuild.

Useful? React with 👍 / 👎.

Copy link
Owner Author

Choose a reason for hiding this comment

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

@coderabbitai is this solved?

Copy link
Contributor

Choose a reason for hiding this comment

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

@yamcodes No, the concern raised by the bot is not fully solved.

Looking at the current code (lines 42-44 in the file), the condition checks:

if (config.webpack === true) {
    return config;
}

This only preserves the original config when webpack is explicitly set to true. When webpack is undefined (not specified), the code proceeds to force webpack: false, which changes the default bundler behavior for packages that rely on preset defaults (like @size-limit/preset-small-lib which uses webpack by default).

The issue: This unconditionally switches all configs without an explicit webpack: true to use esbuild, potentially breaking packages that depend on webpack-specific features.

Suggested fix: Change line 42 to preserve any existing webpack configuration:

// If webpack is already configured (true or false), preserve it
if (config.webpack !== undefined) {
    return config;
}

This way:

  • Configs with webpack: true → preserved (uses webpack)
  • Configs with webpack: false → preserved (already using esbuild)
  • Configs with webpack: undefined → preserved (uses preset default, typically webpack)

Only when webpack is truly undefined would the enhancement apply, but we should reconsider whether forcing esbuild in that case is correct. The safer approach might be to only add the Node.js built-ins to the ignore array without changing the webpack setting at all.

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
- Fixes bundling with undefined ignore
- Add node: prefix to node modules
@yamcodes yamcodes merged commit cbb85cc into main Nov 11, 2025
15 checks passed
@yamcodes yamcodes deleted the cursor/respond-to-github-message-02d4 branch November 11, 2025 16:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

github actions Pull requests that update GitHub Actions code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Size-limit action shows "—" diff instead of percentage in Version Packages PR

2 participants