From d3daa3a0df8df15aa09d8f2d1b5bb79694d19f7a Mon Sep 17 00:00:00 2001 From: Pooya Parsa Date: Wed, 5 Nov 2025 11:08:13 +0100 Subject: [PATCH 1/3] perf(rsc): use `srvx/node` --- packages/plugin-rsc/package.json | 2 +- packages/plugin-rsc/src/plugin.ts | 10 ++++------ pnpm-lock.yaml | 18 ++++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/plugin-rsc/package.json b/packages/plugin-rsc/package.json index 3656a421..a75254b1 100644 --- a/packages/plugin-rsc/package.json +++ b/packages/plugin-rsc/package.json @@ -39,11 +39,11 @@ "prepack": "tsdown" }, "dependencies": { - "@remix-run/node-fetch-server": "^0.11.0", "es-module-lexer": "^1.7.0", "estree-walker": "^3.0.3", "magic-string": "^0.30.21", "periscopic": "^4.0.2", + "srvx": "^0.9.5", "strip-literal": "^3.1.0", "turbo-stream": "^3.1.0", "vitefu": "^1.1.1" diff --git a/packages/plugin-rsc/src/plugin.ts b/packages/plugin-rsc/src/plugin.ts index 4851bbab..560a6132 100644 --- a/packages/plugin-rsc/src/plugin.ts +++ b/packages/plugin-rsc/src/plugin.ts @@ -3,7 +3,7 @@ import fs from 'node:fs' import { createRequire } from 'node:module' import path from 'node:path' import { pathToFileURL } from 'node:url' -import { createRequestListener } from '@remix-run/node-fetch-server' +import { toNodeHandler } from 'srvx/node' import * as esModuleLexer from 'es-module-lexer' import MagicString from 'magic-string' import * as vite from 'vite' @@ -537,9 +537,7 @@ export default function vitePluginRsc( // for example, this restores `base` which is automatically stripped by Vite. // https://github.com/vitejs/vite/blob/84079a84ad94de4c1ef4f1bdb2ab448ff2c01196/packages/vite/src/node/server/middlewares/base.ts#L18-L20 req.url = req.originalUrl ?? req.url - // ensure catching rejected promise - // https://github.com/mjackson/remix-the-web/blob/b5aa2ae24558f5d926af576482caf6e9b35461dc/packages/node-fetch-server/src/lib/request-listener.ts#L87 - await createRequestListener(fetchHandler)(req, res) + await toNodeHandler(fetchHandler)(req, res) } catch (e) { next(e) } @@ -560,7 +558,7 @@ export default function vitePluginRsc( const entry = pathToFileURL(entryFile).href const mod = await import(/* @vite-ignore */ entry) const fetchHandler = getFetchHandlerExport(mod) - const handler = createRequestListener(fetchHandler) + const handler = toNodeHandler(fetchHandler) // disable compressions since it breaks html streaming // https://github.com/vitejs/vite/blob/9f5c59f07aefb1756a37bcb1c0aff24d54288950/packages/vite/src/node/preview.ts#L178 @@ -841,7 +839,7 @@ export default function vitePluginRsc( if (url.pathname === '/__vite_rsc_load_module_dev_proxy') { try { const handler = await createHandler(url) - createRequestListener(handler)(req, res) + await toNodeHandler(handler)(req, res) } catch (e) { next(e) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 67c642c7..a576a401 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -436,9 +436,6 @@ importers: packages/plugin-rsc: dependencies: - '@remix-run/node-fetch-server': - specifier: ^0.11.0 - version: 0.11.0 es-module-lexer: specifier: ^1.7.0 version: 1.7.0 @@ -451,6 +448,9 @@ importers: periscopic: specifier: ^4.0.2 version: 4.0.2 + srvx: + specifier: ^0.9.5 + version: 0.9.5 strip-literal: specifier: ^3.1.0 version: 3.1.0 @@ -1788,9 +1788,6 @@ packages: '@quansync/fs@0.1.5': resolution: {integrity: sha512-lNS9hL2aS2NZgNW7BBj+6EBl4rOf8l+tQ0eRY6JWCI8jI2kc53gSoqbjojU0OnAWhzoXiOjFyGsHcDGePB3lhA==} - '@remix-run/node-fetch-server@0.11.0': - resolution: {integrity: sha512-nCrFHVxDFioSHc0g/3m5ztwgjBt7g8qh/UwmYkDjuMePKFepMKfNGgH5S6L7iXKX+jUrf3ooVmhx3NGIoa9iYA==} - '@remix-run/node-fetch-server@0.8.0': resolution: {integrity: sha512-8/sKegb4HrM6IdcQeU0KPhj9VOHm5SUqswJDHuMCS3mwbr/NRx078QDbySmn0xslahvvZoOENd7EnK40kWKxkg==} @@ -4251,6 +4248,11 @@ packages: spdx-license-ids@3.0.21: resolution: {integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==} + srvx@0.9.5: + resolution: {integrity: sha512-nQsA2c8q3XwbSn6kTxVQjz0zS096rV+Be2pzJwrYEAdtnYszLw4MTy8JWJjz1XEGBZwP0qW51SUIX3WdjdRemQ==} + engines: {node: '>=20.16.0'} + hasBin: true + stable-hash-x@0.2.0: resolution: {integrity: sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==} engines: {node: '>=12.0.0'} @@ -5411,8 +5413,6 @@ snapshots: dependencies: quansync: 0.2.11 - '@remix-run/node-fetch-server@0.11.0': {} - '@remix-run/node-fetch-server@0.8.0': {} '@rolldown/binding-android-arm64@1.0.0-beta.45': @@ -7916,6 +7916,8 @@ snapshots: spdx-license-ids@3.0.21: {} + srvx@0.9.5: {} + stable-hash-x@0.2.0: {} stackback@0.0.2: {} From de6204b67b84ea3ea5b77bdcd5b3bc56ce9d87e3 Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 6 Nov 2025 09:36:03 +0900 Subject: [PATCH 2/3] test: more srvx --- packages/plugin-rsc/examples/e2e/middleware-mode.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin-rsc/examples/e2e/middleware-mode.ts b/packages/plugin-rsc/examples/e2e/middleware-mode.ts index 2b0c38cd..352ea597 100644 --- a/packages/plugin-rsc/examples/e2e/middleware-mode.ts +++ b/packages/plugin-rsc/examples/e2e/middleware-mode.ts @@ -2,7 +2,7 @@ import path from 'node:path' import { pathToFileURL } from 'node:url' // @ts-ignore import connect from 'connect' -import { createRequestListener } from '@remix-run/node-fetch-server' +import { toNodeHandler } from 'srvx/node' import sirv from 'sirv' import type { Connect } from 'vite' @@ -28,7 +28,7 @@ async function main() { const entry = await import( pathToFileURL(path.resolve('dist/rsc/index.js')).href ) - app.use(createRequestListener(entry.default)) + app.use(toNodeHandler(entry.default)) } else { console.error(`Unknown command: ${command}`) process.exitCode = 1 From efebcc5742068cb2b8932fbd25a180e7f6848c9f Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Thu, 6 Nov 2025 09:49:13 +0900 Subject: [PATCH 3/3] wip: playwright workers: 1 --- packages/plugin-rsc/playwright.config.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/plugin-rsc/playwright.config.ts b/packages/plugin-rsc/playwright.config.ts index 520a08ef..d706e20d 100644 --- a/packages/plugin-rsc/playwright.config.ts +++ b/packages/plugin-rsc/playwright.config.ts @@ -27,7 +27,8 @@ export default defineConfig({ use: devices['Desktop Safari'], }, ], - workers: 2, + // workers: 2, + workers: 1, forbidOnly: !!process.env.CI, retries: process.env.CI ? 2 : 0, reporter: ['list', process.env.CI && 'github']