From 819175d6920d023803f71f686694b2cde2a305e6 Mon Sep 17 00:00:00 2001 From: Manuel Schiller <6340397+schiller-manuel@users.noreply.github.com> Date: Mon, 3 Aug 2026 23:14:24 +0200 Subject: [PATCH] fix(start): keep server-only routes out of RSC bundles Use the Start storage context for request cancellation and focused server entrypoints to keep unrelated route dependencies out of the RSC module graph. Add emitted-build regression coverage for the boundary. fixes #7938 --- .changeset/calm-barrels-focus.md | 8 ++ .changeset/tidy-ravens-rest.md | 5 ++ e2e/react-start/rsc/src/routeTree.gen.ts | 21 +++++ .../rsc/src/routes/api.rsc-build-boundary.ts | 14 +++ .../rsc/src/utils/rscBuildBoundarySentinel.ts | 3 + .../rsc/tests/rsc-build-boundary.spec.ts | 87 +++++++++++++++++++ packages/react-start-rsc/eslint.config.js | 27 ++++++ packages/react-start-rsc/package.json | 1 - .../src/createCompositeComponent.ts | 3 +- .../src/renderServerComponent.ts | 3 +- .../tests/createServerComponent.test-d.tsx | 13 +-- .../src/defaultRenderHandler.tsx | 6 +- .../src/defaultStreamHandler.tsx | 6 +- packages/start-plugin-core/src/post-build.ts | 2 +- .../src/rsbuild/virtual-modules.ts | 2 +- .../src/vite/serialization-adapters-plugin.ts | 2 +- .../src/vite/start-compiler-plugin/plugin.ts | 2 +- .../src/vite/start-manifest-plugin/plugin.ts | 2 +- .../tests/post-server-build.test.ts | 2 +- .../tests/rsbuild/post-build.test.ts | 2 +- .../tests/start-manifest-plugin.test.ts | 4 +- packages/start-server-core/package.json | 12 +++ packages/start-server-core/vite.config.ts | 2 + .../src/defaultRenderHandler.tsx | 6 +- .../src/defaultStreamHandler.tsx | 6 +- pnpm-lock.yaml | 3 - 26 files changed, 207 insertions(+), 37 deletions(-) create mode 100644 .changeset/calm-barrels-focus.md create mode 100644 .changeset/tidy-ravens-rest.md create mode 100644 e2e/react-start/rsc/src/routes/api.rsc-build-boundary.ts create mode 100644 e2e/react-start/rsc/src/utils/rscBuildBoundarySentinel.ts create mode 100644 e2e/react-start/rsc/tests/rsc-build-boundary.spec.ts diff --git a/.changeset/calm-barrels-focus.md b/.changeset/calm-barrels-focus.md new file mode 100644 index 0000000000..d44541be14 --- /dev/null +++ b/.changeset/calm-barrels-focus.md @@ -0,0 +1,8 @@ +--- +'@tanstack/start-server-core': patch +'@tanstack/start-plugin-core': patch +'@tanstack/solid-start-server': patch +'@tanstack/vue-start-server': patch +--- + +Use focused server entrypoints for shared constants and handler helpers so build tooling and framework renderers do not traverse the full Start server barrel. diff --git a/.changeset/tidy-ravens-rest.md b/.changeset/tidy-ravens-rest.md new file mode 100644 index 0000000000..b81144ad53 --- /dev/null +++ b/.changeset/tidy-ravens-rest.md @@ -0,0 +1,5 @@ +--- +'@tanstack/react-start-rsc': patch +--- + +Read request cancellation from the Start storage context so RSC helpers do not pull the Start server barrel into the RSC module graph. diff --git a/e2e/react-start/rsc/src/routeTree.gen.ts b/e2e/react-start/rsc/src/routeTree.gen.ts index 209c514f89..38137dfb4b 100644 --- a/e2e/react-start/rsc/src/routeTree.gen.ts +++ b/e2e/react-start/rsc/src/routeTree.gen.ts @@ -51,6 +51,7 @@ import { Route as RscStreamingRouteImport } from './routes/rsc-streaming' import { Route as RscSuspenseRouteImport } from './routes/rsc-suspense' import { Route as RscTreeRouteImport } from './routes/rsc-tree' import { Route as RscUseServerFnRouteImport } from './routes/rsc-use-server-fn' +import { Route as ApiRscBuildBoundaryRouteImport } from './routes/api.rsc-build-boundary' import { Route as ApiRscFlightRouteImport } from './routes/api.rsc-flight' import { Route as RscCssConditionalIndexRouteImport } from './routes/rsc-css-conditional.index' import { Route as RscCssConditionalBranchRouteImport } from './routes/rsc-css-conditional.$branch' @@ -267,6 +268,11 @@ const RscUseServerFnRoute = RscUseServerFnRouteImport.update({ path: '/rsc-use-server-fn', getParentRoute: () => rootRouteImport, } as any) +const ApiRscBuildBoundaryRoute = ApiRscBuildBoundaryRouteImport.update({ + id: '/api/rsc-build-boundary', + path: '/api/rsc-build-boundary', + getParentRoute: () => rootRouteImport, +} as any) const ApiRscFlightRoute = ApiRscFlightRouteImport.update({ id: '/api/rsc-flight', path: '/api/rsc-flight', @@ -336,6 +342,7 @@ export interface FileRoutesByFullPath { '/rsc-suspense': typeof RscSuspenseRoute '/rsc-tree': typeof RscTreeRoute '/rsc-use-server-fn': typeof RscUseServerFnRoute + '/api/rsc-build-boundary': typeof ApiRscBuildBoundaryRoute '/api/rsc-flight': typeof ApiRscFlightRoute '/rsc-css-conditional/$branch': typeof RscCssConditionalBranchRoute '/rsc-param/$id': typeof RscParamIdRoute @@ -385,6 +392,7 @@ export interface FileRoutesByTo { '/rsc-suspense': typeof RscSuspenseRoute '/rsc-tree': typeof RscTreeRoute '/rsc-use-server-fn': typeof RscUseServerFnRoute + '/api/rsc-build-boundary': typeof ApiRscBuildBoundaryRoute '/api/rsc-flight': typeof ApiRscFlightRoute '/rsc-css-conditional/$branch': typeof RscCssConditionalBranchRoute '/rsc-param/$id': typeof RscParamIdRoute @@ -435,6 +443,7 @@ export interface FileRoutesById { '/rsc-suspense': typeof RscSuspenseRoute '/rsc-tree': typeof RscTreeRoute '/rsc-use-server-fn': typeof RscUseServerFnRoute + '/api/rsc-build-boundary': typeof ApiRscBuildBoundaryRoute '/api/rsc-flight': typeof ApiRscFlightRoute '/rsc-css-conditional/$branch': typeof RscCssConditionalBranchRoute '/rsc-param/$id': typeof RscParamIdRoute @@ -486,6 +495,7 @@ export interface FileRouteTypes { | '/rsc-suspense' | '/rsc-tree' | '/rsc-use-server-fn' + | '/api/rsc-build-boundary' | '/api/rsc-flight' | '/rsc-css-conditional/$branch' | '/rsc-param/$id' @@ -535,6 +545,7 @@ export interface FileRouteTypes { | '/rsc-suspense' | '/rsc-tree' | '/rsc-use-server-fn' + | '/api/rsc-build-boundary' | '/api/rsc-flight' | '/rsc-css-conditional/$branch' | '/rsc-param/$id' @@ -584,6 +595,7 @@ export interface FileRouteTypes { | '/rsc-suspense' | '/rsc-tree' | '/rsc-use-server-fn' + | '/api/rsc-build-boundary' | '/api/rsc-flight' | '/rsc-css-conditional/$branch' | '/rsc-param/$id' @@ -634,6 +646,7 @@ export interface RootRouteChildren { RscSuspenseRoute: typeof RscSuspenseRoute RscTreeRoute: typeof RscTreeRoute RscUseServerFnRoute: typeof RscUseServerFnRoute + ApiRscBuildBoundaryRoute: typeof ApiRscBuildBoundaryRoute ApiRscFlightRoute: typeof ApiRscFlightRoute RscCssConditionalBranchRoute: typeof RscCssConditionalBranchRoute RscParamIdRoute: typeof RscParamIdRoute @@ -937,6 +950,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof RscUseServerFnRouteImport parentRoute: typeof rootRouteImport } + '/api/rsc-build-boundary': { + id: '/api/rsc-build-boundary' + path: '/api/rsc-build-boundary' + fullPath: '/api/rsc-build-boundary' + preLoaderRoute: typeof ApiRscBuildBoundaryRouteImport + parentRoute: typeof rootRouteImport + } '/api/rsc-flight': { id: '/api/rsc-flight' path: '/api/rsc-flight' @@ -1018,6 +1038,7 @@ const rootRouteChildren: RootRouteChildren = { RscSuspenseRoute: RscSuspenseRoute, RscTreeRoute: RscTreeRoute, RscUseServerFnRoute: RscUseServerFnRoute, + ApiRscBuildBoundaryRoute: ApiRscBuildBoundaryRoute, ApiRscFlightRoute: ApiRscFlightRoute, RscCssConditionalBranchRoute: RscCssConditionalBranchRoute, RscParamIdRoute: RscParamIdRoute, diff --git a/e2e/react-start/rsc/src/routes/api.rsc-build-boundary.ts b/e2e/react-start/rsc/src/routes/api.rsc-build-boundary.ts new file mode 100644 index 0000000000..d29d2a8cb8 --- /dev/null +++ b/e2e/react-start/rsc/src/routes/api.rsc-build-boundary.ts @@ -0,0 +1,14 @@ +import { createFileRoute } from '@tanstack/react-router' +import { getRscBuildBoundarySentinel } from '~/utils/rscBuildBoundarySentinel' + +export const Route = createFileRoute('/api/rsc-build-boundary')({ + server: { + handlers: { + GET: () => { + return new Response(getRscBuildBoundarySentinel(), { + headers: { 'Content-Type': 'text/plain' }, + }) + }, + }, + }, +}) diff --git a/e2e/react-start/rsc/src/utils/rscBuildBoundarySentinel.ts b/e2e/react-start/rsc/src/utils/rscBuildBoundarySentinel.ts new file mode 100644 index 0000000000..706adb30d9 --- /dev/null +++ b/e2e/react-start/rsc/src/utils/rscBuildBoundarySentinel.ts @@ -0,0 +1,3 @@ +export function getRscBuildBoundarySentinel() { + return 'tanstack-start-rsc-server-only-route-sentinel' +} diff --git a/e2e/react-start/rsc/tests/rsc-build-boundary.spec.ts b/e2e/react-start/rsc/tests/rsc-build-boundary.spec.ts new file mode 100644 index 0000000000..f57fefe994 --- /dev/null +++ b/e2e/react-start/rsc/tests/rsc-build-boundary.spec.ts @@ -0,0 +1,87 @@ +import { readdir, readFile } from 'node:fs/promises' +import path from 'node:path' +import { expect } from '@playwright/test' +import { test } from '@tanstack/router-e2e-utils' + +// This marker deliberately lives behind a server-only route. If its route +// dependency graph enters the RSC build, the emitted-file assertion will fail. +const SENTINEL = 'tanstack-start-rsc-server-only-route-sentinel' +const EXECUTABLE_EXTENSIONS = new Set(['.js', '.mjs', '.cjs']) + +const distDir = path.resolve(process.cwd(), process.env.E2E_DIST_DIR ?? 'dist') +const serverDir = path.join(distDir, 'server') +const rscDir = path.join(serverDir, 'rsc') + +async function findExecutableFiles( + directory: string, + excludedDirectories = new Set(), +): Promise> { + const entries = await readdir(directory, { withFileTypes: true }) + const files: Array = [] + + for (const entry of entries) { + const entryPath = path.join(directory, entry.name) + + if (entry.isDirectory()) { + if (!excludedDirectories.has(entryPath)) { + files.push( + ...(await findExecutableFiles(entryPath, excludedDirectories)), + ) + } + } else if ( + entry.isFile() && + EXECUTABLE_EXTENSIONS.has(path.extname(entry.name)) + ) { + files.push(entryPath) + } + } + + return files.sort() +} + +async function findSentinelMatches(files: Array) { + const matches: Array = [] + + for (const file of files) { + if ((await readFile(file, 'utf-8')).includes(SENTINEL)) { + matches.push(path.relative(distDir, file)) + } + } + + return matches +} + +test('server-only route dependencies stay out of the RSC build output', async ({ + request, +}) => { + test.skip( + (process.env.E2E_TOOLCHAIN ?? 'vite') !== 'vite', + 'Vite emits the RSC environment as a separate output directory', + ) + + const response = await request.get('/api/rsc-build-boundary') + expect(response.ok()).toBe(true) + expect(await response.text()).toBe(SENTINEL) + + const [ssrFiles, rscFiles] = await Promise.all([ + findExecutableFiles(serverDir, new Set([rscDir])), + findExecutableFiles(rscDir), + ]) + const [ssrMatches, rscMatches] = await Promise.all([ + findSentinelMatches(ssrFiles), + findSentinelMatches(rscFiles), + ]) + + expect( + ssrMatches, + `Expected the sentinel in the SSR output. Scanned files:\n${ssrFiles + .map((file) => path.relative(distDir, file)) + .join('\n')}`, + ).not.toEqual([]) + expect( + rscMatches, + `The server-only route dependency leaked into these RSC files:\n${rscMatches.join( + '\n', + )}`, + ).toEqual([]) +}) diff --git a/packages/react-start-rsc/eslint.config.js b/packages/react-start-rsc/eslint.config.js index 931f0ec774..daf1baa88a 100644 --- a/packages/react-start-rsc/eslint.config.js +++ b/packages/react-start-rsc/eslint.config.js @@ -22,6 +22,33 @@ export default [ 'react-hooks/rules-of-hooks': 'error', }, }, + { + name: 'react-start-rsc/import-boundaries', + files: ['src/**/*.{ts,tsx}'], + rules: { + 'no-restricted-imports': [ + 'error', + { + paths: [ + { + name: '@tanstack/start-server-core', + message: + 'Import from a dedicated @tanstack/start-server-core subpath to avoid pulling the full server barrel into the RSC module graph.', + }, + ], + }, + ], + 'no-restricted-syntax': [ + 'error', + { + selector: + "ImportExpression[source.value='@tanstack/start-server-core']", + message: + 'Dynamically import a dedicated @tanstack/start-server-core subpath instead of the root barrel.', + }, + ], + }, + }, { files: ['**/__tests__/**'], rules: { diff --git a/packages/react-start-rsc/package.json b/packages/react-start-rsc/package.json index ac3110104f..a5c77327bd 100644 --- a/packages/react-start-rsc/package.json +++ b/packages/react-start-rsc/package.json @@ -103,7 +103,6 @@ "@tanstack/start-client-core": "workspace:*", "@tanstack/start-fn-stubs": "workspace:*", "@tanstack/start-plugin-core": "workspace:*", - "@tanstack/start-server-core": "workspace:*", "@tanstack/start-storage-context": "workspace:*", "pathe": "^2.0.3" }, diff --git a/packages/react-start-rsc/src/createCompositeComponent.ts b/packages/react-start-rsc/src/createCompositeComponent.ts index c6a43b0f9d..02a840dc64 100644 --- a/packages/react-start-rsc/src/createCompositeComponent.ts +++ b/packages/react-start-rsc/src/createCompositeComponent.ts @@ -1,6 +1,5 @@ import { createElement } from 'react' import { renderToReadableStream } from 'virtual:tanstack-rsc-runtime' -import { getRequest } from '@tanstack/start-server-core' import { getStartContext } from '@tanstack/start-storage-context' import { sanitizeSlotArgs } from './slotUsageSanitizer' import { ReplayableStream } from './ReplayableStream' @@ -99,7 +98,7 @@ export async function createCompositeComponent( // SSR path: buffer stream for replay, pre-decode for synchronous rendering if (isRouterRequest && ssrHandler) { - const signal = getRequest().signal + const signal = ctx.request.signal const stream = new ReplayableStream(flightStream, { signal }) // Pre-decode during loader phase for synchronous SSR rendering diff --git a/packages/react-start-rsc/src/renderServerComponent.ts b/packages/react-start-rsc/src/renderServerComponent.ts index d282d63111..4ef6037821 100644 --- a/packages/react-start-rsc/src/renderServerComponent.ts +++ b/packages/react-start-rsc/src/renderServerComponent.ts @@ -1,5 +1,4 @@ import { renderToReadableStream } from 'virtual:tanstack-rsc-runtime' -import { getRequest } from '@tanstack/start-server-core' import { getStartContext } from '@tanstack/start-storage-context' import { ReplayableStream } from './ReplayableStream' import { RENDERABLE_RSC, SERVER_COMPONENT_STREAM } from './ServerComponentTypes' @@ -72,7 +71,7 @@ export async function renderServerComponent( // SSR path: buffer stream for replay, pre-decode for synchronous rendering if (isRouterRequest && ssrHandler) { - const signal = getRequest().signal + const signal = ctx.request.signal const stream = new ReplayableStream(flightStream, { signal }) // Pre-decode during loader phase for synchronous SSR rendering diff --git a/packages/react-start-rsc/tests/createServerComponent.test-d.tsx b/packages/react-start-rsc/tests/createServerComponent.test-d.tsx index 9a161e2345..320ef4f30a 100644 --- a/packages/react-start-rsc/tests/createServerComponent.test-d.tsx +++ b/packages/react-start-rsc/tests/createServerComponent.test-d.tsx @@ -1,21 +1,10 @@ -import { expectTypeOf, test, vi } from 'vitest' +import { expectTypeOf, test } from 'vitest' import type { CompositeComponentResult, ValidateCompositeComponent, } from '../src/ServerComponentTypes' import { CompositeComponent } from '../src/CompositeComponent' -vi.mock('@tanstack/start-server-core', () => { - return { - getRequest: () => undefined, - } -}) - -vi.mock('@tanstack/start-storage-context', () => { - return { - getStartContext: () => undefined, - } -}) import { JSX } from 'react' test('when a server component is created with no props', () => { diff --git a/packages/solid-start-server/src/defaultRenderHandler.tsx b/packages/solid-start-server/src/defaultRenderHandler.tsx index e3be93323b..66b3e27889 100644 --- a/packages/solid-start-server/src/defaultRenderHandler.tsx +++ b/packages/solid-start-server/src/defaultRenderHandler.tsx @@ -1,5 +1,7 @@ -import { defineHandlerCallback } from '@tanstack/start-server-core' -import { renderRouterToString } from '@tanstack/solid-router/ssr/server' +import { + defineHandlerCallback, + renderRouterToString, +} from '@tanstack/solid-router/ssr/server' import { StartServer } from './StartServer' export const defaultRenderHandler = defineHandlerCallback( diff --git a/packages/solid-start-server/src/defaultStreamHandler.tsx b/packages/solid-start-server/src/defaultStreamHandler.tsx index 4ee257a186..9575b801e0 100644 --- a/packages/solid-start-server/src/defaultStreamHandler.tsx +++ b/packages/solid-start-server/src/defaultStreamHandler.tsx @@ -1,5 +1,7 @@ -import { defineHandlerCallback } from '@tanstack/start-server-core' -import { renderRouterToStream } from '@tanstack/solid-router/ssr/server' +import { + defineHandlerCallback, + renderRouterToStream, +} from '@tanstack/solid-router/ssr/server' import { StartServer } from './StartServer' export const defaultStreamHandler = defineHandlerCallback( diff --git a/packages/start-plugin-core/src/post-build.ts b/packages/start-plugin-core/src/post-build.ts index 966cdd38cc..0fd2410d56 100644 --- a/packages/start-plugin-core/src/post-build.ts +++ b/packages/start-plugin-core/src/post-build.ts @@ -1,4 +1,4 @@ -import { HEADERS } from '@tanstack/start-server-core' +import { HEADERS } from '@tanstack/start-server-core/constants' import { buildSitemap } from './build-sitemap' import type { TanStackStartOutputConfig } from './schema' diff --git a/packages/start-plugin-core/src/rsbuild/virtual-modules.ts b/packages/start-plugin-core/src/rsbuild/virtual-modules.ts index 9e4c0bc4df..591625ce1c 100644 --- a/packages/start-plugin-core/src/rsbuild/virtual-modules.ts +++ b/packages/start-plugin-core/src/rsbuild/virtual-modules.ts @@ -1,4 +1,4 @@ -import { VIRTUAL_MODULES } from '@tanstack/start-server-core' +import { VIRTUAL_MODULES } from '@tanstack/start-server-core/virtual-modules' import { generateSerializationAdaptersModule } from '../serialization-adapters-module' import { generateServerFnResolverModule } from '../start-compiler/server-fn-resolver-module' import { buildStartManifest } from '../start-manifest-plugin/manifestBuilder' diff --git a/packages/start-plugin-core/src/vite/serialization-adapters-plugin.ts b/packages/start-plugin-core/src/vite/serialization-adapters-plugin.ts index 3cf12ad97c..26eb92c5ca 100644 --- a/packages/start-plugin-core/src/vite/serialization-adapters-plugin.ts +++ b/packages/start-plugin-core/src/vite/serialization-adapters-plugin.ts @@ -1,4 +1,4 @@ -import { VIRTUAL_MODULES } from '@tanstack/start-server-core' +import { VIRTUAL_MODULES } from '@tanstack/start-server-core/virtual-modules' import { generateSerializationAdaptersModule } from '../serialization-adapters-module' import { START_ENVIRONMENT_NAMES } from '../constants' import { createIdFilter } from '../utils' diff --git a/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts b/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts index 1cc02f3b91..6814740074 100644 --- a/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts +++ b/packages/start-plugin-core/src/vite/start-compiler-plugin/plugin.ts @@ -1,4 +1,4 @@ -import { VIRTUAL_MODULES } from '@tanstack/start-server-core' +import { VIRTUAL_MODULES } from '@tanstack/start-server-core/virtual-modules' import { resolve as resolvePath } from 'pathe' import { SERVER_FN_LOOKUP, diff --git a/packages/start-plugin-core/src/vite/start-manifest-plugin/plugin.ts b/packages/start-plugin-core/src/vite/start-manifest-plugin/plugin.ts index 9b9c274520..11a490388a 100644 --- a/packages/start-plugin-core/src/vite/start-manifest-plugin/plugin.ts +++ b/packages/start-plugin-core/src/vite/start-manifest-plugin/plugin.ts @@ -1,5 +1,5 @@ import { joinURL } from 'ufo' -import { VIRTUAL_MODULES } from '@tanstack/start-server-core' +import { VIRTUAL_MODULES } from '@tanstack/start-server-core/virtual-modules' import { rootRouteId } from '@tanstack/router-core' import { DEV_CLIENT_ENTRY, START_ENVIRONMENT_NAMES } from '../../constants' import { diff --git a/packages/start-plugin-core/tests/post-server-build.test.ts b/packages/start-plugin-core/tests/post-server-build.test.ts index 763f5e5d05..e290382d4d 100644 --- a/packages/start-plugin-core/tests/post-server-build.test.ts +++ b/packages/start-plugin-core/tests/post-server-build.test.ts @@ -1,6 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -vi.mock('@tanstack/start-server-core', () => ({ +vi.mock('@tanstack/start-server-core/constants', () => ({ HEADERS: { TSS_SHELL: 'x-tss-shell', }, diff --git a/packages/start-plugin-core/tests/rsbuild/post-build.test.ts b/packages/start-plugin-core/tests/rsbuild/post-build.test.ts index 9f302d5c8e..26443c7e7c 100644 --- a/packages/start-plugin-core/tests/rsbuild/post-build.test.ts +++ b/packages/start-plugin-core/tests/rsbuild/post-build.test.ts @@ -3,7 +3,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises' import { tmpdir } from 'node:os' import { join } from 'pathe' -vi.mock('@tanstack/start-server-core', () => ({ +vi.mock('@tanstack/start-server-core/constants', () => ({ HEADERS: { TSS_SHELL: 'x-tss-shell', }, diff --git a/packages/start-plugin-core/tests/start-manifest-plugin.test.ts b/packages/start-plugin-core/tests/start-manifest-plugin.test.ts index 68270fb6d7..8d671d1dbf 100644 --- a/packages/start-plugin-core/tests/start-manifest-plugin.test.ts +++ b/packages/start-plugin-core/tests/start-manifest-plugin.test.ts @@ -1,9 +1,9 @@ -import { VIRTUAL_MODULES } from '@tanstack/start-server-core' +import { VIRTUAL_MODULES } from '@tanstack/start-server-core/virtual-modules' import { describe, expect, test, vi } from 'vitest' import { DEV_CLIENT_ENTRY, START_ENVIRONMENT_NAMES } from '../src/constants' import { startManifestPlugin } from '../src/vite/start-manifest-plugin/plugin' -vi.mock('@tanstack/start-server-core', () => ({ +vi.mock('@tanstack/start-server-core/virtual-modules', () => ({ VIRTUAL_MODULES: { startManifest: 'tanstack-start-manifest:v', }, diff --git a/packages/start-server-core/package.json b/packages/start-server-core/package.json index 38ff82ce3c..a38803820d 100644 --- a/packages/start-server-core/package.json +++ b/packages/start-server-core/package.json @@ -65,6 +65,18 @@ "default": "./dist/esm/request-response.js" } }, + "./constants": { + "import": { + "types": "./dist/esm/constants.d.ts", + "default": "./dist/esm/constants.js" + } + }, + "./virtual-modules": { + "import": { + "types": "./dist/esm/virtual-modules.d.ts", + "default": "./dist/esm/virtual-modules.js" + } + }, "./package.json": "./package.json" }, "imports": { diff --git a/packages/start-server-core/vite.config.ts b/packages/start-server-core/vite.config.ts index dd252ddb08..a445c8fa1c 100644 --- a/packages/start-server-core/vite.config.ts +++ b/packages/start-server-core/vite.config.ts @@ -42,6 +42,8 @@ export default mergeConfig( './src/createServerRpc.ts', './src/createSsrRpc.ts', './src/request-response.ts', + './src/constants.ts', + './src/virtual-modules.ts', './src/fake-start-server-fn-resolver.ts', './src/empty-plugin-adapters.ts', ], diff --git a/packages/vue-start-server/src/defaultRenderHandler.tsx b/packages/vue-start-server/src/defaultRenderHandler.tsx index 69fa83d8ac..1e31e6e97e 100644 --- a/packages/vue-start-server/src/defaultRenderHandler.tsx +++ b/packages/vue-start-server/src/defaultRenderHandler.tsx @@ -1,5 +1,7 @@ -import { defineHandlerCallback } from '@tanstack/start-server-core' -import { renderRouterToString } from '@tanstack/vue-router/ssr/server' +import { + defineHandlerCallback, + renderRouterToString, +} from '@tanstack/vue-router/ssr/server' import { StartServer } from './StartServer' export const defaultRenderHandler = defineHandlerCallback( diff --git a/packages/vue-start-server/src/defaultStreamHandler.tsx b/packages/vue-start-server/src/defaultStreamHandler.tsx index 94106eee85..2eb8c09f82 100644 --- a/packages/vue-start-server/src/defaultStreamHandler.tsx +++ b/packages/vue-start-server/src/defaultStreamHandler.tsx @@ -1,5 +1,7 @@ -import { defineHandlerCallback } from '@tanstack/start-server-core' -import { renderRouterToStream } from '@tanstack/vue-router/ssr/server' +import { + defineHandlerCallback, + renderRouterToStream, +} from '@tanstack/vue-router/ssr/server' import { StartServer } from './StartServer' export const defaultStreamHandler = defineHandlerCallback( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 75be091d06..bbbc0e852c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -13480,9 +13480,6 @@ importers: '@tanstack/start-plugin-core': specifier: workspace:* version: link:../start-plugin-core - '@tanstack/start-server-core': - specifier: workspace:* - version: link:../start-server-core '@tanstack/start-storage-context': specifier: workspace:* version: link:../start-storage-context