Skip to content

Prototype: per-module build with per-component CSS - #339

Draft
spawnia wants to merge 3 commits into
masterfrom
per-module-build-prototype
Draft

spawnia wants to merge 3 commits into
masterfrom
per-module-build-prototype

Conversation

@spawnia

@spawnia spawnia commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

Prototype, not planned to merge: a per-module build so consumers bundle only the CSS of the components they use.
The measurements and the reasons against it are in the rejected-alternative fold of #338.

In our main consumer it trims each first page load by about 84 KB gzip of JS and 119 KB of CSS

The consumer, built against a packed tarball of this branch and compared with 21.0.1 across 205 lazily loaded routes, counting entry chunks plus the route's chunk group:

First page load 21.0.1 Per module
JS, gzip 1,531 KB at the entry, median route −84 KB 1,443 KB at the entry
CSS in the JS 1,013 KB median route −119 KB
Library CSS at the entry 578 KB 454 KB

The app shell imports 33 of the 53 component styles it uses before any route loads: grid, button, menu, date-picker, table, input and more, 454 KB.
Only 103 KB moves into route chunks.
A larger gain needs the consumer to load its shell lazily, not only the library to split.

For agents 🤖: parked prototype, close when no consumer needs it
  • preserveModules build, antd and dependencies external, output.paths maps antd/es for esm and antd/lib for cjs.
  • scripts/antd-styles.cjs compiles one prefixed, minified stylesheet per antd component into styles/, with src/antd-variables.less imported (multiple). The compact theme must come from antd/es/style/themes/compact.less.
  • A rollup plugin antdStyleImports prepends the CSS imports of each module's antd dependency closure.
  • Measured on 2026-10-30 with stats from rspack build --json; scripts in scripts/limes-build.sh and scripts/route-load.py, which read and write /tmp/per-module-scripts. The consumer needs its esm/index.css import removed.
  • Open: about 29 eslint errors in scripts/antd-styles.cjs, rc-picker and tslib missing from dependencies, no visual check, Storybook and the second consumer untested. Measuring scripts were in /tmp/per-module-scripts, not committed.

🤖 Generated with Claude Code

Not intended to merge, kept for reference. See the rejected-alternative
fold in #338.

🤖 Generated with Claude Code
npm pack drops every node_modules directory, so the packed prototype missed
tslib, react-hotkeys and the other bundled modules.

🤖 Generated with Claude Code
limes-build.sh builds the consumer with Rspack stats, route-load.py sums what
each route's first page load needs.

🤖 Generated with Claude Code

This branch has not been deployed

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

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant