Skip to content

feat(external-bundle): emit css diagnostics#2563

Open
luhc228 wants to merge 1 commit into
mainfrom
fix/external-bundle-css-diagnostics
Open

feat(external-bundle): emit css diagnostics#2563
luhc228 wants to merge 1 commit into
mainfrom
fix/external-bundle-css-diagnostics

Conversation

@luhc228
Copy link
Copy Markdown
Collaborator

@luhc228 luhc228 commented May 6, 2026

image

Summary by CodeRabbit

  • New Features

    • Emit CSS diagnostics for external bundles and surface them as build warnings.
    • Return CSS diagnostics from bundle encoding to enable downstream handling.
  • Improvements

    • Generate CSS sourcemaps for external bundles to aid debugging.
    • Make CSS minification behavior explicit and configurable by default.
  • Tests

    • Expanded tests covering diagnostics propagation and default minification behavior.
  • Chores

    • Updated related build/test dependencies.

Checklist

  • Tests updated (or not required).
  • Documentation updated (or not required).
  • Changeset added, and when a BREAKING CHANGE occurs, it needs to be clearly marked (or not required).

Copilot AI review requested due to automatic review settings May 6, 2026 12:43
@luhc228 luhc228 requested review from colinaaa and upupming as code owners May 6, 2026 12:43
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Walkthrough

Adds CSS diagnostics propagation and processing to ExternalBundleWebpackPlugin: the encode callback may return css_diagnostics, which the plugin collects, maps via processTasmCSSDiagnostics, and emits as Webpack warnings. Also updates TASM/template-webpack-plugin dependencies, enables CSS sourcemaps, and adds tests and project references.

Changes

CSS Diagnostics Integration

