Repository navigation
fix(start-plugin-core): keep the app's server.compress on Rsbuild - #8863
Conversation
The Rsbuild plugin always set `server.compress: false`, so an app's
`server: { compress: true }` had no effect (#8544). It now sets it only
when the app leaves it unset: a compressed streamed page reaches the
browser only once the stream ends.
From #8817. Rsbuild merges its defaults (`compress: true`) into the
config before `modifyRsbuildConfig`, so the check reads the app's own
config through `api.getRsbuildConfig('original')`.
Fixes #8544
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: ba6cf0e The changes in this PR will be included in the next version bump. This PR includes changesets to release 5 packages
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 |
|
No actionable comments were generated in the recent review. Walkthrough
Merge Risk:
|
|
View your CI Pipeline Execution ↗ for commit ba6cf0e
☁️ Nx Cloud last updated this comment at |
Bundle Size BenchmarksThis pull request does not affect bundle size in any measured scenario. |
🚀 Changeset Version Preview8 package(s) bumped directly, 2 bumped as dependents. 🟨 Minor bumps
🟩 Patch bumps
|
…ild plugin Now that an app's `server.compress: true` takes effect, Rsbuild 2.0.0 to 2.0.4 would corrupt SSR response headers: their compression middleware reads the raw header array `writeHead` form as an object. Rsbuild 2.0.5 fixed it (web-infra-dev/rsbuild#7613). Raise the optional peer of start-plugin-core, react-start, solid-start and vue-start to ^2.0.5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merging this PR will not alter performance1 warning
Comparing Footnotes
|
Through the compiler-test-utils harness, failing on #8817 (f90a6e5): - Rsbuild dev compresses responses when the app leaves server.compress unset (#8863). - A Vite root given relative or through a symbolic link misses a Start library hoisted above the app: its server fn runs uncompiled in SSR (#8866). - An Rsbuild root of '.' fails the build (#8868). - A webpack or Rspack configuration without mode builds the client with route HMR code ($$tsrRefreshId with absolute paths) (#8269). The Start build harness gains an app inside a temporary monorepo (workspace) and the bundler root as the app configures it (root). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
main c156097: #8858, #8863, #8805, #8269, #8866, #8867, #8868, #8869, #8870, #8871, #8876, #8888, #8889, #8890, #8892, Version Packages (#8854, #8891) and docs. - #8817's side and deletions throughout (Babel compilers, start-compiler, add-hmr, start-app.ts, server-fn-id-check.ts, router-utils ast.ts). The lines main changed for #8863, #8866, #8868, #8269 and #8889/#8892 stay #8817's here: their fixes follow as separate commits after the tests that reproduce them. - @rsbuild/core 2.3.1 (#8890) in the catalog, the examples and benchmarks/compiler-perf; Start's peers keep #8817's ^2.2.13 floor. Lockfile and e2e/react-start/basic's route tree regenerated. - Tests: main's start-vite-root, start-rsbuild-root, rsbuild server-compress and router-plugin production-warnings tests are replaced by their ports in the harness (start-build-roots, dev-server-config, production-bundle); main's start-dev-restart test is ported to the dev-server harness and replaces resolve-entries.test.ts (internals). #8817's Rsbuild SPA dev case gives way to main's spa-shell e2e. The route HMR `hot` binding test gains main's unsplit case (#8870). - KNOWN-BUGS: main fixed decorators after `export` (#8867) and the Rsbuild sibling-route manifest (#8780, #8876). - Changesets: drop what main ships now (custom server-fn ids, the Rsbuild manifest and SPA/compress items, exsolve, Vue store pre-bundling, falsy `use` entries, `.ts` route HMR). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… app turns it on Rsbuild fills its defaults (`server.compress: true`) into the config before `modifyRsbuildConfig`, so the check never saw it unset and dev compressed every response. Read the app's own config, as main does (#8863). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
## pnpm-workspace.yaml (default) ## Dependency Updates | Package | From | To | Type | | --- | --- | --- | --- | | `@tanstack/react-router-devtools` | 1.167.2 | 1.167.3 | patch | | `@tanstack/react-start` | 1.169.4 | 1.169.5 | patch | | `ai` | 7.0.164 | 7.0.165 | patch | | `seroval` | 1.7.9 | 1.7.10 | patch | ## Release Notes <details> <summary><b>@<!---->tanstack/react-router-devtools</b> (1.167.2 → 1.167.3)</summary> ### Patch Changes - Updated dependencies \[[`bbf9b75`](TanStack/router@bbf9b75)]: - @<!---->tanstack/router-devtools-core@1.168.3 </details> <details> <summary><b>@<!---->tanstack/react-start</b> (1.169.4 → 1.169.5)</summary> ### Patch Changes - [#8863](TanStack/router#8863) [`01fab5a`](TanStack/router@01fab5a) - The Rsbuild plugin keeps the app's `server.compress` setting instead of always setting it to `false`. Compression stays off by default: a compressed streamed page reaches the browser only once the stream ends. The optional `@rsbuild/core` peer is now `^2.0.5`, the first version whose compression keeps SSR response headers intact. - Updated dependencies \[[`446ce1b`](TanStack/router@446ce1b), [`ff157f0`](TanStack/router@ff157f0), [`01fab5a`](TanStack/router@01fab5a), [`c5320d7`](TanStack/router@c5320d7), [`545a8d3`](TanStack/router@545a8d3), [`da8c28c`](TanStack/router@da8c28c), [`d66a84b`](TanStack/router@d66a84b)]: - @<!---->tanstack/router-utils@1.163.0 - @<!---->tanstack/start-plugin-core@1.171.56 - @<!---->tanstack/react-start-client@1.168.45 - @<!---->tanstack/react-start-rsc@0.1.66 </details> <details> <summary><b>seroval</b> (1.7.9 → 1.7.10)</summary> ### Patch Changes - 7ae5573: Fix several parser edge cases: - The async parser no longer leaves a rejecting promise unhandled while an earlier sibling is still pending. - The stream parser removes queued records in constant time, so a consumer that applies backpressure no longer makes emission quadratic. - A failed parse no longer leaves ids in a caller-owned `refs` map, so later calls and `Serializer` writes define those values again. - The stream parser counts only the first settlement of a promise whose `then` calls back more than once. - Arrays with more than 1,000,000 holes are rejected with a `SerovalParserError` instead of exhausting memory. - `Buffer` and other typed array subclasses serialize as their base typed array, and the typed array size limit applies to them. </details> --- *This PR was auto-generated by [catalog-update-action](https://github.com/brandhaug/catalog-update-action).* Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
What
The Rsbuild Start plugin always set
server.compress: false, soserver: { compress: true }in an app's Rsbuild config had no effect (#8544). Now the plugin setsfalseonly when the app leavesserver.compressunset. Compression stays off by default because a compressed streamed page reaches the browser only once the stream ends: the SSR middleware's srvx response never flushes the compression middleware.This change comes from #8817 (
packages/start-plugin-core/src/rsbuild/plugin.ts), with one difference. #8817 checksrsbuildConfig.server?.compress === undefined, but that never matches. Rsbuild merges its defaults (compress: true) into the config beforemodifyRsbuildConfigruns (withDefaultConfigincreateRsbuild, on 2.2.5 and on #8817's 2.2.14). So with #8817's code, compression would be on by default in dev. This PR reads the app's own value with Rsbuild's publicapi.getRsbuildConfig('original').Now that
compress: truetakes effect, the optional@rsbuild/corepeer of start-plugin-core, react-start, solid-start and vue-start goes from^2.0.0to^2.0.5. Rsbuild 2.0.0–2.0.4 corrupted SSR response headers when compressing (fixed in web-infra-dev/rsbuild#7613). The lockfile doesn't change.Fixes #8544
Tests
tests/rsbuild/server-compress.test.tsrunscreateRsbuildwith the Start plugin, callsinitConfigs({ action: 'dev' }), then readsgetNormalizedConfig().server.compress:falsetrue)compress: true→truefalse)compress: false→falsemain has no dev-server test harness in start-plugin-core yet, so I checked the response by hand on
e2e/react-start/basicwithrsbuild dev:server: { compress: true },/answers200,text/html,Content-Encoding: gzip, and the decompressed page has the home route's content;Validation
Run locally with Node 26.12.1, a frozen install, through Nx:
pnpm format;test:unit(50 files, 877 tests),test:types,test:eslintandtest:buildpass (re-run after the peer change, withtest:buildof react-start, solid-start and vue-start);tanstack-react-start-e2e-basic: the Rsbuild modesssr,ssr--iife,spa,prerenderandpreviewpass;tanstack-react-start-e2e-hmr:test:e2e--rsbuild-ssrpasses (it runsrsbuild dev);react-start.rsbuild.minimal,minimal-iifeandfullare byte-identical to main, file hashes included. The change only touches dev-server config.Merging into #8817
Merging this branch into #8817's head adds one conflict to the ones main already has:
packages/start-plugin-core/src/rsbuild/plugin.ts, thecompresscondition: take this PR's side (api.getRsbuildConfig('original')).@rsbuild/corepeer line in thepackage.jsonof start-plugin-core, react-start, solid-start and vue-start: take refactor(compiler)!: replace Babel with a Yuku-based compiler core for Router and Start #8817's^2.2.13.After that, #8817 should drop:
server.compressclause in.changeset/start-compiler-yuku.md(line 43), keeping thespa.enabled/ Start + Rsbuild: SPA mode dev server SSRs routes and runs loaders on the server #8543 part;server.compressis no longer forced" bullet andCloses #8544in its description.#8817's
dev-server-config.test.tscoverscompress: trueonly. A default-off case there would have caught the difference above.#8543 (the SPA shell in Rsbuild dev, the other half of this split item) isn't in this PR: #8805 already fixes it.
🤖 Generated with Claude Code
Summary by CodeRabbit