Skip to content

rsbuild/rspack tree-shakes reset.css side-effect import out of src/app production CSS bundle #708

Description

@bpowers

Problem

reset.css is tree-shaken out of the src/app production CSS bundle despite being a legitimate side-effect import, and the root cause is unexplained.

src/diagram/index.ts does:

import './reset.css';

and src/diagram/package.json correctly declares CSS as side-effectful:

"sideEffects": [
  "*.css",
  "**/*.css"
]

Yet the universal box-sizing: border-box rule (and all of reset.css's body/typography defaults) was absent from src/app/build/static/css/index.*.css until an explicit import was added to src/app/index.tsx:

import '@simlin/diagram/reset.css';

(added on branch frontend-react-audit, June 2026).

Why it matters

The explicit import is a workaround, not a fix. The bundler is dropping a declared CSS side-effect import that is reached through the aliased package index (src/app/config/rsbuild/shared.config.js aliases @simlin/diagram to the ../diagram source). Because the mechanism is unexplained, the same tree-shaking behavior could silently drop other side-effect imports reached the same way (theme.css, third-party CSS, future side-effectful modules), with no build-time error -- only a visual regression in production. This is a correctness/maintainability hazard in the build pipeline.

Components affected

  • src/app (production CSS bundle, src/app/index.tsx workaround, src/app/config/rsbuild/shared.config.js alias config)
  • src/diagram (index.ts side-effect import, package.json sideEffects)

Investigation / possible approaches

  1. Reproduce: remove the explicit import '@simlin/diagram/reset.css' from src/app/index.tsx, run the production build, and confirm reset.css rules are absent from src/app/build/static/css/index.*.css.
  2. Determine why rspack's tree-shaking honors the sideEffects glob for the in-package import './reset.css' but drops it when @simlin/diagram is consumed via the source alias (resolveApp('../diagram')) rather than via the built package exports. Likely candidates: the alias bypassing the package's sideEffects metadata, or the index re-export chain marking the CSS import as unused.
  3. Either fix the bundler config so declared CSS side-effects are honored through the alias, or -- if explicit entry-point CSS imports are genuinely required by this setup -- document that requirement (in src/app/config/rsbuild/shared.config.js and/or the diagram package README) so future side-effect CSS isn't silently dropped.

Discovery context

Identified during the frontend-react-audit branch work (June 2026) when box-sizing: border-box and other reset defaults were missing from the production app; the explicit src/app/index.tsx import resolved the symptom but left the root cause unexplained.

Activity

  1. added
    frontendInvolved the React-based Typescript frontend
    ciCI, build pipeline, test hygiene
    on Jun 8, 2026
  2. bpowers commented on Jul 2, 2026

    @bpowers
    OwnerAuthor

    Root-caused and fixed in 0ef9fdc. The sideEffects array means ONLY the listed files have side effects, so every JS module — including the compiled entry lib.browser/index.js — was declared pure. Bundlers then re-export from the entry without including its body, dropping its bare CSS imports; the CSS files' own side-effect flag never matters because they are unreachable (verified by instrumenting Vite: index.js isIncluded:false). The same mechanism shipped black diagrams in simlin-serve (theme.css tokens missing, so fill: var(--color-white) fell back to SVG initial black).

    Fix: sideEffects now also lists lib/index.js, lib.browser/index.js, lib/StaticDiagram.js, lib.browser/StaticDiagram.js, and index.ts imports both reset.css and theme.css. Contract pinned by tests in src/diagram/tests/theme-tokens.test.ts. Verified reset+theme now appear exactly once in both the rspack src/app bundles (build/static/css and build-component) and the Vite serve-web bundle; src/app's explicit entry imports dedupe cleanly. Follow-up for dist-level CI smoke coverage: #828.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ciCI, build pipeline, test hygienefrontendInvolved the React-based Typescript frontend

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions