From 8b4c483a02352525e7026cfb07943138b2943c8b Mon Sep 17 00:00:00 2001 From: Elecmonkey Date: Fri, 12 Jun 2026 11:44:30 +0800 Subject: [PATCH 1/2] fix(start-plugin-core): support rsbuild preview SSR --- .changeset/quiet-rsbuild-preview.md | 5 + benchmarks/bundle-size/package.json | 2 +- .../rspack-basic-file-based/package.json | 2 +- .../package.json | 2 +- e2e/react-start/basic/package.json | 7 +- e2e/react-start/basic/playwright.config.ts | 8 +- e2e/react-start/css-inline/package.json | 2 +- .../custom-server-rsbuild/package.json | 2 +- .../custom-server-rsbuild/rsbuild.config.ts | 4 +- .../deferred-hydration/package.json | 2 +- e2e/react-start/hmr/package.json | 2 +- .../import-protection/package.json | 2 +- e2e/react-start/rsc/package.json | 2 +- e2e/react-start/server-functions/package.json | 2 +- .../rspack-basic-file-based/package.json | 2 +- .../package.json | 2 +- e2e/solid-start/basic/package.json | 2 +- .../deferred-hydration/package.json | 2 +- .../rspack-basic-file-based/package.json | 2 +- .../package.json | 2 +- e2e/vue-start/basic/package.json | 2 +- .../quickstart-rspack-file-based/package.json | 2 +- .../quickstart-rspack-file-based/package.json | 2 +- packages/react-start/package.json | 2 +- packages/solid-start/package.json | 2 +- packages/start-plugin-core/package.json | 2 +- .../src/rsbuild/dev-server.ts | 129 ------ .../start-plugin-core/src/rsbuild/plugin.ts | 15 +- .../start-plugin-core/src/rsbuild/schema.ts | 4 +- .../src/rsbuild/server-middleware.ts | 217 ++++++++++ packages/vue-start/package.json | 2 +- pnpm-lock.yaml | 380 ++++++++---------- 32 files changed, 432 insertions(+), 383 deletions(-) create mode 100644 .changeset/quiet-rsbuild-preview.md delete mode 100644 packages/start-plugin-core/src/rsbuild/dev-server.ts create mode 100644 packages/start-plugin-core/src/rsbuild/server-middleware.ts diff --git a/.changeset/quiet-rsbuild-preview.md b/.changeset/quiet-rsbuild-preview.md new file mode 100644 index 0000000000..f0f1421b83 --- /dev/null +++ b/.changeset/quiet-rsbuild-preview.md @@ -0,0 +1,5 @@ +--- +'@tanstack/start-plugin-core': patch +--- + +Fix Rsbuild preview support for TanStack Start SSR and rename the middleware option to `installServerMiddleware`. diff --git a/benchmarks/bundle-size/package.json b/benchmarks/bundle-size/package.json index e03949297b..8cd8f73f41 100644 --- a/benchmarks/bundle-size/package.json +++ b/benchmarks/bundle-size/package.json @@ -39,7 +39,7 @@ "vue": "^3.5.16" }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tanstack/router-plugin": "workspace:^", "@types/react": "^19.0.8", diff --git a/e2e/react-router/rspack-basic-file-based/package.json b/e2e/react-router/rspack-basic-file-based/package.json index b19a27af6d..74659b51e1 100644 --- a/e2e/react-router/rspack-basic-file-based/package.json +++ b/e2e/react-router/rspack-basic-file-based/package.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tailwindcss/postcss": "^4.2.2", "@tanstack/router-e2e-utils": "workspace:^", diff --git a/e2e/react-router/rspack-basic-virtual-named-export-config-file-based/package.json b/e2e/react-router/rspack-basic-virtual-named-export-config-file-based/package.json index 5609c6cef0..a7b9eb58d4 100644 --- a/e2e/react-router/rspack-basic-virtual-named-export-config-file-based/package.json +++ b/e2e/react-router/rspack-basic-virtual-named-export-config-file-based/package.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tailwindcss/postcss": "^4.2.2", "@tanstack/router-e2e-utils": "workspace:^", diff --git a/e2e/react-start/basic/package.json b/e2e/react-start/basic/package.json index 4a6a92d1c5..37a3f4a0e2 100644 --- a/e2e/react-start/basic/package.json +++ b/e2e/react-start/basic/package.json @@ -12,6 +12,7 @@ "build:vite": "vite build && tsc --noEmit", "build:rsbuild": "rsbuild build && tsc --noEmit", "preview": "vite preview", + "preview:rsbuild": "rsbuild preview", "start": "node server.js", "test:e2e:startDummyServer": "node -e 'import(\"./tests/setup/global.setup.ts\").then(m => m.default())' & node -e 'import(\"./tests/setup/waitForDummyServer.ts\").then(m => m.default())'", "test:e2e:stopDummyServer": "node -e 'import(\"./tests/setup/global.teardown.ts\").then(m => m.default())'", @@ -31,7 +32,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tailwindcss/postcss": "^4.2.2", "@tailwindcss/vite": "^4.2.2", @@ -86,6 +87,10 @@ { "toolchain": "rsbuild", "mode": "prerender" + }, + { + "toolchain": "rsbuild", + "mode": "preview" } ] } diff --git a/e2e/react-start/basic/playwright.config.ts b/e2e/react-start/basic/playwright.config.ts index 4d92fc032d..db07d18608 100644 --- a/e2e/react-start/basic/playwright.config.ts +++ b/e2e/react-start/basic/playwright.config.ts @@ -7,6 +7,7 @@ import { import packageJson from './package.json' with { type: 'json' } const mode = process.env.MODE ?? 'ssr' +const toolchain = process.env.E2E_TOOLCHAIN ?? 'vite' const e2ePortKey = process.env.E2E_PORT_KEY ?? packageJson.name const distDir = process.env.E2E_DIST_DIR ?? 'dist' @@ -24,9 +25,13 @@ const PORT = await getTestServerPort(e2ePortKey) const START_PORT = await getTestServerPort(`${e2ePortKey}_start`) const EXTERNAL_PORT = await getDummyServerPort(e2ePortKey) const baseURL = `http://localhost:${PORT}` +const previewCommand = + toolchain === 'rsbuild' + ? `pnpm preview:rsbuild --port ${PORT}` + : `pnpm preview --outDir ${distDir} --port ${PORT}` const commandByMode = mode === 'preview' - ? `pnpm run test:e2e:startDummyServer && pnpm preview --outDir ${distDir} --port ${PORT}` + ? `pnpm run test:e2e:startDummyServer && ${previewCommand}` : `pnpm run test:e2e:startDummyServer && pnpm start` /** * See https://playwright.dev/docs/test-configuration. @@ -50,6 +55,7 @@ export default defineConfig({ stdout: 'pipe', env: { MODE: mode, + E2E_TOOLCHAIN: toolchain, VITE_NODE_ENV: 'test', VITE_EXTERNAL_PORT: String(EXTERNAL_PORT), VITE_SERVER_PORT: String(PORT), diff --git a/e2e/react-start/css-inline/package.json b/e2e/react-start/css-inline/package.json index e3e5d79678..a7bc5d023f 100644 --- a/e2e/react-start/css-inline/package.json +++ b/e2e/react-start/css-inline/package.json @@ -24,7 +24,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tanstack/router-e2e-utils": "workspace:^", "@types/node": "^22.10.2", diff --git a/e2e/react-start/custom-server-rsbuild/package.json b/e2e/react-start/custom-server-rsbuild/package.json index 255b07edc6..75634f79f5 100644 --- a/e2e/react-start/custom-server-rsbuild/package.json +++ b/e2e/react-start/custom-server-rsbuild/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tailwindcss/postcss": "^4.2.2", "@tanstack/router-e2e-utils": "workspace:^", diff --git a/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts b/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts index 5f9aa96e16..739b159c5e 100644 --- a/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts +++ b/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts @@ -28,10 +28,10 @@ import { tanstackStart } from '@tanstack/react-start/plugin/rsbuild' // explicit prefix. export default defineConfig({ plugins: [ - pluginReact(), + pluginReact({ splitChunks: false }), tanstackStart({ rsbuild: { - installDevServerMiddleware: false, + installServerMiddleware: false, client: { output: 'iife', }, diff --git a/e2e/react-start/deferred-hydration/package.json b/e2e/react-start/deferred-hydration/package.json index 9560a44c41..b225528b49 100644 --- a/e2e/react-start/deferred-hydration/package.json +++ b/e2e/react-start/deferred-hydration/package.json @@ -26,7 +26,7 @@ "react-dom": "^19.0.0" }, "devDependencies": { - "@rsbuild/core": "^2.0.1", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tanstack/router-e2e-utils": "workspace:^", "@types/node": "^22.10.2", diff --git a/e2e/react-start/hmr/package.json b/e2e/react-start/hmr/package.json index 3854488170..b3a58125b9 100644 --- a/e2e/react-start/hmr/package.json +++ b/e2e/react-start/hmr/package.json @@ -21,7 +21,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tailwindcss/postcss": "^4.2.2", "@tailwindcss/vite": "^4.2.2", diff --git a/e2e/react-start/import-protection/package.json b/e2e/react-start/import-protection/package.json index e4ad4a79ba..65ad70126b 100644 --- a/e2e/react-start/import-protection/package.json +++ b/e2e/react-start/import-protection/package.json @@ -25,7 +25,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tanstack/router-e2e-utils": "workspace:^", "@types/node": "^22.10.2", diff --git a/e2e/react-start/rsc/package.json b/e2e/react-start/rsc/package.json index 7a499078d3..36f822e660 100644 --- a/e2e/react-start/rsc/package.json +++ b/e2e/react-start/rsc/package.json @@ -40,7 +40,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tanstack/eslint-plugin-start": "workspace:^", "@tanstack/router-e2e-utils": "workspace:^", diff --git a/e2e/react-start/server-functions/package.json b/e2e/react-start/server-functions/package.json index 279883dbb4..5efdf6c42a 100644 --- a/e2e/react-start/server-functions/package.json +++ b/e2e/react-start/server-functions/package.json @@ -31,7 +31,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tailwindcss/postcss": "^4.2.2", "@tailwindcss/vite": "^4.2.2", diff --git a/e2e/solid-router/rspack-basic-file-based/package.json b/e2e/solid-router/rspack-basic-file-based/package.json index 15e0106a68..5641433737 100644 --- a/e2e/solid-router/rspack-basic-file-based/package.json +++ b/e2e/solid-router/rspack-basic-file-based/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-solid": "^1.1.1", "@tailwindcss/postcss": "^4.2.2", diff --git a/e2e/solid-router/rspack-basic-virtual-named-export-config-file-based/package.json b/e2e/solid-router/rspack-basic-virtual-named-export-config-file-based/package.json index 49f56c5c7a..f298b42ca6 100644 --- a/e2e/solid-router/rspack-basic-virtual-named-export-config-file-based/package.json +++ b/e2e/solid-router/rspack-basic-virtual-named-export-config-file-based/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-solid": "^1.1.1", "@tailwindcss/postcss": "^4.2.2", diff --git a/e2e/solid-start/basic/package.json b/e2e/solid-start/basic/package.json index 0210535500..1993225f61 100644 --- a/e2e/solid-start/basic/package.json +++ b/e2e/solid-start/basic/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-solid": "^1.1.1", "@tailwindcss/postcss": "^4.2.2", diff --git a/e2e/solid-start/deferred-hydration/package.json b/e2e/solid-start/deferred-hydration/package.json index e7693d1f10..fd2b681ef1 100644 --- a/e2e/solid-start/deferred-hydration/package.json +++ b/e2e/solid-start/deferred-hydration/package.json @@ -23,7 +23,7 @@ "solid-js": "^1.9.10" }, "devDependencies": { - "@rsbuild/core": "^2.0.1", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-solid": "^1.1.1", "@tanstack/router-e2e-utils": "workspace:^", diff --git a/e2e/vue-router/rspack-basic-file-based/package.json b/e2e/vue-router/rspack-basic-file-based/package.json index 78b7e74a41..5d8a072d87 100644 --- a/e2e/vue-router/rspack-basic-file-based/package.json +++ b/e2e/vue-router/rspack-basic-file-based/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-vue": "^1.2.7", "@rsbuild/plugin-vue-jsx": "^2.0.0", diff --git a/e2e/vue-router/rspack-basic-virtual-named-export-config-file-based/package.json b/e2e/vue-router/rspack-basic-virtual-named-export-config-file-based/package.json index 6a5cfead84..11f61237d3 100644 --- a/e2e/vue-router/rspack-basic-virtual-named-export-config-file-based/package.json +++ b/e2e/vue-router/rspack-basic-virtual-named-export-config-file-based/package.json @@ -17,7 +17,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-vue": "^1.2.7", "@rsbuild/plugin-vue-jsx": "^2.0.0", diff --git a/e2e/vue-start/basic/package.json b/e2e/vue-start/basic/package.json index 2df94b1a20..073627701a 100644 --- a/e2e/vue-start/basic/package.json +++ b/e2e/vue-start/basic/package.json @@ -27,7 +27,7 @@ }, "devDependencies": { "@playwright/test": "^1.50.1", - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.0.5", "@rsbuild/plugin-vue": "^1.2.2", "@rsbuild/plugin-vue-jsx": "^1.1.1", diff --git a/examples/react/quickstart-rspack-file-based/package.json b/examples/react/quickstart-rspack-file-based/package.json index c1fdf3a800..51346b18da 100644 --- a/examples/react/quickstart-rspack-file-based/package.json +++ b/examples/react/quickstart-rspack-file-based/package.json @@ -17,7 +17,7 @@ "tailwindcss": "^4.2.2" }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-react": "^2.0.0", "@tanstack/router-plugin": "^1.168.18", "@types/react": "^19.0.8", diff --git a/examples/solid/quickstart-rspack-file-based/package.json b/examples/solid/quickstart-rspack-file-based/package.json index 582dbe3313..58caf50475 100644 --- a/examples/solid/quickstart-rspack-file-based/package.json +++ b/examples/solid/quickstart-rspack-file-based/package.json @@ -16,7 +16,7 @@ "tailwindcss": "^4.2.2" }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@rsbuild/plugin-babel": "^1.1.2", "@rsbuild/plugin-solid": "^1.1.1", "@tanstack/router-plugin": "^1.168.18", diff --git a/packages/react-start/package.json b/packages/react-start/package.json index f19ff86212..cbaae21f27 100644 --- a/packages/react-start/package.json +++ b/packages/react-start/package.json @@ -188,7 +188,7 @@ } }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@types/node": ">=20" } } diff --git a/packages/solid-start/package.json b/packages/solid-start/package.json index 7561c006e8..8059adf57c 100644 --- a/packages/solid-start/package.json +++ b/packages/solid-start/package.json @@ -127,7 +127,7 @@ "pathe": "^2.0.3" }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@tanstack/router-utils": "workspace:*", "@types/node": ">=20", "vite": "*" diff --git a/packages/start-plugin-core/package.json b/packages/start-plugin-core/package.json index 8587b9dfca..b2f5cec25c 100644 --- a/packages/start-plugin-core/package.json +++ b/packages/start-plugin-core/package.json @@ -107,7 +107,7 @@ "zod": "^4.4.3" }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@types/babel__code-frame": "^7.0.6", "@types/babel__core": "^7.20.5", "@types/node": ">=20", diff --git a/packages/start-plugin-core/src/rsbuild/dev-server.ts b/packages/start-plugin-core/src/rsbuild/dev-server.ts deleted file mode 100644 index c83ec71448..0000000000 --- a/packages/start-plugin-core/src/rsbuild/dev-server.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { NodeRequest, sendNodeResponse } from 'srvx/node' -import { RSBUILD_ENVIRONMENT_NAMES } from './planning' -import type { IncomingMessage, ServerResponse } from 'node:http' -import type { RsbuildConfig } from '@rsbuild/core' - -type ServerSetupFn = Extract< - NonNullable['setup']>, - (...args: Array) => any -> -type SSRMiddleware = ( - req: IncomingMessage & { originalUrl?: string }, - res: ServerResponse, - next: () => void, -) => Promise - -/** - * Returns a `server.setup` function for rsbuild v2. - * - * Two middleware positions are used: - * - * 1. **Setup body** (BEFORE built-ins): Intercepts `/_serverFn/` URLs so - * they never reach rsbuild's htmlFallback/htmlCompletion middleware, - * which can swallow long base64 function IDs. - * - * 2. **Returned callback** (AFTER built-ins, BEFORE fallback): Handles - * all remaining SSR requests (page navigations). This position lets - * rsbuild's asset middleware serve compiled JS/CSS first. - * - * See rsbuild source: devMiddlewares.ts `applyDefaultMiddlewares()`. - */ -export function createServerSetup(opts: { - serverFnBasePath: string -}): ServerSetupFn { - return (context) => { - // Only install SSR middleware in dev mode - if (context.action !== 'dev') { - return () => {} - } - - const serverFnBase = opts.serverFnBasePath - - const handleSSR: SSRMiddleware = async (req, res, next) => { - const ssrEnv = - context.server.environments[RSBUILD_ENVIRONMENT_NAMES.server] - - if (!ssrEnv) { - console.error( - `[tanstack-start] SSR environment "${RSBUILD_ENVIRONMENT_NAMES.server}" not found`, - ) - return next() - } - - try { - const serverEntry = await ssrEnv.loadBundle<{ - default: { fetch: (req: Request) => Promise } - }>('index') - - // Restore the original URL (rsbuild may rewrite to /index.html) - if (req.originalUrl) { - req.url = req.originalUrl - } - - const webReq = new NodeRequest({ req, res }) - const webRes = await serverEntry.default.fetch(webReq) - return sendNodeResponse(res, webRes) - } catch (e) { - console.error('[tanstack-start] SSR error:', e) - - const webReq = new NodeRequest({ req, res }) - if (webReq.headers.get('content-type')?.includes('application/json')) { - return sendNodeResponse( - res, - new Response( - JSON.stringify( - { - status: 500, - error: 'Internal Server Error', - message: - 'An unexpected error occurred. Please try again later.', - timestamp: new Date().toISOString(), - }, - null, - 2, - ), - { - status: 500, - headers: { 'Content-Type': 'application/json' }, - }, - ), - ) - } - - return sendNodeResponse( - res, - new Response( - ` - - Error - -

Internal Server Error

-
${e instanceof Error ? e.message : String(e)}
- -`, - { - status: 500, - headers: { 'Content-Type': 'text/html' }, - }, - ), - ) - } - } - - // Position 1: BEFORE built-ins — intercept server function calls - // early so they are not swallowed by htmlFallback or assetsMiddleware. - context.server.middlewares.use(async (req, res, next) => { - const url = req.url || '/' - if (url.startsWith(serverFnBase)) { - return handleSSR(req, res, next) - } - return next() - }) - - // Position 2: AFTER built-ins, before fallback — SSR catch-all for - // page navigations. Assets are already handled by rsbuild middleware. - return () => { - context.server.middlewares.use(handleSSR) - } - } -} diff --git a/packages/start-plugin-core/src/rsbuild/plugin.ts b/packages/start-plugin-core/src/rsbuild/plugin.ts index f9e48fe7a2..95bfb4b368 100644 --- a/packages/start-plugin-core/src/rsbuild/plugin.ts +++ b/packages/start-plugin-core/src/rsbuild/plugin.ts @@ -24,7 +24,7 @@ import { START_MANIFEST_PLACEHOLDER, registerVirtualModules, } from './virtual-modules' -import { createServerSetup } from './dev-server' +import { createServerSetup } from './server-middleware' import { registerClientBuildCapture } from './normalized-client-build' import { registerRouterPlugins } from './start-router-plugin' import { postBuildWithRsbuild } from './post-build' @@ -159,6 +159,8 @@ export function tanStackStartRsbuild( const resolvedEntryPlan = configContext.resolveEntries() const isDev = api.context.action === 'dev' + const isPreview = api.context.action === 'preview' + const shouldInstallServerMiddleware = isDev || isPreview const entryAliases = createRsbuildResolvedEntryAliases({ entryPaths: resolvedEntryPlan.entryPaths, @@ -244,6 +246,10 @@ export function tanStackStartRsbuild( }, }, server: { + ...(rsbuildConfig.server?.printUrls === undefined || + rsbuildConfig.server.printUrls === true + ? { printUrls: ({ urls }: { urls: Array }) => urls } + : {}), // Rsbuild compression currently treats Node's raw header array // writeHead form as an object, which corrupts SSR response headers. compress: false, @@ -252,11 +258,14 @@ export function tanStackStartRsbuild( htmlFallback: false, // server.setup returned callback runs after built-in middleware // but BEFORE fallback middleware — the ideal slot for SSR. - ...(isDev && - startPluginOpts.rsbuild?.installDevServerMiddleware !== false + ...(shouldInstallServerMiddleware && + startPluginOpts.rsbuild?.installServerMiddleware !== false ? { setup: createServerSetup({ serverFnBasePath: serverFnBase, + serverOutputDirectory: + resolvedStartConfig.outputDirectories.server, + publicBase: resolvedStartConfig.basePaths.publicBase, }), } : {}), diff --git a/packages/start-plugin-core/src/rsbuild/schema.ts b/packages/start-plugin-core/src/rsbuild/schema.ts index 86194e309c..5bccbae71f 100644 --- a/packages/start-plugin-core/src/rsbuild/schema.ts +++ b/packages/start-plugin-core/src/rsbuild/schema.ts @@ -13,7 +13,7 @@ export const tanstackStartRsbuildOptionsSchema = .extend({ rsbuild: z .object({ - installDevServerMiddleware: z.boolean().optional(), + installServerMiddleware: z.boolean().optional(), client: z .object({ output: rsbuildClientOutputSchema.optional().default('module'), @@ -41,7 +41,7 @@ export type TanStackStartRsbuildInputConfig = z.input< typeof tanstackStartRsbuildOptionsSchema > & { rsbuild?: { - installDevServerMiddleware?: boolean + installServerMiddleware?: boolean client?: { output?: z.input } diff --git a/packages/start-plugin-core/src/rsbuild/server-middleware.ts b/packages/start-plugin-core/src/rsbuild/server-middleware.ts new file mode 100644 index 0000000000..70e2f234ce --- /dev/null +++ b/packages/start-plugin-core/src/rsbuild/server-middleware.ts @@ -0,0 +1,217 @@ +import { resolve } from 'node:path' +import { pathToFileURL } from 'node:url' +import { NodeRequest, sendNodeResponse } from 'srvx/node' +import { joinURL } from 'ufo' +import { RSBUILD_ENVIRONMENT_NAMES } from './planning' +import type { IncomingMessage, ServerResponse } from 'node:http' +import type { RsbuildConfig } from '@rsbuild/core' + +type ServerSetupFn = Extract< + NonNullable['setup']>, + (...args: Array) => any +> +type ServerSetupContext = Parameters[0] +type SSRMiddleware = ( + req: IncomingMessage & { originalUrl?: string }, + res: ServerResponse, + next: (error?: unknown) => void, +) => Promise +type FetchHandler = (req: Request) => Promise | Response + +type ServerEntry = + | FetchHandler + | { + fetch?: FetchHandler + } + +function resolveFetchHandler(serverEntry: ServerEntry): FetchHandler { + if (typeof serverEntry === 'function') { + return serverEntry + } + + if (typeof serverEntry.fetch === 'function') { + return serverEntry.fetch.bind(serverEntry) + } + + throw new Error( + 'Unable to resolve a request handler from Rsbuild server bundle', + ) +} + +function getPublicBasePathname(publicBase: string): string { + try { + return new URL(publicBase, 'http://localhost').pathname + } catch { + return publicBase + } +} + +function restorePreviewUrl(opts: { + req: IncomingMessage & { originalUrl?: string } + publicBase: string +}) { + if (opts.req.originalUrl) { + opts.req.url = opts.req.originalUrl + } + + const publicBasePathname = getPublicBasePathname(opts.publicBase) + if (publicBasePathname === '/') { + return + } + + const url = opts.req.url ?? '/' + if (url.startsWith(publicBasePathname)) { + return + } + + opts.req.url = joinURL(publicBasePathname, url) +} + +async function loadDevFetchHandler( + context: ServerSetupContext, +): Promise { + if (context.action !== 'dev') { + throw new Error('Cannot load Rsbuild dev SSR bundle outside dev mode') + } + + const ssrEnv = context.server.environments[RSBUILD_ENVIRONMENT_NAMES.server] + + if (!ssrEnv) { + throw new Error( + `SSR environment "${RSBUILD_ENVIRONMENT_NAMES.server}" not found`, + ) + } + + const serverEntry = await ssrEnv.loadBundle<{ default: ServerEntry }>('index') + return resolveFetchHandler(serverEntry.default) +} + +/** + * Returns a `server.setup` function for rsbuild v2. + * + * Two middleware positions are used: + * + * 1. **Setup body** (BEFORE built-ins): Intercepts `/_serverFn/` URLs so + * they never reach rsbuild's htmlFallback/htmlCompletion middleware, + * which can swallow long base64 function IDs. + * + * 2. **Returned callback** (AFTER built-ins, BEFORE fallback): Handles + * all remaining SSR requests (page navigations). This position lets + * rsbuild's asset middleware serve compiled JS/CSS first. + * + * The middleware choreography is shared by dev and preview. The server entry + * loader differs: dev reads from Rsbuild's in-memory environment so rebuilds + * are reflected immediately, while preview lazy-imports the production server + * bundle from disk. + * + * See rsbuild source: devMiddlewares.ts `applyDefaultMiddlewares()` and + * previewServer.ts `startPreviewServer()`. + */ +export function createServerSetup(opts: { + serverFnBasePath: string + serverOutputDirectory: string + publicBase: string +}): ServerSetupFn { + let previewFetchHandlerPromise: Promise | undefined + + const getPreviewFetchHandler = () => { + if (!previewFetchHandlerPromise) { + previewFetchHandlerPromise = loadPreviewFetchHandler( + opts.serverOutputDirectory, + ) + } + + return previewFetchHandlerPromise + } + + return (context) => { + const serverFnBase = opts.serverFnBasePath + + const handleSSR: SSRMiddleware = async (req, res, next) => { + try { + const fetchHandler = + context.action === 'dev' + ? await loadDevFetchHandler(context) + : await getPreviewFetchHandler() + + if (context.action === 'preview') { + // Rsbuild preview's base middleware strips server.base before the + // returned setup callback runs. Put it back before creating the Web + // Request so Start's router sees the same URL shape as build/custom + // servers. The early server-fn middleware runs before that base + // middleware, so avoid prepending when the URL already has the base. + restorePreviewUrl({ req, publicBase: opts.publicBase }) + } else if (req.originalUrl) { + // Restore the original URL (rsbuild may rewrite to /index.html) + req.url = req.originalUrl + } + + const webReq = new NodeRequest({ req, res }) + const webRes = await fetchHandler(webReq) + return sendNodeResponse(res, webRes) + } catch (e) { + console.error('[tanstack-start] SSR error:', e) + + const webReq = new NodeRequest({ req, res }) + if (webReq.headers.get('content-type')?.includes('application/json')) { + return sendNodeResponse( + res, + new Response( + JSON.stringify( + { + status: 500, + error: 'Internal Server Error', + message: + 'An unexpected error occurred. Please try again later.', + timestamp: new Date().toISOString(), + }, + null, + 2, + ), + { + status: 500, + headers: { 'Content-Type': 'application/json' }, + }, + ), + ) + } + + return next(e) + } + } + + // Position 1: BEFORE built-ins — intercept server function calls + // early so they are not swallowed by htmlFallback or assetsMiddleware. + context.server.middlewares.use(async (req, res, next) => { + const url = req.url || '/' + if (url.startsWith(serverFnBase)) { + return handleSSR(req, res, next) + } + return next() + }) + + // Position 2: AFTER built-ins, before fallback — SSR catch-all for + // page navigations. Assets are already handled by rsbuild middleware. + return () => { + context.server.middlewares.use(handleSSR) + } + } +} + +async function loadPreviewFetchHandler( + serverOutputDirectory: string, +): Promise { + const serverEntryPath = resolve(serverOutputDirectory, 'index.js') + const imported = (await import( + pathToFileURL(serverEntryPath).toString() + )) as { default: ServerEntry } + + try { + return resolveFetchHandler(imported.default) + } catch (error) { + throw new Error( + `Unable to resolve a request handler from Rsbuild server bundle at ${serverEntryPath}`, + { cause: error }, + ) + } +} diff --git a/packages/vue-start/package.json b/packages/vue-start/package.json index b4c35e32d5..c91f957527 100644 --- a/packages/vue-start/package.json +++ b/packages/vue-start/package.json @@ -121,7 +121,7 @@ "pathe": "^2.0.3" }, "devDependencies": { - "@rsbuild/core": "^2.0.8", + "@rsbuild/core": "^2.0.11", "@tanstack/router-utils": "workspace:*", "@types/node": ">=20", "@vitejs/plugin-vue-jsx": "^4.1.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7938cd51f4..164a973ca9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -219,11 +219,11 @@ importers: version: 3.5.25(typescript@6.0.2) devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/router-plugin': specifier: workspace:* version: link:../../packages/router-plugin @@ -1113,11 +1113,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -1165,11 +1165,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -1388,11 +1388,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -1791,11 +1791,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/router-e2e-utils': specifier: workspace:^ version: link:../../e2e-utils @@ -1962,11 +1962,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -2017,11 +2017,11 @@ importers: version: 19.2.3(react@19.2.3) devDependencies: '@rsbuild/core': - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.1)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/router-e2e-utils': specifier: workspace:^ version: link:../../e2e-utils @@ -2210,11 +2210,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -2320,11 +2320,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/router-e2e-utils': specifier: workspace:^ version: link:../../e2e-utils @@ -2479,11 +2479,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/eslint-plugin-start': specifier: workspace:^ version: link:../../../packages/eslint-plugin-start @@ -2645,10 +2645,10 @@ importers: version: 1.58.0 '@rsbuild/core': specifier: ^2.0.8 - version: 2.0.8 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/router-e2e-utils': specifier: workspace:^ version: link:../../e2e-utils @@ -2876,11 +2876,11 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -3974,14 +3974,14 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.8) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-solid': specifier: ^1.1.1 - version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8)(solid-js@1.9.12) + version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)(solid-js@1.9.12) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -4020,14 +4020,14 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.8) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-solid': specifier: ^1.1.1 - version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8)(solid-js@1.9.12) + version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)(solid-js@1.9.12) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -4213,14 +4213,14 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.8) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-solid': specifier: ^1.1.1 - version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8)(solid-js@1.9.12) + version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)(solid-js@1.9.12) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -4602,14 +4602,14 @@ importers: version: 1.9.12 devDependencies: '@rsbuild/core': - specifier: ^2.0.1 - version: 2.0.1 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.1) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-solid': specifier: ^1.1.1 - version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.1)(solid-js@1.9.12) + version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)(solid-js@1.9.12) '@tanstack/router-e2e-utils': specifier: workspace:^ version: link:../../e2e-utils @@ -5802,17 +5802,17 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.8) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-vue': specifier: ^1.2.7 - version: 1.2.7(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)) + version: 1.2.7(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)) '@rsbuild/plugin-vue-jsx': specifier: ^2.0.0 - version: 2.0.0(@babel/core@7.29.0)(@rsbuild/core@2.0.8) + version: 2.0.0(@babel/core@7.29.0)(@rsbuild/core@2.0.11) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -5857,17 +5857,17 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.8) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-vue': specifier: ^1.2.7 - version: 1.2.7(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)) + version: 1.2.7(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)) '@rsbuild/plugin-vue-jsx': specifier: ^2.0.0 - version: 2.0.0(@babel/core@7.29.0)(@rsbuild/core@2.0.8) + version: 2.0.0(@babel/core@7.29.0)(@rsbuild/core@2.0.11) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -6080,17 +6080,17 @@ importers: specifier: ^1.57.0 version: 1.58.0 '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.0.5 - version: 1.0.6(@rsbuild/core@2.0.8) + version: 1.0.6(@rsbuild/core@2.0.11) '@rsbuild/plugin-vue': specifier: ^1.2.2 - version: 1.2.2(@rsbuild/core@2.0.8)(@swc/core@1.15.33(@swc/helpers@0.5.23))(esbuild@0.27.4)(vue@3.5.25(typescript@6.0.2)) + version: 1.2.2(@rsbuild/core@2.0.11)(@swc/core@1.15.33(@swc/helpers@0.5.23))(esbuild@0.27.4)(vue@3.5.25(typescript@6.0.2)) '@rsbuild/plugin-vue-jsx': specifier: ^1.1.1 - version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8) + version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11) '@tailwindcss/postcss': specifier: ^4.2.2 version: 4.2.2 @@ -8153,11 +8153,11 @@ importers: version: 4.2.2 devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-react': specifier: ^2.0.0 - version: 2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23)) + version: 2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23)) '@tanstack/router-plugin': specifier: workspace:* version: link:../../../packages/router-plugin @@ -11126,14 +11126,14 @@ importers: version: 4.2.2 devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@rsbuild/plugin-babel': specifier: ^1.1.2 - version: 1.1.2(@rsbuild/core@2.0.8) + version: 1.1.2(@rsbuild/core@2.0.11) '@rsbuild/plugin-solid': specifier: ^1.1.1 - version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8)(solid-js@1.9.12) + version: 1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)(solid-js@1.9.12) '@tanstack/router-plugin': specifier: workspace:* version: link:../../../packages/router-plugin @@ -12591,8 +12591,8 @@ importers: version: 8.0.14(@types/node@25.0.9)(esbuild@0.27.4)(jiti@2.7.0)(sass@1.97.2)(terser@5.37.0)(tsx@4.20.3)(yaml@2.9.0) devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@types/node': specifier: 25.0.9 version: 25.0.9 @@ -12858,7 +12858,7 @@ importers: version: 7.28.5 '@rsbuild/core': specifier: '>=1.0.2 || ^2.0.0' - version: 2.0.1 + version: 2.0.11 '@tanstack/react-router': specifier: workspace:* version: link:../react-router @@ -13083,8 +13083,8 @@ importers: version: 1.9.12 devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@tanstack/router-utils': specifier: workspace:* version: link:../router-utils @@ -13237,8 +13237,8 @@ importers: version: 4.4.3 devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@types/babel__code-frame': specifier: ^7.0.6 version: 7.0.6 @@ -13475,8 +13475,8 @@ importers: version: 2.0.3 devDependencies: '@rsbuild/core': - specifier: ^2.0.8 - version: 2.0.8 + specifier: ^2.0.11 + version: 2.0.11 '@tanstack/router-utils': specifier: workspace:* version: link:../router-utils @@ -18151,18 +18151,8 @@ packages: cpu: [x64] os: [win32] - '@rsbuild/core@2.0.1': - resolution: {integrity: sha512-5TwUpb10Y+VYaYH8oLL/rfJGrhxrk16BiGzv101kzaMPT60MtOXgjEUTxztbjRuq0ifbtRJ/w7rsIZQ4VziWYg==} - engines: {node: ^20.19.0 || >=22.12.0} - hasBin: true - peerDependencies: - core-js: '>= 3.0.0' - peerDependenciesMeta: - core-js: - optional: true - - '@rsbuild/core@2.0.8': - resolution: {integrity: sha512-V5Bhn3zqljsaB5grw9oMkSk6XZFvMkr6UpIYPZnDmOWsRAT1fNQ6XF6cn8fVUKv/KILblBrKLUZf0DpvDt3exw==} + '@rsbuild/core@2.0.11': + resolution: {integrity: sha512-Mpp/viUSkVdSWJkFipdZxM2nUztrBwSnMm6Q86bPzLHtHnXqQ3VFpSMlA4wWRyySNddP6s6efKiVpx0ZOCf7Gg==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -18234,8 +18224,8 @@ packages: cpu: [arm64] os: [darwin] - '@rspack/binding-darwin-arm64@2.0.5': - resolution: {integrity: sha512-++wjLQjQ20GcR0DwbzQmVXg9qy4XCX5NlfSzkzj2icHoDxr3KkrXhyVrQkdWuNG6l/bQrGLPnvLEAqkroC2Y7A==} + '@rspack/binding-darwin-arm64@2.0.6': + resolution: {integrity: sha512-0giCKiWlBfcM4i2scv1j2k9HlSecO9Ybhaa5wsMUyvcFeKr9HbNHh7C2eDFlC6zaI85IUdY71TXF/g/Tcxr9MA==} cpu: [arm64] os: [darwin] @@ -18244,8 +18234,8 @@ packages: cpu: [x64] os: [darwin] - '@rspack/binding-darwin-x64@2.0.5': - resolution: {integrity: sha512-JBD5mCN3JKjV64Mh9nDYx8lLUrWDfEl5tLBuMkREUnqEKbo+z4nfwotyqHHM8/XgZwL+Gr7ps4GLWuQQrZB8+Q==} + '@rspack/binding-darwin-x64@2.0.6': + resolution: {integrity: sha512-/mMo2IpI02aOKMlHbVbZue3TJxFqHGX+ibVTdEO+6bzRSuHs7+R9KM5U3XH2YxcWJy5Sid1X1T1pJAjsXcE3rA==} cpu: [x64] os: [darwin] @@ -18255,8 +18245,8 @@ packages: os: [linux] libc: [glibc] - '@rspack/binding-linux-arm64-gnu@2.0.5': - resolution: {integrity: sha512-JI8+//woanJPNsfL7iGjX39zyiWumnrKHznWQM/7lEtE5nPmk+j+X7TYXxczSWC9zfZegiqI74D3L5JPDC84Fw==} + '@rspack/binding-linux-arm64-gnu@2.0.6': + resolution: {integrity: sha512-H6ACzeM1KBxYDEF8YAim3501Jb1aCsSG79Gjm1M4pwJ5OJPK2ydiJEa438ugXmh0962eKYMHI2yZY0sQq8txaw==} cpu: [arm64] os: [linux] libc: [glibc] @@ -18267,8 +18257,8 @@ packages: os: [linux] libc: [musl] - '@rspack/binding-linux-arm64-musl@2.0.5': - resolution: {integrity: sha512-5LujilxLtJFRiiPz5i5iWcWJriK9oy4gN7gZtTo8YRB7wwmwA8LMypTjjO0GLbkPS4/KeCfY4fDfTC29KmK+tA==} + '@rspack/binding-linux-arm64-musl@2.0.6': + resolution: {integrity: sha512-QTFmBg0n+L397Wi8CIjbd5pe/hxpHnqCDaG1A7e2NWX8Fj9zulAoKLiKflQa1ELEhAY4Foq88aX75+Ilt2tHcw==} cpu: [arm64] os: [linux] libc: [musl] @@ -18279,8 +18269,8 @@ packages: os: [linux] libc: [glibc] - '@rspack/binding-linux-x64-gnu@2.0.5': - resolution: {integrity: sha512-241wqE132jh+/U/pn97qUPV4KpIy4bSrTH0tqfzQCocgw+8hrUj02GqNG+3MXVC3qtwaQeJFYgEBy3TqFKsrIQ==} + '@rspack/binding-linux-x64-gnu@2.0.6': + resolution: {integrity: sha512-rerCAz022zf0ewxI+7n3SrqLEaxCL+MXRxKjK5FLUGFa8UkIrivq+VUP/1OB6JLh2Bucebc7Y9WoWHvtk22mLA==} cpu: [x64] os: [linux] libc: [glibc] @@ -18291,8 +18281,8 @@ packages: os: [linux] libc: [musl] - '@rspack/binding-linux-x64-musl@2.0.5': - resolution: {integrity: sha512-BhaXZD064Lci3Kia0kLDAb4TyxO2C+0UidMlj44e8+ctasxIfFZgnrhCJrhTFHAtOiAwqhU3FHun2UuxPqX0Eg==} + '@rspack/binding-linux-x64-musl@2.0.6': + resolution: {integrity: sha512-96IgOFXQjX6Wbxd+DCYJFy2r/VMu1OoHifW4Cr3kGTYDKoQOIMLwb0ieu/ILp2dGWFMZo5S8odiByAmNICAOIA==} cpu: [x64] os: [linux] libc: [musl] @@ -18301,8 +18291,8 @@ packages: resolution: {integrity: sha512-ANk73ZKtPrZf9gdtyRK2nQUfhi1uXoC5P2KF89pyVAE8+zcoLBnYtZGYpWa/cmNi5BcO5g4Z+v2l1UA3bUPLQQ==} cpu: [wasm32] - '@rspack/binding-wasm32-wasi@2.0.5': - resolution: {integrity: sha512-duEkRoXrl9SW8uGHv7JURJ5lgKu87qFDQ4Exy6UQPvsUJVXhtRXTfvMHCb/CejVJuW2Bw2D632/axZq3qRSuBQ==} + '@rspack/binding-wasm32-wasi@2.0.6': + resolution: {integrity: sha512-0aWiF+qmdb0csp1x+MaR2o1pscoquLaEbLTVdKjmoTRs6sguMemtB1ObnVTahAUL73P66WePuNpFAJ81zNdqzQ==} cpu: [wasm32] '@rspack/binding-win32-arm64-msvc@2.0.0': @@ -18310,8 +18300,8 @@ packages: cpu: [arm64] os: [win32] - '@rspack/binding-win32-arm64-msvc@2.0.5': - resolution: {integrity: sha512-q2WT3HFoWL+2g84l3s2kY7CiE1gEZ1bwB3txx3eZzQQ6YKP7bE82z6sl6S/pTOHGjHdAO4snQXpSaHwUt3LX5g==} + '@rspack/binding-win32-arm64-msvc@2.0.6': + resolution: {integrity: sha512-BX638A1MXsjc2E3tUskVh3X/WBIHjLKK+lo395v7MmEL9u2BA6l3F6RyW+YaJOt5aEOOv83iA7iCZsviVZ49Uw==} cpu: [arm64] os: [win32] @@ -18320,8 +18310,8 @@ packages: cpu: [ia32] os: [win32] - '@rspack/binding-win32-ia32-msvc@2.0.5': - resolution: {integrity: sha512-nMJGIY7kvgbyMolEE7tXDe+Z9jSItDshTIqMQQkkD3WTHdjlBQozHxk4kBtKLsunO+3NkCLe5Oa3hXg1yyStIg==} + '@rspack/binding-win32-ia32-msvc@2.0.6': + resolution: {integrity: sha512-DCK/+MlN35uvH7tp4j0hbg8wIs9MHArMIrNZXtiD8xP6DNw2wrXcGC1VaxxR5apyWpqXAfIL/KsXBiWS3ygCvg==} cpu: [ia32] os: [win32] @@ -18330,16 +18320,16 @@ packages: cpu: [x64] os: [win32] - '@rspack/binding-win32-x64-msvc@2.0.5': - resolution: {integrity: sha512-vP0BR6fxdPL9cb02HAuZATg/CjR07aecWel3s1vqRwW1aDffgXh9PVmqEKIHTgyaNsNR55kSKNJsB9AcQ8/QrA==} + '@rspack/binding-win32-x64-msvc@2.0.6': + resolution: {integrity: sha512-TxutgzdEX9BkAU/5liKxdQmggJ23INz7EZDWtzSJO6C2SiSYzTJdyPQDIJi1ddkM5TX/drzH184gAJMVOQefng==} cpu: [x64] os: [win32] '@rspack/binding@2.0.0': resolution: {integrity: sha512-WA2f9eQpejkvf5Vrnf6wNCn1m8RT1p08NjgOZpKhsCzr0uBjWeRvGduawlrFFHZh/jPnWZTVaVdQ08FEAWbwGw==} - '@rspack/binding@2.0.5': - resolution: {integrity: sha512-Ta1y4WXJA87wM1OstqaMddoPsBGv7Cu779bYToKxEAqR/Yy9DxLkp7bdgBaAx2JH++BwVjV+toWts2V9AaiTFQ==} + '@rspack/binding@2.0.6': + resolution: {integrity: sha512-z5EO9mPlmYNpHAlRGub0Chr6D+Klgy+tX36n7tCm7VRGRlwTmTU9wSENrYbHcCpFbegtrE0s30rDeTBeOu+JiQ==} '@rspack/core@2.0.0': resolution: {integrity: sha512-WD1mJM9LbZ7Z399Rbv9dE3BNEV0+3sE5OzDdzV8hOxUb3mX++ynK5n9kil8w60B6nGdcKeV9ly5aN4PgqiwWUg==} @@ -18353,8 +18343,8 @@ packages: '@swc/helpers': optional: true - '@rspack/core@2.0.5': - resolution: {integrity: sha512-9tv2HAnSiTote5WPH2tmz1hLZ1zKbzkiZc1eYp7LP/8jcsiJBuf40ihiWidAgbbuYtJo3kWET6q+qOm5UhNiGA==} + '@rspack/core@2.0.6': + resolution: {integrity: sha512-ronRqH1T2dYdMFVOQbGvDNxYaLugQK8qhNYYtS2DbOvPKQYvdIYWDenL9k/WV+hLoknnPWMn2ME2cKJcK3Po+g==} engines: {node: ^20.19.0 || >=22.12.0} peerDependencies: '@module-federation/runtime-tools': ^0.24.1 || ^2.0.0 @@ -18813,9 +18803,6 @@ packages: '@swc/helpers@0.5.15': resolution: {integrity: sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==} - '@swc/helpers@0.5.21': - resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} - '@swc/helpers@0.5.23': resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} @@ -31392,27 +31379,20 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.56.0': optional: true - '@rsbuild/core@2.0.1': + '@rsbuild/core@2.0.11': dependencies: - '@rspack/core': 2.0.0(@swc/helpers@0.5.21) - '@swc/helpers': 0.5.21 - transitivePeerDependencies: - - '@module-federation/runtime-tools' - - '@rsbuild/core@2.0.8': - dependencies: - '@rspack/core': 2.0.5(@swc/helpers@0.5.23) + '@rspack/core': 2.0.6(@swc/helpers@0.5.23) '@swc/helpers': 0.5.23 transitivePeerDependencies: - '@module-federation/runtime-tools' - '@rsbuild/plugin-babel@1.0.6(@rsbuild/core@2.0.8)': + '@rsbuild/plugin-babel@1.0.6(@rsbuild/core@2.0.11)': dependencies: '@babel/core': 7.28.5 '@babel/plugin-proposal-decorators': 7.28.0(@babel/core@7.28.5) '@babel/plugin-transform-class-properties': 7.27.1(@babel/core@7.28.5) '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) - '@rsbuild/core': 2.0.8 + '@rsbuild/core': 2.0.11 '@types/babel__core': 7.20.5 deepmerge: 4.3.1 reduce-configs: 1.1.1 @@ -31420,7 +31400,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@rsbuild/plugin-babel@1.1.2(@rsbuild/core@2.0.1)': + '@rsbuild/plugin-babel@1.1.2(@rsbuild/core@2.0.11)': dependencies: '@babel/core': 7.29.0 '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) @@ -31429,90 +31409,56 @@ snapshots: '@types/babel__core': 7.20.5 reduce-configs: 1.1.1 optionalDependencies: - '@rsbuild/core': 2.0.1 + '@rsbuild/core': 2.0.11 transitivePeerDependencies: - supports-color - '@rsbuild/plugin-babel@1.1.2(@rsbuild/core@2.0.8)': + '@rsbuild/plugin-react@2.0.0(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23))': dependencies: - '@babel/core': 7.29.0 - '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) - '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) - '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) - '@types/babel__core': 7.20.5 - reduce-configs: 1.1.1 - optionalDependencies: - '@rsbuild/core': 2.0.8 - transitivePeerDependencies: - - supports-color - - '@rsbuild/plugin-react@2.0.0(@rsbuild/core@2.0.1)(@rspack/core@2.0.5(@swc/helpers@0.5.23))': - dependencies: - '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.0.5(@swc/helpers@0.5.23))(react-refresh@0.18.0) + '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.0.6(@swc/helpers@0.5.23))(react-refresh@0.18.0) react-refresh: 0.18.0 optionalDependencies: - '@rsbuild/core': 2.0.1 + '@rsbuild/core': 2.0.11 transitivePeerDependencies: - '@rspack/core' - '@rsbuild/plugin-react@2.0.0(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23))': + '@rsbuild/plugin-solid@1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)(solid-js@1.9.12)': dependencies: - '@rspack/plugin-react-refresh': 2.0.0(@rspack/core@2.0.5(@swc/helpers@0.5.23))(react-refresh@0.18.0) - react-refresh: 0.18.0 - optionalDependencies: - '@rsbuild/core': 2.0.8 - transitivePeerDependencies: - - '@rspack/core' - - '@rsbuild/plugin-solid@1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.1)(solid-js@1.9.12)': - dependencies: - '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.1) - babel-preset-solid: 1.9.10(@babel/core@7.29.0)(solid-js@1.9.12) - solid-refresh: 0.7.8(solid-js@1.9.12) - optionalDependencies: - '@rsbuild/core': 2.0.1 - transitivePeerDependencies: - - '@babel/core' - - solid-js - - supports-color - - '@rsbuild/plugin-solid@1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8)(solid-js@1.9.12)': - dependencies: - '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.8) + '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.11) babel-preset-solid: 1.9.10(@babel/core@7.29.0)(solid-js@1.9.12) solid-refresh: 0.7.8(solid-js@1.9.12) optionalDependencies: - '@rsbuild/core': 2.0.8 + '@rsbuild/core': 2.0.11 transitivePeerDependencies: - '@babel/core' - solid-js - supports-color - '@rsbuild/plugin-vue-jsx@1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.8)': + '@rsbuild/plugin-vue-jsx@1.1.1(@babel/core@7.29.0)(@rsbuild/core@2.0.11)': dependencies: - '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.8) + '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.11) '@vue/babel-plugin-jsx': 1.5.0(@babel/core@7.29.0) babel-plugin-vue-jsx-hmr: 1.0.0 optionalDependencies: - '@rsbuild/core': 2.0.8 + '@rsbuild/core': 2.0.11 transitivePeerDependencies: - '@babel/core' - supports-color - '@rsbuild/plugin-vue-jsx@2.0.0(@babel/core@7.29.0)(@rsbuild/core@2.0.8)': + '@rsbuild/plugin-vue-jsx@2.0.0(@babel/core@7.29.0)(@rsbuild/core@2.0.11)': dependencies: - '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.8) + '@rsbuild/plugin-babel': 1.1.2(@rsbuild/core@2.0.11) '@vue/babel-plugin-jsx': 2.0.1(@babel/core@7.29.0) babel-plugin-vue-jsx-hmr: 1.0.0 optionalDependencies: - '@rsbuild/core': 2.0.8 + '@rsbuild/core': 2.0.11 transitivePeerDependencies: - '@babel/core' - supports-color - '@rsbuild/plugin-vue@1.2.2(@rsbuild/core@2.0.8)(@swc/core@1.15.33(@swc/helpers@0.5.23))(esbuild@0.27.4)(vue@3.5.25(typescript@6.0.2))': + '@rsbuild/plugin-vue@1.2.2(@rsbuild/core@2.0.11)(@swc/core@1.15.33(@swc/helpers@0.5.23))(esbuild@0.27.4)(vue@3.5.25(typescript@6.0.2))': dependencies: - '@rsbuild/core': 2.0.8 + '@rsbuild/core': 2.0.11 rspack-vue-loader: 17.4.4(vue@3.5.25(typescript@6.0.2))(webpack@5.104.0(@swc/core@1.15.33(@swc/helpers@0.5.23))(esbuild@0.27.4)) webpack: 5.104.0(@swc/core@1.15.33(@swc/helpers@0.5.23))(esbuild@0.27.4) transitivePeerDependencies: @@ -31523,11 +31469,11 @@ snapshots: - vue - webpack-cli - '@rsbuild/plugin-vue@1.2.7(@rsbuild/core@2.0.8)(@rspack/core@2.0.5(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2))': + '@rsbuild/plugin-vue@1.2.7(@rsbuild/core@2.0.11)(@rspack/core@2.0.6(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2))': dependencies: - rspack-vue-loader: 17.5.0(@rspack/core@2.0.5(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)) + rspack-vue-loader: 17.5.0(@rspack/core@2.0.6(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)) optionalDependencies: - '@rsbuild/core': 2.0.8 + '@rsbuild/core': 2.0.11 transitivePeerDependencies: - '@rspack/core' - '@vue/compiler-sfc' @@ -31536,37 +31482,37 @@ snapshots: '@rspack/binding-darwin-arm64@2.0.0': optional: true - '@rspack/binding-darwin-arm64@2.0.5': + '@rspack/binding-darwin-arm64@2.0.6': optional: true '@rspack/binding-darwin-x64@2.0.0': optional: true - '@rspack/binding-darwin-x64@2.0.5': + '@rspack/binding-darwin-x64@2.0.6': optional: true '@rspack/binding-linux-arm64-gnu@2.0.0': optional: true - '@rspack/binding-linux-arm64-gnu@2.0.5': + '@rspack/binding-linux-arm64-gnu@2.0.6': optional: true '@rspack/binding-linux-arm64-musl@2.0.0': optional: true - '@rspack/binding-linux-arm64-musl@2.0.5': + '@rspack/binding-linux-arm64-musl@2.0.6': optional: true '@rspack/binding-linux-x64-gnu@2.0.0': optional: true - '@rspack/binding-linux-x64-gnu@2.0.5': + '@rspack/binding-linux-x64-gnu@2.0.6': optional: true '@rspack/binding-linux-x64-musl@2.0.0': optional: true - '@rspack/binding-linux-x64-musl@2.0.5': + '@rspack/binding-linux-x64-musl@2.0.6': optional: true '@rspack/binding-wasm32-wasi@2.0.0': @@ -31576,7 +31522,7 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.4(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) optional: true - '@rspack/binding-wasm32-wasi@2.0.5': + '@rspack/binding-wasm32-wasi@2.0.6': dependencies: '@emnapi/core': 1.10.0 '@emnapi/runtime': 1.10.0 @@ -31586,19 +31532,19 @@ snapshots: '@rspack/binding-win32-arm64-msvc@2.0.0': optional: true - '@rspack/binding-win32-arm64-msvc@2.0.5': + '@rspack/binding-win32-arm64-msvc@2.0.6': optional: true '@rspack/binding-win32-ia32-msvc@2.0.0': optional: true - '@rspack/binding-win32-ia32-msvc@2.0.5': + '@rspack/binding-win32-ia32-msvc@2.0.6': optional: true '@rspack/binding-win32-x64-msvc@2.0.0': optional: true - '@rspack/binding-win32-x64-msvc@2.0.5': + '@rspack/binding-win32-x64-msvc@2.0.6': optional: true '@rspack/binding@2.0.0': @@ -31614,24 +31560,18 @@ snapshots: '@rspack/binding-win32-ia32-msvc': 2.0.0 '@rspack/binding-win32-x64-msvc': 2.0.0 - '@rspack/binding@2.0.5': - optionalDependencies: - '@rspack/binding-darwin-arm64': 2.0.5 - '@rspack/binding-darwin-x64': 2.0.5 - '@rspack/binding-linux-arm64-gnu': 2.0.5 - '@rspack/binding-linux-arm64-musl': 2.0.5 - '@rspack/binding-linux-x64-gnu': 2.0.5 - '@rspack/binding-linux-x64-musl': 2.0.5 - '@rspack/binding-wasm32-wasi': 2.0.5 - '@rspack/binding-win32-arm64-msvc': 2.0.5 - '@rspack/binding-win32-ia32-msvc': 2.0.5 - '@rspack/binding-win32-x64-msvc': 2.0.5 - - '@rspack/core@2.0.0(@swc/helpers@0.5.21)': - dependencies: - '@rspack/binding': 2.0.0 + '@rspack/binding@2.0.6': optionalDependencies: - '@swc/helpers': 0.5.21 + '@rspack/binding-darwin-arm64': 2.0.6 + '@rspack/binding-darwin-x64': 2.0.6 + '@rspack/binding-linux-arm64-gnu': 2.0.6 + '@rspack/binding-linux-arm64-musl': 2.0.6 + '@rspack/binding-linux-x64-gnu': 2.0.6 + '@rspack/binding-linux-x64-musl': 2.0.6 + '@rspack/binding-wasm32-wasi': 2.0.6 + '@rspack/binding-win32-arm64-msvc': 2.0.6 + '@rspack/binding-win32-ia32-msvc': 2.0.6 + '@rspack/binding-win32-x64-msvc': 2.0.6 '@rspack/core@2.0.0(@swc/helpers@0.5.23)': dependencies: @@ -31639,19 +31579,19 @@ snapshots: optionalDependencies: '@swc/helpers': 0.5.23 - '@rspack/core@2.0.5(@swc/helpers@0.5.23)': + '@rspack/core@2.0.6(@swc/helpers@0.5.23)': dependencies: - '@rspack/binding': 2.0.5 + '@rspack/binding': 2.0.6 optionalDependencies: '@swc/helpers': 0.5.23 '@rspack/lite-tapable@1.1.0': {} - '@rspack/plugin-react-refresh@2.0.0(@rspack/core@2.0.5(@swc/helpers@0.5.23))(react-refresh@0.18.0)': + '@rspack/plugin-react-refresh@2.0.0(@rspack/core@2.0.6(@swc/helpers@0.5.23))(react-refresh@0.18.0)': dependencies: react-refresh: 0.18.0 optionalDependencies: - '@rspack/core': 2.0.5(@swc/helpers@0.5.23) + '@rspack/core': 2.0.6(@swc/helpers@0.5.23) '@rushstack/node-core-library@5.7.0(@types/node@25.0.9)': dependencies: @@ -32101,10 +32041,6 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/helpers@0.5.21': - dependencies: - tslib: 2.8.1 - '@swc/helpers@0.5.23': dependencies: tslib: 2.8.1 @@ -39405,12 +39341,12 @@ snapshots: optionalDependencies: vue: 3.5.25(typescript@6.0.2) - rspack-vue-loader@17.5.0(@rspack/core@2.0.5(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)): + rspack-vue-loader@17.5.0(@rspack/core@2.0.6(@swc/helpers@0.5.23))(vue@3.5.25(typescript@6.0.2)): dependencies: '@rspack/lite-tapable': 1.1.0 chalk: 4.1.2 optionalDependencies: - '@rspack/core': 2.0.5(@swc/helpers@0.5.23) + '@rspack/core': 2.0.6(@swc/helpers@0.5.23) vue: 3.5.25(typescript@6.0.2) run-applescript@7.0.0: {} From 5b3668058f0e634e859acfda0013f765eaa7efc1 Mon Sep 17 00:00:00 2001 From: Elecmonkey Date: Tue, 16 Jun 2026 14:55:35 +0800 Subject: [PATCH 2/2] fix(start-plugin-core): always install rsbuild SSR middleware in preview Preview is the only SSR handler in `rsbuild preview`, so gate the opt-out to dev only and keep the option named `installDevServerMiddleware`. --- .changeset/quiet-rsbuild-preview.md | 2 +- e2e/react-start/custom-server-rsbuild/rsbuild.config.ts | 2 +- packages/start-plugin-core/src/rsbuild/plugin.ts | 8 +++++--- packages/start-plugin-core/src/rsbuild/schema.ts | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.changeset/quiet-rsbuild-preview.md b/.changeset/quiet-rsbuild-preview.md index f0f1421b83..f3378b21ff 100644 --- a/.changeset/quiet-rsbuild-preview.md +++ b/.changeset/quiet-rsbuild-preview.md @@ -2,4 +2,4 @@ '@tanstack/start-plugin-core': patch --- -Fix Rsbuild preview support for TanStack Start SSR and rename the middleware option to `installServerMiddleware`. +Fix Rsbuild preview support for TanStack Start SSR. Preview always installs the SSR middleware; the `installDevServerMiddleware` option only applies to dev. diff --git a/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts b/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts index 739b159c5e..dec3a6d0fc 100644 --- a/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts +++ b/e2e/react-start/custom-server-rsbuild/rsbuild.config.ts @@ -31,7 +31,7 @@ export default defineConfig({ pluginReact({ splitChunks: false }), tanstackStart({ rsbuild: { - installServerMiddleware: false, + installDevServerMiddleware: false, client: { output: 'iife', }, diff --git a/packages/start-plugin-core/src/rsbuild/plugin.ts b/packages/start-plugin-core/src/rsbuild/plugin.ts index 95bfb4b368..3de4ed8c2f 100644 --- a/packages/start-plugin-core/src/rsbuild/plugin.ts +++ b/packages/start-plugin-core/src/rsbuild/plugin.ts @@ -160,7 +160,6 @@ export function tanStackStartRsbuild( const resolvedEntryPlan = configContext.resolveEntries() const isDev = api.context.action === 'dev' const isPreview = api.context.action === 'preview' - const shouldInstallServerMiddleware = isDev || isPreview const entryAliases = createRsbuildResolvedEntryAliases({ entryPaths: resolvedEntryPlan.entryPaths, @@ -258,8 +257,11 @@ export function tanStackStartRsbuild( htmlFallback: false, // server.setup returned callback runs after built-in middleware // but BEFORE fallback middleware — the ideal slot for SSR. - ...(shouldInstallServerMiddleware && - startPluginOpts.rsbuild?.installServerMiddleware !== false + // Preview always installs the middleware since it is the only SSR + // handler; dev can opt out when a custom server hosts SSR. + ...(isPreview || + (isDev && + startPluginOpts.rsbuild?.installDevServerMiddleware !== false) ? { setup: createServerSetup({ serverFnBasePath: serverFnBase, diff --git a/packages/start-plugin-core/src/rsbuild/schema.ts b/packages/start-plugin-core/src/rsbuild/schema.ts index 5bccbae71f..86194e309c 100644 --- a/packages/start-plugin-core/src/rsbuild/schema.ts +++ b/packages/start-plugin-core/src/rsbuild/schema.ts @@ -13,7 +13,7 @@ export const tanstackStartRsbuildOptionsSchema = .extend({ rsbuild: z .object({ - installServerMiddleware: z.boolean().optional(), + installDevServerMiddleware: z.boolean().optional(), client: z .object({ output: rsbuildClientOutputSchema.optional().default('module'), @@ -41,7 +41,7 @@ export type TanStackStartRsbuildInputConfig = z.input< typeof tanstackStartRsbuildOptionsSchema > & { rsbuild?: { - installServerMiddleware?: boolean + installDevServerMiddleware?: boolean client?: { output?: z.input }