Layer / File(s) Summary
Project Setup & Dependencies
.changeset/*, packages/rspeedy/lynx-bundle-rslib-config/package.json, packages/webpack/template-webpack-plugin/package.json
Changesets added for diagnostics and template TASM update; bumped @lynx-js/tasm 0.0.35→0.0.38; added @lynx-js/template-webpack-plugin dependency and a pnpm test script.
TypeScript Project References
packages/rspeedy/lynx-bundle-rslib-config/tsconfig.json, packages/rspeedy/lynx-bundle-rslib-config/tsconfig.build.json
Added references entries pointing at the template-webpack-plugin build tsconfig.
API Surface
packages/rspeedy/lynx-bundle-rslib-config/etc/lynx-bundle-rslib-config.api.md
ExternalBundleWebpackPluginOptions.encode return shape now optionally includes css_diagnostics?: unknown.
Plugin Core Implementation
packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts
Plugin now collects emittedCSSDiagnosticWarnings, accepts/propagates css_diagnostics from encode, processes diagnostics via processTasmCSSDiagnostics (imported from template-webpack-plugin), emits Webpack warnings, refactors #generateExternalBundle, and adds collectCSSSourceMapContents helper.
Build Configuration
packages/rspeedy/lynx-bundle-rslib-config/src/externalBundleRslibConfig.ts
Default external bundle minify config sets css: false; distPath.sourceMap extended to { css: true }.
Tests & Coverage
packages/rspeedy/lynx-bundle-rslib-config/test/external-bundle.test.ts
Added runExternalBundlePlugin test helper, reorganized imports, added tests for preserving css: false under minify and for CSS diagnostics propagation/emission.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • lynx-family/lynx-stack#2519: Implements the CSS diagnostics processing and source-map handling that this PR wires into ExternalBundleWebpackPlugin.
  • lynx-family/lynx-stack#2143: Prior changes to ExternalBundleWebpackPlugin's CSS handling that this PR extends with diagnostics.
  • lynx-family/lynx-stack#1943: Earlier adjustments to the plugin encode return shape which this PR further extends with css_diagnostics.

Suggested reviewers

  • upupming
  • colinaaa

Poem

🐰 A tiny rabbit hops with care and cheer,
I gather sourcemaps, warnings I make clear,
TASM stepped up, templates sing along,
CSS whispers turned to helpful song,
Bundles now report what once was unclear.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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.
Title check ✅ Passed The title 'feat(external-bundle): emit css diagnostics' directly and clearly summarizes the main change: adding CSS diagnostics emission to the external bundle webpack plugin.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/external-bundle-css-diagnostics

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


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.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 6, 2026

Codecov Report

❌ Patch coverage is 86.44068% with 8 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
...-config/src/webpack/ExternalBundleWebpackPlugin.ts 85.45% 8 Missing ⚠️

📢 Thoughts on this report? Let us know!

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 adds CSS encode diagnostic emission to the @lynx-js/lynx-bundle-rslib-config external bundle build flow by consuming css_diagnostics returned from TASM and converting them into webpack warnings (optionally source-mapped back to original files).

Changes:

  • Bump @lynx-js/tasm to 0.0.38 and wire in @lynx-js/template-webpack-plugin to reuse processTasmCSSDiagnostics.
  • Enhance ExternalBundleWebpackPlugin to collect CSS source maps, resolve/dedupe TASM CSS diagnostics, and push them into compilation.warnings with file/loc when available.
  • Update default external bundle output settings to enable CSS sourcemaps and disable CSS minification (with a note about sourcemap correctness), plus add a focused unit test for diagnostics emission.

Reviewed changes

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

Show a summary per file
File Description
pnpm-lock.yaml Updates lockfile for @lynx-js/tasm@0.0.38 and workspace link for @lynx-js/template-webpack-plugin.
packages/webpack/template-webpack-plugin/package.json Bumps TASM dependency to 0.0.38.
packages/rspeedy/lynx-bundle-rslib-config/tsconfig.json Adds TS project reference to template webpack plugin build config.
packages/rspeedy/lynx-bundle-rslib-config/tsconfig.build.json Adds TS project reference to template webpack plugin build config.
packages/rspeedy/lynx-bundle-rslib-config/test/external-bundle.test.ts Adds unit coverage asserting CSS diagnostics become webpack warnings with mapped locations.
packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts Emits resolved CSS diagnostics via compilation.warnings and collects CSS source maps from extracted CSS assets.
packages/rspeedy/lynx-bundle-rslib-config/src/externalBundleRslibConfig.ts Enables CSS sourcemaps for external bundles and disables CSS minification to avoid sourcemap source path issues.
packages/rspeedy/lynx-bundle-rslib-config/package.json Updates dependencies (@lynx-js/tasm@0.0.38, adds @lynx-js/template-webpack-plugin) and aligns test script pattern with repo conventions.
packages/rspeedy/lynx-bundle-rslib-config/etc/lynx-bundle-rslib-config.api.md Updates public API surface for css_diagnostics on the encode return type.
.changeset/update-template-tasm.md Changeset for template plugin patch release due to TASM bump.
.changeset/external-bundle-css-diagnostics.md Changeset for external bundle config patch release to emit CSS encode diagnostics.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown
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.

🧹 Nitpick comments (2)
packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts (2)

110-117: 💤 Low value

Optional: short-circuit diagnostic processing when there are no diagnostics.

processTasmCSSDiagnostics is invoked on every compilation, even when cssDiagnostics is undefined (the common path when no CSS issues are emitted). It's safe — extractTasmCSSDiagnostics returns [] early — but collectCSSSourceMapContents still walks all assets and JSON.stringifys every CSS source map. Skipping the call when cssDiagnostics is nullish avoids that work on the hot path.

♻️ Proposed early-return
-    const { buffer, encodeOptions, cssDiagnostics } = await this.#encode(assets)
-
-    const resolvedDiagnostics = processTasmCSSDiagnostics({
-      cssDiagnostics,
-      cssSourceMaps: collectCSSSourceMapContents(assets),
-      context: compiler.context,
-      emittedWarnings: emittedCSSDiagnosticWarnings,
-    })
-    resolvedDiagnostics.forEach((diagnostic) => {
+    const { buffer, encodeOptions, cssDiagnostics } = await this.#encode(assets)
+
+    const resolvedDiagnostics = cssDiagnostics
+      ? processTasmCSSDiagnostics({
+        cssDiagnostics,
+        cssSourceMaps: collectCSSSourceMapContents(assets),
+        context: compiler.context,
+        emittedWarnings: emittedCSSDiagnosticWarnings,
+      })
+      : []
+    resolvedDiagnostics.forEach((diagnostic) => {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts`
around lines 110 - 117, The code currently calls processTasmCSSDiagnostics and
collectCSSSourceMapContents on every compilation; add a nullish check for
cssDiagnostics (the value returned from this.#encode) and short-circuit the
diagnostic work when cssDiagnostics is null or undefined: if cssDiagnostics is
nullish, skip calling collectCSSSourceMapContents and processTasmCSSDiagnostics
and set resolvedDiagnostics to an empty array (or the expected empty shape),
otherwise call collectCSSSourceMapContents(assets) and
processTasmCSSDiagnostics({ cssDiagnostics, cssSourceMaps: ..., context:
compiler.context, emittedWarnings: emittedCSSDiagnosticWarnings }); this change
touches the block using const { buffer, encodeOptions, cssDiagnostics } = await
this.#encode(assets) and the subsequent processTasmCSSDiagnostics call.

234-252: 💤 Low value

Consider deduping by reference rather than serialized JSON.

Source maps for CSS chunks can be large; JSON.stringifying each one purely to use it as a Set key, then reparsing it inside parseCSSSourceMaps, doubles the work. Since each asset emits a unique Source instance, deduping by the asset name (or by the RawSourceMap object identity / file field) would avoid the round-trip. Low priority.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts`
around lines 234 - 252, collectCSSSourceMapContents currently JSON.stringifys
each source map to dedupe which forces double work in parseCSSSourceMaps;
instead gather the actual source map objects (or use the asset name) and dedupe
by object identity or a stable key like sourceMap.file or asset.name. Update
collectCSSSourceMapContents to push the RawSourceMap (not JSON) into an array
and use a Set of seen keys (sourceMap.file || asset.name) to skip duplicates,
then return the unique collection and adjust parseCSSSourceMaps callers to
accept the RawSourceMap objects rather than re-parsing JSON.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts`:
- Around line 110-117: The code currently calls processTasmCSSDiagnostics and
collectCSSSourceMapContents on every compilation; add a nullish check for
cssDiagnostics (the value returned from this.#encode) and short-circuit the
diagnostic work when cssDiagnostics is null or undefined: if cssDiagnostics is
nullish, skip calling collectCSSSourceMapContents and processTasmCSSDiagnostics
and set resolvedDiagnostics to an empty array (or the expected empty shape),
otherwise call collectCSSSourceMapContents(assets) and
processTasmCSSDiagnostics({ cssDiagnostics, cssSourceMaps: ..., context:
compiler.context, emittedWarnings: emittedCSSDiagnosticWarnings }); this change
touches the block using const { buffer, encodeOptions, cssDiagnostics } = await
this.#encode(assets) and the subsequent processTasmCSSDiagnostics call.
- Around line 234-252: collectCSSSourceMapContents currently JSON.stringifys
each source map to dedupe which forces double work in parseCSSSourceMaps;
instead gather the actual source map objects (or use the asset name) and dedupe
by object identity or a stable key like sourceMap.file or asset.name. Update
collectCSSSourceMapContents to push the RawSourceMap (not JSON) into an array
and use a Set of seen keys (sourceMap.file || asset.name) to skip duplicates,
then return the unique collection and adjust parseCSSSourceMaps callers to
accept the RawSourceMap objects rather than re-parsing JSON.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 360fb8e7-dd2a-4ad8-96cc-9f1238b2f589

📥 Commits

Reviewing files that changed from the base of the PR and between 5f3b6eb and 7f2d1b3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • .changeset/external-bundle-css-diagnostics.md
  • .changeset/update-template-tasm.md
  • packages/rspeedy/lynx-bundle-rslib-config/etc/lynx-bundle-rslib-config.api.md
  • packages/rspeedy/lynx-bundle-rslib-config/package.json
  • packages/rspeedy/lynx-bundle-rslib-config/src/externalBundleRslibConfig.ts
  • packages/rspeedy/lynx-bundle-rslib-config/src/webpack/ExternalBundleWebpackPlugin.ts
  • packages/rspeedy/lynx-bundle-rslib-config/test/external-bundle.test.ts
  • packages/rspeedy/lynx-bundle-rslib-config/tsconfig.build.json
  • packages/rspeedy/lynx-bundle-rslib-config/tsconfig.json
  • packages/webpack/template-webpack-plugin/package.json

@luhc228 luhc228 force-pushed the fix/external-bundle-css-diagnostics branch from 7f2d1b3 to 2d0afe0 Compare May 6, 2026 12:55
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 6, 2026

🦋 Changeset detected

Latest commit: 2d0afe0

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
@lynx-js/lynx-bundle-rslib-config Patch
@lynx-js/template-webpack-plugin Patch
@lynx-js/react-rsbuild-plugin Patch
@lynx-js/react-alias-rsbuild-plugin Patch

Not sure what this means? Click here to learn what changesets are.

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

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 6, 2026

React External

#927 Bundle Size — 680.83KiB (~+0.01%).

2d0afe0(current) vs 5f3b6eb main#913(baseline)

Bundle metrics  Change 1 change
                 Current
#927
     Baseline
#913
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
Change  Cache Invalidation 58.84% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 17 17
No change  Duplicate Modules 5 5
No change  Duplicate Code 8.59% 8.59%
No change  Packages 0 0
No change  Duplicate Packages 0 0
Bundle size by type  Change 1 change Regression 1 regression
                 Current
#927
     Baseline
#913
Regression  Other 680.83KiB (~+0.01%) 680.82KiB

Bundle analysis reportBranch fix/external-bundle-css-diagnost...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 6, 2026

React MTF Example

#944 Bundle Size — 196.68KiB (0%).

2d0afe0(current) vs 5f3b6eb main#930(baseline)

Bundle metrics  no changes
                 Current
#944
     Baseline
#930
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 3 3
No change  Modules 174 174
No change  Duplicate Modules 66 66
No change  Duplicate Code 44.05% 44.05%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#944
     Baseline
#930
No change  IMG 111.23KiB 111.23KiB
No change  Other 85.45KiB 85.45KiB

Bundle analysis reportBranch fix/external-bundle-css-diagnost...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 6, 2026

React Example

#7812 Bundle Size — 225.52KiB (0%).

2d0afe0(current) vs 5f3b6eb main#7798(baseline)

Bundle metrics  no changes
                 Current
#7812
     Baseline
#7798
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
No change  Modules 180 180
No change  Duplicate Modules 69 69
No change  Duplicate Code 44.54% 44.54%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#7812
     Baseline
#7798
No change  IMG 145.76KiB 145.76KiB
No change  Other 79.77KiB 79.77KiB

Bundle analysis reportBranch fix/external-bundle-css-diagnost...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 6, 2026

Web Explorer

#9385 Bundle Size — 900.03KiB (0%).

2d0afe0(current) vs 5f3b6eb main#9371(baseline)

Bundle metrics  no changes
                 Current
#9385
     Baseline
#9371
No change  Initial JS 44.46KiB 44.46KiB
No change  Initial CSS 2.22KiB 2.22KiB
No change  Cache Invalidation 0% 0%
No change  Chunks 9 9
No change  Assets 11 11
No change  Modules 228 228
No change  Duplicate Modules 11 11
No change  Duplicate Code 27.29% 27.29%
No change  Packages 10 10
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#9385
     Baseline
#9371
No change  JS 495.9KiB 495.9KiB
No change  Other 401.92KiB 401.92KiB
No change  CSS 2.22KiB 2.22KiB

Bundle analysis reportBranch fix/external-bundle-css-diagnost...Project dashboard


Generated by RelativeCIDocumentationReport issue

@relativeci
Copy link
Copy Markdown

relativeci Bot commented May 6, 2026

React Example with Element Template

#78 Bundle Size — 198.12KiB (0%).

2d0afe0(current) vs 5f3b6eb main#64(baseline)

Bundle metrics  Change 2 changes
                 Current
#78
     Baseline
#64
No change  Initial JS 0B 0B
No change  Initial CSS 0B 0B
No change  Cache Invalidation 0% 0%
No change  Chunks 0 0
No change  Assets 4 4
Change  Modules 79(+1.28%) 78
No change  Duplicate Modules 23 23
Change  Duplicate Code 40.56%(-0.05%) 40.58%
No change  Packages 2 2
No change  Duplicate Packages 0 0
Bundle size by type  no changes
                 Current
#78
     Baseline
#64
No change  IMG 145.76KiB 145.76KiB
No change  Other 52.36KiB 52.36KiB

Bundle analysis reportBranch fix/external-bundle-css-diagnost...Project dashboard


Generated by RelativeCIDocumentationReport issue

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented May 6, 2026

Merging this PR will not alter performance

✅ 81 untouched benchmarks
⏩ 26 skipped benchmarks1


Comparing fix/external-bundle-css-diagnostics (2d0afe0) with main (5f3b6eb)

Open in CodSpeed

Footnotes

  1. 26 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@luhc228 luhc228 changed the title feat(lynx-bundle): emit css diagnostics feat(external-bundle): emit css diagnostics May 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants