@tanstack/start-plugin-core 1.164.1 → 1.166.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/esm/dev-server-plugin/plugin.d.ts +2 -1
- package/dist/esm/dev-server-plugin/plugin.js +38 -35
- package/dist/esm/dev-server-plugin/plugin.js.map +1 -1
- package/dist/esm/plugin.js +30 -4
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/schema.d.ts +40 -0
- package/dist/esm/schema.js +6 -0
- package/dist/esm/schema.js.map +1 -1
- package/package.json +4 -4
- package/src/dev-server-plugin/plugin.ts +49 -45
- package/src/plugin.ts +38 -4
- package/src/schema.ts +12 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { PluginOption } from 'vite';
|
|
2
2
|
import { GetConfigFn } from '../types.js';
|
|
3
|
-
export declare function devServerPlugin({ getConfig, }: {
|
|
3
|
+
export declare function devServerPlugin({ getConfig, devSsrStylesEnabled, }: {
|
|
4
4
|
getConfig: GetConfigFn;
|
|
5
|
+
devSsrStylesEnabled: boolean;
|
|
5
6
|
}): PluginOption;
|
|
@@ -6,7 +6,8 @@ import { resolveViteId } from "../utils.js";
|
|
|
6
6
|
import { extractHtmlScripts } from "./extract-html-scripts.js";
|
|
7
7
|
import { CSS_MODULES_REGEX, collectDevStyles, normalizeCssModuleCacheKey } from "./dev-styles.js";
|
|
8
8
|
function devServerPlugin({
|
|
9
|
-
getConfig
|
|
9
|
+
getConfig,
|
|
10
|
+
devSsrStylesEnabled
|
|
10
11
|
}) {
|
|
11
12
|
let isTest = false;
|
|
12
13
|
let injectedHeadScripts;
|
|
@@ -37,43 +38,45 @@ function devServerPlugin({
|
|
|
37
38
|
);
|
|
38
39
|
const scripts = extractHtmlScripts(transformedHtml);
|
|
39
40
|
injectedHeadScripts = scripts.flatMap((script) => script.content ?? []).join(";");
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
if (devSsrStylesEnabled) {
|
|
42
|
+
viteDevServer.middlewares.use(async (req, res, next) => {
|
|
43
|
+
const url = req.url ?? "";
|
|
44
|
+
const pathname = url.split("?")[0];
|
|
45
|
+
if (!pathname?.endsWith("/@tanstack-start/styles.css")) {
|
|
46
|
+
return next();
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
const urlObj = new URL(url, "http://localhost");
|
|
50
|
+
const routesParam = urlObj.searchParams.get("routes");
|
|
51
|
+
const routeIds = routesParam ? routesParam.split(",") : [];
|
|
52
|
+
const entries = [];
|
|
53
|
+
const routesManifest = globalThis.TSS_ROUTES_MANIFEST;
|
|
54
|
+
if (routesManifest && routeIds.length > 0) {
|
|
55
|
+
for (const routeId of routeIds) {
|
|
56
|
+
const route = routesManifest[routeId];
|
|
57
|
+
if (route?.filePath) {
|
|
58
|
+
entries.push(route.filePath);
|
|
59
|
+
}
|
|
57
60
|
}
|
|
58
61
|
}
|
|
62
|
+
const css = entries.length > 0 ? await collectDevStyles({
|
|
63
|
+
viteDevServer,
|
|
64
|
+
entries,
|
|
65
|
+
cssModulesCache
|
|
66
|
+
}) : void 0;
|
|
67
|
+
res.setHeader("Content-Type", "text/css");
|
|
68
|
+
res.setHeader("Cache-Control", "no-store");
|
|
69
|
+
res.end(css ?? "");
|
|
70
|
+
} catch (e) {
|
|
71
|
+
console.error("[tanstack-start] Error collecting dev styles:", e);
|
|
72
|
+
res.setHeader("Content-Type", "text/css");
|
|
73
|
+
res.setHeader("Cache-Control", "no-store");
|
|
74
|
+
res.end(
|
|
75
|
+
`/* Error collecting styles: ${e instanceof Error ? e.message : String(e)} */`
|
|
76
|
+
);
|
|
59
77
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
entries,
|
|
63
|
-
cssModulesCache
|
|
64
|
-
}) : void 0;
|
|
65
|
-
res.setHeader("Content-Type", "text/css");
|
|
66
|
-
res.setHeader("Cache-Control", "no-store");
|
|
67
|
-
res.end(css ?? "");
|
|
68
|
-
} catch (e) {
|
|
69
|
-
console.error("[tanstack-start] Error collecting dev styles:", e);
|
|
70
|
-
res.setHeader("Content-Type", "text/css");
|
|
71
|
-
res.setHeader("Cache-Control", "no-store");
|
|
72
|
-
res.end(
|
|
73
|
-
`/* Error collecting styles: ${e instanceof Error ? e.message : String(e)} */`
|
|
74
|
-
);
|
|
75
|
-
}
|
|
76
|
-
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
77
80
|
return () => {
|
|
78
81
|
const serverEnv = viteDevServer.environments[VITE_ENVIRONMENT_NAMES.server];
|
|
79
82
|
if (!serverEnv) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../../src/dev-server-plugin/plugin.ts"],"sourcesContent":["import { isRunnableDevEnvironment } from 'vite'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { NodeRequest, sendNodeResponse } from 'srvx/node'\nimport { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { resolveViteId } from '../utils'\nimport { extractHtmlScripts } from './extract-html-scripts'\nimport {\n CSS_MODULES_REGEX,\n collectDevStyles,\n normalizeCssModuleCacheKey,\n} from './dev-styles'\nimport type { Connect, DevEnvironment, PluginOption } from 'vite'\nimport type { GetConfigFn } from '../types'\n\nexport function devServerPlugin({\n getConfig,\n}: {\n getConfig: GetConfigFn\n}): PluginOption {\n let isTest = false\n\n let injectedHeadScripts: string | undefined\n\n // Cache CSS modules content during transform hook.\n // For CSS modules, the transform hook receives the raw CSS content before\n // Vite wraps it in JS. We capture this to use during SSR style collection.\n const cssModulesCache: Record<string, string> = {}\n\n return [\n {\n name: 'tanstack-start-core:dev-server',\n config(_userConfig, { mode }) {\n isTest = isTest ? isTest : mode === 'test'\n },\n // Capture CSS modules content during transform\n transform: {\n filter: {\n id: CSS_MODULES_REGEX,\n },\n handler(code, id) {\n cssModulesCache[normalizeCssModuleCacheKey(id)] = code\n },\n },\n async configureServer(viteDevServer) {\n if (isTest) {\n return\n }\n\n // Extract the scripts that Vite plugins would inject into the initial HTML\n const templateHtml = `<html><head></head><body></body></html>`\n const transformedHtml = await viteDevServer.transformIndexHtml(\n '/',\n templateHtml,\n )\n const scripts = extractHtmlScripts(transformedHtml)\n injectedHeadScripts = scripts\n .flatMap((script) => script.content ?? [])\n .join(';')\n\n // CSS middleware registered in PRE-PHASE (before Vite's internal middlewares)\n // This ensures it handles /@tanstack-start/styles.css before any catch-all middleware\n // from other plugins (like nitro) that may be registered in the post-phase.\n // This makes the CSS endpoint work regardless of plugin order in the Vite config.\n // We check pathname.endsWith() to handle basepaths (e.g., /my-app/@tanstack-start/styles.css)\n // since pre-phase runs before Vite's base middleware strips the basepath.\n viteDevServer.middlewares.use(async (req, res, next) => {\n const url = req.url ?? ''\n const pathname = url.split('?')[0]\n if (!pathname?.endsWith('/@tanstack-start/styles.css')) {\n return next()\n }\n\n try {\n // Parse route IDs from query param\n const urlObj = new URL(url, 'http://localhost')\n const routesParam = urlObj.searchParams.get('routes')\n const routeIds = routesParam ? routesParam.split(',') : []\n\n // Build entries list from route file paths\n const entries: Array<string> = []\n\n // Look up route file paths from manifest\n // Only routes registered in the manifest are used - this prevents path injection\n const routesManifest = (globalThis as any).TSS_ROUTES_MANIFEST as\n | Record<string, { filePath: string; children?: Array<string> }>\n | undefined\n\n if (routesManifest && routeIds.length > 0) {\n for (const routeId of routeIds) {\n const route = routesManifest[routeId]\n if (route?.filePath) {\n entries.push(route.filePath)\n }\n }\n }\n\n const css =\n entries.length > 0\n ? await collectDevStyles({\n viteDevServer,\n entries,\n cssModulesCache,\n })\n : undefined\n\n res.setHeader('Content-Type', 'text/css')\n res.setHeader('Cache-Control', 'no-store')\n res.end(css ?? '')\n } catch (e) {\n // Log error but still return valid CSS response to avoid MIME type issues\n console.error('[tanstack-start] Error collecting dev styles:', e)\n res.setHeader('Content-Type', 'text/css')\n res.setHeader('Cache-Control', 'no-store')\n res.end(\n `/* Error collecting styles: ${e instanceof Error ? e.message : String(e)} */`,\n )\n }\n })\n\n return () => {\n const serverEnv = viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ] as DevEnvironment | undefined\n\n if (!serverEnv) {\n throw new Error(\n `Server environment ${VITE_ENVIRONMENT_NAMES.server} not found`,\n )\n }\n\n const { startConfig } = getConfig()\n const installMiddleware = startConfig.vite?.installDevServerMiddleware\n if (installMiddleware === false) {\n return\n }\n if (installMiddleware == undefined) {\n // do not install middleware in middlewareMode by default\n if (viteDevServer.config.server.middlewareMode) {\n return\n }\n\n // do not install middleware if SSR env in case another plugin already did\n if (\n !isRunnableDevEnvironment(serverEnv) ||\n // do not check via `isFetchableDevEnvironment` since nitro does implement the `FetchableDevEnvironment` interface but not via inheritance (which this helper checks)\n 'dispatchFetch' in serverEnv\n ) {\n return\n }\n }\n\n if (!isRunnableDevEnvironment(serverEnv)) {\n throw new Error(\n 'cannot install vite dev server middleware for TanStack Start since the SSR environment is not a RunnableDevEnvironment',\n )\n }\n\n viteDevServer.middlewares.use(async (req, res) => {\n // fix the request URL to match the original URL\n // otherwise, the request URL will '/index.html'\n if (req.originalUrl) {\n req.url = req.originalUrl\n }\n const webReq = new NodeRequest({ req, res })\n\n try {\n // Import and resolve the request by running the server request entry point\n // this request entry point must implement the `fetch` API as follows:\n /**\n * export default {\n * fetch(req: Request): Promise<Response>\n * }\n */\n const serverEntry = await serverEnv.runner.import(\n ENTRY_POINTS.server,\n )\n const webRes = await serverEntry['default'].fetch(webReq)\n\n return sendNodeResponse(res, webRes)\n } catch (e) {\n console.error(e)\n try {\n viteDevServer.ssrFixStacktrace(e as Error)\n } catch {}\n\n if (\n webReq.headers.get('content-type')?.includes('application/json')\n ) {\n return sendNodeResponse(\n res,\n new Response(\n JSON.stringify(\n {\n status: 500,\n error: 'Internal Server Error',\n message:\n 'An unexpected error occurred. Please try again later.',\n timestamp: new Date().toISOString(),\n },\n null,\n 2,\n ),\n {\n status: 500,\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ),\n )\n }\n\n return sendNodeResponse(\n res,\n new Response(\n `\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>Error</title>\n <script type=\"module\">\n import { ErrorOverlay } from '/@vite/client'\n document.body.appendChild(new ErrorOverlay(${JSON.stringify(\n prepareError(req, e),\n ).replace(/</g, '\\\\u003c')}))\n </script>\n </head>\n <body>\n </body>\n </html>\n `,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n },\n ),\n )\n }\n })\n }\n },\n },\n {\n name: 'tanstack-start-core:dev-server:injected-head-scripts',\n sharedDuringBuild: true,\n applyToEnvironment: (env) => env.config.consumer === 'server',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.injectedHeadScripts) },\n handler(_id) {\n return resolveViteId(VIRTUAL_MODULES.injectedHeadScripts)\n },\n },\n load: {\n filter: {\n id: new RegExp(resolveViteId(VIRTUAL_MODULES.injectedHeadScripts)),\n },\n handler() {\n const mod = `\n export const injectedHeadScripts = ${JSON.stringify(injectedHeadScripts) || 'undefined'}`\n return mod\n },\n },\n },\n ]\n}\n\n/**\n * Formats error for SSR message in error overlay\n * @param req\n * @param error\n * @returns\n */\nfunction prepareError(req: Connect.IncomingMessage, error: unknown) {\n const e = error as Error\n return {\n message: `An error occurred while server rendering ${req.url}:\\n\\n\\t${\n typeof e === 'string' ? e : e.message\n } `,\n stack: typeof e === 'string' ? '' : e.stack,\n }\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../../src/dev-server-plugin/plugin.ts"],"sourcesContent":["import { isRunnableDevEnvironment } from 'vite'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { NodeRequest, sendNodeResponse } from 'srvx/node'\nimport { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { resolveViteId } from '../utils'\nimport { extractHtmlScripts } from './extract-html-scripts'\nimport {\n CSS_MODULES_REGEX,\n collectDevStyles,\n normalizeCssModuleCacheKey,\n} from './dev-styles'\nimport type { Connect, DevEnvironment, PluginOption } from 'vite'\nimport type { GetConfigFn } from '../types'\n\nexport function devServerPlugin({\n getConfig,\n devSsrStylesEnabled,\n}: {\n getConfig: GetConfigFn\n devSsrStylesEnabled: boolean\n}): PluginOption {\n let isTest = false\n\n let injectedHeadScripts: string | undefined\n\n // Cache CSS modules content during transform hook.\n // For CSS modules, the transform hook receives the raw CSS content before\n // Vite wraps it in JS. We capture this to use during SSR style collection.\n const cssModulesCache: Record<string, string> = {}\n\n return [\n {\n name: 'tanstack-start-core:dev-server',\n config(_userConfig, { mode }) {\n isTest = isTest ? isTest : mode === 'test'\n },\n // Capture CSS modules content during transform\n transform: {\n filter: {\n id: CSS_MODULES_REGEX,\n },\n handler(code, id) {\n cssModulesCache[normalizeCssModuleCacheKey(id)] = code\n },\n },\n async configureServer(viteDevServer) {\n if (isTest) {\n return\n }\n\n // Extract the scripts that Vite plugins would inject into the initial HTML\n const templateHtml = `<html><head></head><body></body></html>`\n const transformedHtml = await viteDevServer.transformIndexHtml(\n '/',\n templateHtml,\n )\n const scripts = extractHtmlScripts(transformedHtml)\n injectedHeadScripts = scripts\n .flatMap((script) => script.content ?? [])\n .join(';')\n\n // CSS middleware registered in PRE-PHASE (before Vite's internal middlewares)\n // This ensures it handles /@tanstack-start/styles.css before any catch-all middleware\n // from other plugins (like nitro) that may be registered in the post-phase.\n // This makes the CSS endpoint work regardless of plugin order in the Vite config.\n // We check pathname.endsWith() to handle basepaths (e.g., /my-app/@tanstack-start/styles.css)\n // since pre-phase runs before Vite's base middleware strips the basepath.\n if (devSsrStylesEnabled) {\n viteDevServer.middlewares.use(async (req, res, next) => {\n const url = req.url ?? ''\n const pathname = url.split('?')[0]\n if (!pathname?.endsWith('/@tanstack-start/styles.css')) {\n return next()\n }\n\n try {\n // Parse route IDs from query param\n const urlObj = new URL(url, 'http://localhost')\n const routesParam = urlObj.searchParams.get('routes')\n const routeIds = routesParam ? routesParam.split(',') : []\n\n // Build entries list from route file paths\n const entries: Array<string> = []\n\n // Look up route file paths from manifest\n // Only routes registered in the manifest are used - this prevents path injection\n const routesManifest = (globalThis as any).TSS_ROUTES_MANIFEST as\n | Record<string, { filePath: string; children?: Array<string> }>\n | undefined\n\n if (routesManifest && routeIds.length > 0) {\n for (const routeId of routeIds) {\n const route = routesManifest[routeId]\n if (route?.filePath) {\n entries.push(route.filePath)\n }\n }\n }\n\n const css =\n entries.length > 0\n ? await collectDevStyles({\n viteDevServer,\n entries,\n cssModulesCache,\n })\n : undefined\n\n res.setHeader('Content-Type', 'text/css')\n res.setHeader('Cache-Control', 'no-store')\n res.end(css ?? '')\n } catch (e) {\n // Log error but still return valid CSS response to avoid MIME type issues\n console.error('[tanstack-start] Error collecting dev styles:', e)\n res.setHeader('Content-Type', 'text/css')\n res.setHeader('Cache-Control', 'no-store')\n res.end(\n `/* Error collecting styles: ${e instanceof Error ? e.message : String(e)} */`,\n )\n }\n })\n }\n\n return () => {\n const serverEnv = viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ] as DevEnvironment | undefined\n\n if (!serverEnv) {\n throw new Error(\n `Server environment ${VITE_ENVIRONMENT_NAMES.server} not found`,\n )\n }\n\n const { startConfig } = getConfig()\n const installMiddleware = startConfig.vite?.installDevServerMiddleware\n if (installMiddleware === false) {\n return\n }\n if (installMiddleware == undefined) {\n // do not install middleware in middlewareMode by default\n if (viteDevServer.config.server.middlewareMode) {\n return\n }\n\n // do not install middleware if SSR env in case another plugin already did\n if (\n !isRunnableDevEnvironment(serverEnv) ||\n // do not check via `isFetchableDevEnvironment` since nitro does implement the `FetchableDevEnvironment` interface but not via inheritance (which this helper checks)\n 'dispatchFetch' in serverEnv\n ) {\n return\n }\n }\n\n if (!isRunnableDevEnvironment(serverEnv)) {\n throw new Error(\n 'cannot install vite dev server middleware for TanStack Start since the SSR environment is not a RunnableDevEnvironment',\n )\n }\n\n viteDevServer.middlewares.use(async (req, res) => {\n // fix the request URL to match the original URL\n // otherwise, the request URL will '/index.html'\n if (req.originalUrl) {\n req.url = req.originalUrl\n }\n const webReq = new NodeRequest({ req, res })\n\n try {\n // Import and resolve the request by running the server request entry point\n // this request entry point must implement the `fetch` API as follows:\n /**\n * export default {\n * fetch(req: Request): Promise<Response>\n * }\n */\n const serverEntry = await serverEnv.runner.import(\n ENTRY_POINTS.server,\n )\n const webRes = await serverEntry['default'].fetch(webReq)\n\n return sendNodeResponse(res, webRes)\n } catch (e) {\n console.error(e)\n try {\n viteDevServer.ssrFixStacktrace(e as Error)\n } catch {}\n\n if (\n webReq.headers.get('content-type')?.includes('application/json')\n ) {\n return sendNodeResponse(\n res,\n new Response(\n JSON.stringify(\n {\n status: 500,\n error: 'Internal Server Error',\n message:\n 'An unexpected error occurred. Please try again later.',\n timestamp: new Date().toISOString(),\n },\n null,\n 2,\n ),\n {\n status: 500,\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ),\n )\n }\n\n return sendNodeResponse(\n res,\n new Response(\n `\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>Error</title>\n <script type=\"module\">\n import { ErrorOverlay } from '/@vite/client'\n document.body.appendChild(new ErrorOverlay(${JSON.stringify(\n prepareError(req, e),\n ).replace(/</g, '\\\\u003c')}))\n </script>\n </head>\n <body>\n </body>\n </html>\n `,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n },\n ),\n )\n }\n })\n }\n },\n },\n {\n name: 'tanstack-start-core:dev-server:injected-head-scripts',\n sharedDuringBuild: true,\n applyToEnvironment: (env) => env.config.consumer === 'server',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.injectedHeadScripts) },\n handler(_id) {\n return resolveViteId(VIRTUAL_MODULES.injectedHeadScripts)\n },\n },\n load: {\n filter: {\n id: new RegExp(resolveViteId(VIRTUAL_MODULES.injectedHeadScripts)),\n },\n handler() {\n const mod = `\n export const injectedHeadScripts = ${JSON.stringify(injectedHeadScripts) || 'undefined'}`\n return mod\n },\n },\n },\n ]\n}\n\n/**\n * Formats error for SSR message in error overlay\n * @param req\n * @param error\n * @returns\n */\nfunction prepareError(req: Connect.IncomingMessage, error: unknown) {\n const e = error as Error\n return {\n message: `An error occurred while server rendering ${req.url}:\\n\\n\\t${\n typeof e === 'string' ? e : e.message\n } `,\n stack: typeof e === 'string' ? '' : e.stack,\n }\n}\n"],"names":[],"mappings":"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"}
|
package/dist/esm/plugin.js
CHANGED
|
@@ -48,6 +48,7 @@ function TanStackStartVitePluginCore(corePluginOpts, startPluginOpts) {
|
|
|
48
48
|
}
|
|
49
49
|
return { startConfig, resolvedStartConfig, corePluginOpts };
|
|
50
50
|
};
|
|
51
|
+
let needsDevBaseRewrite = false;
|
|
51
52
|
const capturedBundle = {};
|
|
52
53
|
function getBundle(envName) {
|
|
53
54
|
const bundle = capturedBundle[envName];
|
|
@@ -93,9 +94,7 @@ function TanStackStartVitePluginCore(corePluginOpts, startPluginOpts) {
|
|
|
93
94
|
if (!joinPaths(["/", startConfig2.router.basepath, "/"]).startsWith(
|
|
94
95
|
joinPaths(["/", resolvedStartConfig.viteAppBase, "/"])
|
|
95
96
|
)) {
|
|
96
|
-
|
|
97
|
-
"[tanstack-start]: During `vite dev`, `router.basepath` must start with the vite `base` config value"
|
|
98
|
-
);
|
|
97
|
+
needsDevBaseRewrite = true;
|
|
99
98
|
}
|
|
100
99
|
}
|
|
101
100
|
}
|
|
@@ -238,6 +237,9 @@ function TanStackStartVitePluginCore(corePluginOpts, startPluginOpts) {
|
|
|
238
237
|
...defineReplaceEnv("TSS_ROUTER_BASEPATH", startConfig2.router.basepath),
|
|
239
238
|
...command === "serve" ? defineReplaceEnv("TSS_SHELL", startConfig2.spa?.enabled ? "true" : "false") : {},
|
|
240
239
|
...defineReplaceEnv("TSS_DEV_SERVER", command === "serve" ? "true" : "false"),
|
|
240
|
+
// Dev SSR styles: enabled flag and basepath (defaults to vite base for asset URL alignment)
|
|
241
|
+
...defineReplaceEnv("TSS_DEV_SSR_STYLES_ENABLED", startConfig2.dev.ssrStyles.enabled ? "true" : "false"),
|
|
242
|
+
...defineReplaceEnv("TSS_DEV_SSR_STYLES_BASEPATH", startConfig2.dev.ssrStyles.basepath ?? resolvedStartConfig.viteAppBase),
|
|
241
243
|
// Replace NODE_ENV during build (unless opted out) for dead code elimination in server bundles
|
|
242
244
|
...command === "build" && startConfig2.server.build.staticNodeEnv ? {
|
|
243
245
|
"process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV || viteConfig.mode || "production")
|
|
@@ -315,7 +317,31 @@ function TanStackStartVitePluginCore(corePluginOpts, startPluginOpts) {
|
|
|
315
317
|
getClientBundle: () => getBundle(VITE_ENVIRONMENT_NAMES.client),
|
|
316
318
|
getConfig
|
|
317
319
|
}),
|
|
318
|
-
|
|
320
|
+
// When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),
|
|
321
|
+
// install a middleware that rewrites incoming request URLs to prepend the vite base prefix.
|
|
322
|
+
// This allows Vite's internal base middleware to accept the requests, then strips the prefix
|
|
323
|
+
// before passing to the SSR handler.
|
|
324
|
+
// Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,
|
|
325
|
+
// ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.
|
|
326
|
+
{
|
|
327
|
+
name: "tanstack-start-core:dev-base-rewrite",
|
|
328
|
+
configureServer(server) {
|
|
329
|
+
if (!needsDevBaseRewrite) {
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
332
|
+
const basePrefix = resolvedStartConfig.viteAppBase.replace(/\/$/, "");
|
|
333
|
+
server.middlewares.use((req, _res, next) => {
|
|
334
|
+
if (req.url && !req.url.startsWith(basePrefix)) {
|
|
335
|
+
req.url = basePrefix + req.url;
|
|
336
|
+
}
|
|
337
|
+
next();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
devServerPlugin({
|
|
342
|
+
getConfig,
|
|
343
|
+
devSsrStylesEnabled: startPluginOpts?.dev?.ssrStyles?.enabled ?? true
|
|
344
|
+
}),
|
|
319
345
|
previewServerPlugin(),
|
|
320
346
|
{
|
|
321
347
|
name: "tanstack-start:core:capture-bundle",
|
package/dist/esm/plugin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { joinPaths } from '@tanstack/router-core'\nimport * as vite from 'vite'\nimport { crawlFrameworkPkgs } from 'vitefu'\nimport { join } from 'pathe'\nimport { escapePath } from 'tinyglobby'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from './constants'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { previewServerPlugin } from './preview-server-plugin/plugin'\nimport { parseStartConfig } from './schema'\nimport { resolveEntry } from './resolve-entries'\nimport {\n getClientOutputDirectory,\n getServerOutputDirectory,\n} from './output-directory'\nimport { postServerBuild } from './post-server-build'\nimport { startCompilerPlugin } from './start-compiler-plugin/plugin'\nimport { importProtectionPlugin } from './import-protection-plugin/plugin'\nimport type {\n GetConfigFn,\n ResolvedStartConfig,\n TanStackStartVitePluginCoreOptions,\n} from './types'\nimport type { ViteEnvironmentNames } from './constants'\nimport type {\n TanStackStartInputConfig,\n TanStackStartOutputConfig,\n} from './schema'\nimport type { PluginOption } from 'vite'\n\nfunction isFullUrl(str: string): boolean {\n try {\n new URL(str)\n return true\n } catch {\n return false\n }\n}\n\nexport function TanStackStartVitePluginCore(\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n startPluginOpts: TanStackStartInputConfig,\n): Array<PluginOption> {\n // Determine the provider environment for server functions\n // If providerEnv is set, use that; otherwise default to SSR as the provider\n const serverFnProviderEnv =\n corePluginOpts.serverFn?.providerEnv || VITE_ENVIRONMENT_NAMES.server\n const ssrIsProvider = serverFnProviderEnv === VITE_ENVIRONMENT_NAMES.server\n\n const resolvedStartConfig: ResolvedStartConfig = {\n root: '',\n startFilePath: undefined,\n routerFilePath: '',\n srcDirectory: '',\n viteAppBase: '',\n serverFnProviderEnv,\n }\n\n let startConfig: TanStackStartOutputConfig | null\n const getConfig: GetConfigFn = () => {\n if (!resolvedStartConfig.root) {\n throw new Error(`Cannot get config before root is resolved`)\n }\n if (!startConfig) {\n startConfig = parseStartConfig(\n startPluginOpts,\n corePluginOpts,\n resolvedStartConfig.root,\n )\n }\n return { startConfig, resolvedStartConfig, corePluginOpts }\n }\n\n const capturedBundle: Partial<\n Record<ViteEnvironmentNames, vite.Rollup.OutputBundle>\n > = {}\n\n function getBundle(envName: ViteEnvironmentNames): vite.Rollup.OutputBundle {\n const bundle = capturedBundle[envName]\n if (!bundle) {\n throw new Error(`No bundle captured for environment: ${envName}`)\n }\n return bundle\n }\n\n const environments: Array<{ name: string; type: 'client' | 'server' }> = [\n { name: VITE_ENVIRONMENT_NAMES.client, type: 'client' },\n { name: VITE_ENVIRONMENT_NAMES.server, type: 'server' },\n ]\n if (\n corePluginOpts.serverFn?.providerEnv &&\n !environments.find((e) => e.name === corePluginOpts.serverFn?.providerEnv)\n ) {\n environments.push({\n name: corePluginOpts.serverFn.providerEnv,\n type: 'server',\n })\n }\n return [\n {\n name: 'tanstack-start-core:config',\n enforce: 'pre',\n async config(viteConfig, { command }) {\n resolvedStartConfig.viteAppBase = viteConfig.base ?? '/'\n if (!isFullUrl(resolvedStartConfig.viteAppBase)) {\n resolvedStartConfig.viteAppBase = joinPaths([\n '/',\n viteConfig.base,\n '/',\n ])\n }\n const root = viteConfig.root || process.cwd()\n resolvedStartConfig.root = root\n\n const { startConfig } = getConfig()\n if (startConfig.router.basepath === undefined) {\n if (!isFullUrl(resolvedStartConfig.viteAppBase)) {\n startConfig.router.basepath =\n resolvedStartConfig.viteAppBase.replace(/^\\/|\\/$/g, '')\n } else {\n startConfig.router.basepath = '/'\n }\n } else {\n if (command === 'serve' && !viteConfig.server?.middlewareMode) {\n // when serving, we must ensure that router basepath and viteAppBase are aligned\n if (\n !joinPaths(['/', startConfig.router.basepath, '/']).startsWith(\n joinPaths(['/', resolvedStartConfig.viteAppBase, '/']),\n )\n ) {\n this.error(\n '[tanstack-start]: During `vite dev`, `router.basepath` must start with the vite `base` config value',\n )\n }\n }\n }\n\n const TSS_SERVER_FN_BASE = joinPaths([\n '/',\n startConfig.router.basepath,\n startConfig.serverFns.base,\n '/',\n ])\n const resolvedSrcDirectory = join(root, startConfig.srcDirectory)\n resolvedStartConfig.srcDirectory = resolvedSrcDirectory\n\n const startFilePath = resolveEntry({\n type: 'start entry',\n configuredEntry: startConfig.start.entry,\n defaultEntry: 'start',\n resolvedSrcDirectory,\n required: false,\n })\n resolvedStartConfig.startFilePath = startFilePath\n\n const routerFilePath = resolveEntry({\n type: 'router entry',\n configuredEntry: startConfig.router.entry,\n defaultEntry: 'router',\n resolvedSrcDirectory,\n required: true,\n })\n resolvedStartConfig.routerFilePath = routerFilePath\n\n const clientEntryPath = resolveEntry({\n type: 'client entry',\n configuredEntry: startConfig.client.entry,\n defaultEntry: 'client',\n resolvedSrcDirectory,\n required: false,\n })\n\n const serverEntryPath = resolveEntry({\n type: 'server entry',\n configuredEntry: startConfig.server.entry,\n defaultEntry: 'server',\n resolvedSrcDirectory,\n required: false,\n })\n\n const clientAlias = vite.normalizePath(\n clientEntryPath ?? corePluginOpts.defaultEntryPaths.client,\n )\n const serverAlias = vite.normalizePath(\n serverEntryPath ?? corePluginOpts.defaultEntryPaths.server,\n )\n const startAlias = vite.normalizePath(\n startFilePath ?? corePluginOpts.defaultEntryPaths.start,\n )\n const routerAlias = vite.normalizePath(routerFilePath)\n\n const entryAliasConfiguration: Record<\n (typeof ENTRY_POINTS)[keyof typeof ENTRY_POINTS],\n string\n > = {\n [ENTRY_POINTS.client]: clientAlias,\n [ENTRY_POINTS.server]: serverAlias,\n [ENTRY_POINTS.start]: startAlias,\n [ENTRY_POINTS.router]: routerAlias,\n }\n\n const startPackageName =\n `@tanstack/${corePluginOpts.framework}-start` as const\n\n // crawl packages that have start in \"peerDependencies\"\n // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101\n\n // this is currently uncached; could be implemented similarly as vite handles lock file changes\n // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282\n\n const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({\n root: process.cwd(),\n isBuild: command === 'build',\n isFrameworkPkgByJson(pkgJson) {\n const peerDependencies = pkgJson['peerDependencies']\n\n if (peerDependencies) {\n if (\n startPackageName in peerDependencies ||\n '@tanstack/start-client-core' in peerDependencies\n ) {\n return true\n }\n }\n\n return false\n },\n })\n\n return {\n // see https://vite.dev/config/shared-options.html#apptype\n // this will prevent vite from injecting middlewares that we don't want\n appType: viteConfig.appType ?? 'custom',\n environments: {\n [VITE_ENVIRONMENT_NAMES.client]: {\n consumer: 'client',\n build: {\n rollupOptions: {\n input: {\n main: ENTRY_POINTS.client,\n },\n },\n outDir: getClientOutputDirectory(viteConfig),\n },\n optimizeDeps: {\n exclude: crawlFrameworkPkgsResult.optimizeDeps.exclude,\n // Ensure user code can be crawled for dependencies\n entries: [clientAlias, routerAlias].map((entry) =>\n // Entries are treated as `tinyglobby` patterns so need to be escaped\n escapePath(entry),\n ),\n },\n },\n [VITE_ENVIRONMENT_NAMES.server]: {\n consumer: 'server',\n build: {\n ssr: true,\n rollupOptions: {\n input:\n viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]\n ?.build?.rollupOptions?.input ?? serverAlias,\n },\n outDir: getServerOutputDirectory(viteConfig),\n commonjsOptions: {\n include: [/node_modules/],\n },\n copyPublicDir:\n viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]\n ?.build?.copyPublicDir ?? false,\n },\n optimizeDeps: {\n // Ensure user code can be crawled for dependencies\n entries: [serverAlias, startAlias, routerAlias].map((entry) =>\n // Entries are treated as `tinyglobby` patterns so need to be escaped\n escapePath(entry),\n ),\n },\n },\n },\n\n resolve: {\n noExternal: [\n // ENTRY_POINTS.start,\n '@tanstack/start**',\n `@tanstack/${corePluginOpts.framework}-start**`,\n ...crawlFrameworkPkgsResult.ssr.noExternal.sort(),\n ],\n alias: {\n ...entryAliasConfiguration,\n },\n },\n /* prettier-ignore */\n define: {\n // define is an esbuild function that replaces the any instances of given keys with the given values\n // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify(\"TanStack Start\")\n // This is not the same as injecting environment variables.\n\n ...defineReplaceEnv('TSS_SERVER_FN_BASE', TSS_SERVER_FN_BASE),\n ...defineReplaceEnv('TSS_CLIENT_OUTPUT_DIR', getClientOutputDirectory(viteConfig)),\n ...defineReplaceEnv('TSS_ROUTER_BASEPATH', startConfig.router.basepath),\n ...(command === 'serve' ? defineReplaceEnv('TSS_SHELL', startConfig.spa?.enabled ? 'true' : 'false') : {}),\n ...defineReplaceEnv('TSS_DEV_SERVER', command === 'serve' ? 'true' : 'false'),\n // Replace NODE_ENV during build (unless opted out) for dead code elimination in server bundles\n ...(command === 'build' && startConfig.server.build.staticNodeEnv ? {\n 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || viteConfig.mode || 'production'),\n } : {}),\n },\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const client = builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const server = builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!client) {\n throw new Error('Client environment not found')\n }\n\n if (!server) {\n throw new Error('SSR environment not found')\n }\n\n if (!client.isBuilt) {\n // Build the client bundle first\n await builder.build(client)\n }\n if (!server.isBuilt) {\n // Build the SSR bundle\n await builder.build(server)\n }\n\n // If a custom provider environment is configured (not SSR),\n // build it last so the manifest includes functions from all environments\n if (!ssrIsProvider) {\n const providerEnv = builder.environments[serverFnProviderEnv]\n if (!providerEnv) {\n throw new Error(\n `Provider environment \"${serverFnProviderEnv}\" not found`,\n )\n }\n if (!providerEnv.isBuilt) {\n // Build the provider environment last\n // This ensures all server functions are discovered from client/ssr builds\n await builder.build(providerEnv)\n }\n }\n },\n },\n }\n },\n },\n // Separate plugin for buildApp hook with enforce: 'post'\n // This ensures proper ordering with other plugins that also have\n // buildApp hooks with order: 'post'. The enforce: 'post' ensures this\n // runs after other plugins (like Nitro) complete their builds.\n {\n name: 'tanstack-start-core:post-build',\n enforce: 'post',\n buildApp: {\n order: 'post',\n async handler(builder) {\n const { startConfig } = getConfig()\n await postServerBuild({ builder, startConfig })\n },\n },\n },\n // Server function plugin handles:\n // 1. Identifying createServerFn().handler() calls\n // 2. Extracting server functions to separate modules\n // 3. Replacing call sites with RPC stubs\n // 4. Generating the server function manifest\n // Also handles createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, createMiddleware\n startCompilerPlugin({\n framework: corePluginOpts.framework,\n environments,\n generateFunctionId: startPluginOpts?.serverFns?.generateFunctionId,\n providerEnvName: serverFnProviderEnv,\n }),\n importProtectionPlugin({\n getConfig,\n framework: corePluginOpts.framework,\n environments,\n providerEnvName: serverFnProviderEnv,\n }),\n tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts),\n loadEnvPlugin(),\n startManifestPlugin({\n getClientBundle: () => getBundle(VITE_ENVIRONMENT_NAMES.client),\n getConfig,\n }),\n devServerPlugin({ getConfig }),\n previewServerPlugin(),\n {\n name: 'tanstack-start:core:capture-bundle',\n applyToEnvironment(e) {\n return (\n e.name === VITE_ENVIRONMENT_NAMES.client ||\n e.name === VITE_ENVIRONMENT_NAMES.server\n )\n },\n enforce: 'post',\n generateBundle(_options, bundle) {\n const environment = this.environment.name as ViteEnvironmentNames\n if (!Object.values(VITE_ENVIRONMENT_NAMES).includes(environment)) {\n throw new Error(`Unknown environment: ${environment}`)\n }\n capturedBundle[environment] = bundle\n },\n },\n ]\n}\n\nfunction defineReplaceEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n"],"names":["startConfig"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import { joinPaths } from '@tanstack/router-core'\nimport * as vite from 'vite'\nimport { crawlFrameworkPkgs } from 'vitefu'\nimport { join } from 'pathe'\nimport { escapePath } from 'tinyglobby'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from './constants'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { previewServerPlugin } from './preview-server-plugin/plugin'\nimport { parseStartConfig } from './schema'\nimport { resolveEntry } from './resolve-entries'\nimport {\n getClientOutputDirectory,\n getServerOutputDirectory,\n} from './output-directory'\nimport { postServerBuild } from './post-server-build'\nimport { startCompilerPlugin } from './start-compiler-plugin/plugin'\nimport { importProtectionPlugin } from './import-protection-plugin/plugin'\nimport type {\n GetConfigFn,\n ResolvedStartConfig,\n TanStackStartVitePluginCoreOptions,\n} from './types'\nimport type { ViteEnvironmentNames } from './constants'\nimport type {\n TanStackStartInputConfig,\n TanStackStartOutputConfig,\n} from './schema'\nimport type { PluginOption } from 'vite'\n\nfunction isFullUrl(str: string): boolean {\n try {\n new URL(str)\n return true\n } catch {\n return false\n }\n}\n\nexport function TanStackStartVitePluginCore(\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n startPluginOpts: TanStackStartInputConfig,\n): Array<PluginOption> {\n // Determine the provider environment for server functions\n // If providerEnv is set, use that; otherwise default to SSR as the provider\n const serverFnProviderEnv =\n corePluginOpts.serverFn?.providerEnv || VITE_ENVIRONMENT_NAMES.server\n const ssrIsProvider = serverFnProviderEnv === VITE_ENVIRONMENT_NAMES.server\n\n const resolvedStartConfig: ResolvedStartConfig = {\n root: '',\n startFilePath: undefined,\n routerFilePath: '',\n srcDirectory: '',\n viteAppBase: '',\n serverFnProviderEnv,\n }\n\n let startConfig: TanStackStartOutputConfig | null\n const getConfig: GetConfigFn = () => {\n if (!resolvedStartConfig.root) {\n throw new Error(`Cannot get config before root is resolved`)\n }\n if (!startConfig) {\n startConfig = parseStartConfig(\n startPluginOpts,\n corePluginOpts,\n resolvedStartConfig.root,\n )\n }\n return { startConfig, resolvedStartConfig, corePluginOpts }\n }\n\n // When the router basepath and vite base are misaligned during dev,\n // we install a URL rewrite middleware instead of erroring.\n let needsDevBaseRewrite = false\n\n const capturedBundle: Partial<\n Record<ViteEnvironmentNames, vite.Rollup.OutputBundle>\n > = {}\n\n function getBundle(envName: ViteEnvironmentNames): vite.Rollup.OutputBundle {\n const bundle = capturedBundle[envName]\n if (!bundle) {\n throw new Error(`No bundle captured for environment: ${envName}`)\n }\n return bundle\n }\n\n const environments: Array<{ name: string; type: 'client' | 'server' }> = [\n { name: VITE_ENVIRONMENT_NAMES.client, type: 'client' },\n { name: VITE_ENVIRONMENT_NAMES.server, type: 'server' },\n ]\n if (\n corePluginOpts.serverFn?.providerEnv &&\n !environments.find((e) => e.name === corePluginOpts.serverFn?.providerEnv)\n ) {\n environments.push({\n name: corePluginOpts.serverFn.providerEnv,\n type: 'server',\n })\n }\n return [\n {\n name: 'tanstack-start-core:config',\n enforce: 'pre',\n async config(viteConfig, { command }) {\n resolvedStartConfig.viteAppBase = viteConfig.base ?? '/'\n if (!isFullUrl(resolvedStartConfig.viteAppBase)) {\n resolvedStartConfig.viteAppBase = joinPaths([\n '/',\n viteConfig.base,\n '/',\n ])\n }\n const root = viteConfig.root || process.cwd()\n resolvedStartConfig.root = root\n\n const { startConfig } = getConfig()\n if (startConfig.router.basepath === undefined) {\n if (!isFullUrl(resolvedStartConfig.viteAppBase)) {\n startConfig.router.basepath =\n resolvedStartConfig.viteAppBase.replace(/^\\/|\\/$/g, '')\n } else {\n startConfig.router.basepath = '/'\n }\n } else {\n if (command === 'serve' && !viteConfig.server?.middlewareMode) {\n // when serving, we must ensure that router basepath and viteAppBase are aligned\n if (\n !joinPaths(['/', startConfig.router.basepath, '/']).startsWith(\n joinPaths(['/', resolvedStartConfig.viteAppBase, '/']),\n )\n ) {\n // The router basepath and vite base are misaligned.\n // Instead of erroring, we install a dev-server middleware that\n // rewrites incoming request URLs to prepend the vite base prefix.\n // This allows users to have e.g. base: '/_ui/' for asset URLs\n // while keeping router basepath at '/' for page navigation.\n needsDevBaseRewrite = true\n }\n }\n }\n\n const TSS_SERVER_FN_BASE = joinPaths([\n '/',\n startConfig.router.basepath,\n startConfig.serverFns.base,\n '/',\n ])\n const resolvedSrcDirectory = join(root, startConfig.srcDirectory)\n resolvedStartConfig.srcDirectory = resolvedSrcDirectory\n\n const startFilePath = resolveEntry({\n type: 'start entry',\n configuredEntry: startConfig.start.entry,\n defaultEntry: 'start',\n resolvedSrcDirectory,\n required: false,\n })\n resolvedStartConfig.startFilePath = startFilePath\n\n const routerFilePath = resolveEntry({\n type: 'router entry',\n configuredEntry: startConfig.router.entry,\n defaultEntry: 'router',\n resolvedSrcDirectory,\n required: true,\n })\n resolvedStartConfig.routerFilePath = routerFilePath\n\n const clientEntryPath = resolveEntry({\n type: 'client entry',\n configuredEntry: startConfig.client.entry,\n defaultEntry: 'client',\n resolvedSrcDirectory,\n required: false,\n })\n\n const serverEntryPath = resolveEntry({\n type: 'server entry',\n configuredEntry: startConfig.server.entry,\n defaultEntry: 'server',\n resolvedSrcDirectory,\n required: false,\n })\n\n const clientAlias = vite.normalizePath(\n clientEntryPath ?? corePluginOpts.defaultEntryPaths.client,\n )\n const serverAlias = vite.normalizePath(\n serverEntryPath ?? corePluginOpts.defaultEntryPaths.server,\n )\n const startAlias = vite.normalizePath(\n startFilePath ?? corePluginOpts.defaultEntryPaths.start,\n )\n const routerAlias = vite.normalizePath(routerFilePath)\n\n const entryAliasConfiguration: Record<\n (typeof ENTRY_POINTS)[keyof typeof ENTRY_POINTS],\n string\n > = {\n [ENTRY_POINTS.client]: clientAlias,\n [ENTRY_POINTS.server]: serverAlias,\n [ENTRY_POINTS.start]: startAlias,\n [ENTRY_POINTS.router]: routerAlias,\n }\n\n const startPackageName =\n `@tanstack/${corePluginOpts.framework}-start` as const\n\n // crawl packages that have start in \"peerDependencies\"\n // see https://github.com/svitejs/vitefu/blob/d8d82fa121e3b2215ba437107093c77bde51b63b/src/index.js#L95-L101\n\n // this is currently uncached; could be implemented similarly as vite handles lock file changes\n // see https://github.com/vitejs/vite/blob/557f797d29422027e8c451ca50dd84bf8c41b5f0/packages/vite/src/node/optimizer/index.ts#L1282\n\n const crawlFrameworkPkgsResult = await crawlFrameworkPkgs({\n root: process.cwd(),\n isBuild: command === 'build',\n isFrameworkPkgByJson(pkgJson) {\n const peerDependencies = pkgJson['peerDependencies']\n\n if (peerDependencies) {\n if (\n startPackageName in peerDependencies ||\n '@tanstack/start-client-core' in peerDependencies\n ) {\n return true\n }\n }\n\n return false\n },\n })\n\n return {\n // see https://vite.dev/config/shared-options.html#apptype\n // this will prevent vite from injecting middlewares that we don't want\n appType: viteConfig.appType ?? 'custom',\n environments: {\n [VITE_ENVIRONMENT_NAMES.client]: {\n consumer: 'client',\n build: {\n rollupOptions: {\n input: {\n main: ENTRY_POINTS.client,\n },\n },\n outDir: getClientOutputDirectory(viteConfig),\n },\n optimizeDeps: {\n exclude: crawlFrameworkPkgsResult.optimizeDeps.exclude,\n // Ensure user code can be crawled for dependencies\n entries: [clientAlias, routerAlias].map((entry) =>\n // Entries are treated as `tinyglobby` patterns so need to be escaped\n escapePath(entry),\n ),\n },\n },\n [VITE_ENVIRONMENT_NAMES.server]: {\n consumer: 'server',\n build: {\n ssr: true,\n rollupOptions: {\n input:\n viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]\n ?.build?.rollupOptions?.input ?? serverAlias,\n },\n outDir: getServerOutputDirectory(viteConfig),\n commonjsOptions: {\n include: [/node_modules/],\n },\n copyPublicDir:\n viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]\n ?.build?.copyPublicDir ?? false,\n },\n optimizeDeps: {\n // Ensure user code can be crawled for dependencies\n entries: [serverAlias, startAlias, routerAlias].map((entry) =>\n // Entries are treated as `tinyglobby` patterns so need to be escaped\n escapePath(entry),\n ),\n },\n },\n },\n\n resolve: {\n noExternal: [\n // ENTRY_POINTS.start,\n '@tanstack/start**',\n `@tanstack/${corePluginOpts.framework}-start**`,\n ...crawlFrameworkPkgsResult.ssr.noExternal.sort(),\n ],\n alias: {\n ...entryAliasConfiguration,\n },\n },\n /* prettier-ignore */\n define: {\n // define is an esbuild function that replaces the any instances of given keys with the given values\n // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify(\"TanStack Start\")\n // This is not the same as injecting environment variables.\n\n ...defineReplaceEnv('TSS_SERVER_FN_BASE', TSS_SERVER_FN_BASE),\n ...defineReplaceEnv('TSS_CLIENT_OUTPUT_DIR', getClientOutputDirectory(viteConfig)),\n ...defineReplaceEnv('TSS_ROUTER_BASEPATH', startConfig.router.basepath),\n ...(command === 'serve' ? defineReplaceEnv('TSS_SHELL', startConfig.spa?.enabled ? 'true' : 'false') : {}),\n ...defineReplaceEnv('TSS_DEV_SERVER', command === 'serve' ? 'true' : 'false'),\n // Dev SSR styles: enabled flag and basepath (defaults to vite base for asset URL alignment)\n ...defineReplaceEnv('TSS_DEV_SSR_STYLES_ENABLED', startConfig.dev.ssrStyles.enabled ? 'true' : 'false'),\n ...defineReplaceEnv('TSS_DEV_SSR_STYLES_BASEPATH', startConfig.dev.ssrStyles.basepath ?? resolvedStartConfig.viteAppBase),\n // Replace NODE_ENV during build (unless opted out) for dead code elimination in server bundles\n ...(command === 'build' && startConfig.server.build.staticNodeEnv ? {\n 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || viteConfig.mode || 'production'),\n } : {}),\n },\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const client = builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const server = builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!client) {\n throw new Error('Client environment not found')\n }\n\n if (!server) {\n throw new Error('SSR environment not found')\n }\n\n if (!client.isBuilt) {\n // Build the client bundle first\n await builder.build(client)\n }\n if (!server.isBuilt) {\n // Build the SSR bundle\n await builder.build(server)\n }\n\n // If a custom provider environment is configured (not SSR),\n // build it last so the manifest includes functions from all environments\n if (!ssrIsProvider) {\n const providerEnv = builder.environments[serverFnProviderEnv]\n if (!providerEnv) {\n throw new Error(\n `Provider environment \"${serverFnProviderEnv}\" not found`,\n )\n }\n if (!providerEnv.isBuilt) {\n // Build the provider environment last\n // This ensures all server functions are discovered from client/ssr builds\n await builder.build(providerEnv)\n }\n }\n },\n },\n }\n },\n },\n // Separate plugin for buildApp hook with enforce: 'post'\n // This ensures proper ordering with other plugins that also have\n // buildApp hooks with order: 'post'. The enforce: 'post' ensures this\n // runs after other plugins (like Nitro) complete their builds.\n {\n name: 'tanstack-start-core:post-build',\n enforce: 'post',\n buildApp: {\n order: 'post',\n async handler(builder) {\n const { startConfig } = getConfig()\n await postServerBuild({ builder, startConfig })\n },\n },\n },\n // Server function plugin handles:\n // 1. Identifying createServerFn().handler() calls\n // 2. Extracting server functions to separate modules\n // 3. Replacing call sites with RPC stubs\n // 4. Generating the server function manifest\n // Also handles createIsomorphicFn, createServerOnlyFn, createClientOnlyFn, createMiddleware\n startCompilerPlugin({\n framework: corePluginOpts.framework,\n environments,\n generateFunctionId: startPluginOpts?.serverFns?.generateFunctionId,\n providerEnvName: serverFnProviderEnv,\n }),\n importProtectionPlugin({\n getConfig,\n framework: corePluginOpts.framework,\n environments,\n providerEnvName: serverFnProviderEnv,\n }),\n tanStackStartRouter(startPluginOpts, getConfig, corePluginOpts),\n loadEnvPlugin(),\n startManifestPlugin({\n getClientBundle: () => getBundle(VITE_ENVIRONMENT_NAMES.client),\n getConfig,\n }),\n // When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),\n // install a middleware that rewrites incoming request URLs to prepend the vite base prefix.\n // This allows Vite's internal base middleware to accept the requests, then strips the prefix\n // before passing to the SSR handler.\n // Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,\n // ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.\n {\n name: 'tanstack-start-core:dev-base-rewrite',\n configureServer(server) {\n if (!needsDevBaseRewrite) {\n return\n }\n const basePrefix = resolvedStartConfig.viteAppBase.replace(/\\/$/, '')\n server.middlewares.use((req, _res, next) => {\n if (req.url && !req.url.startsWith(basePrefix)) {\n req.url = basePrefix + req.url\n }\n next()\n })\n },\n },\n devServerPlugin({\n getConfig,\n devSsrStylesEnabled: startPluginOpts?.dev?.ssrStyles?.enabled ?? true,\n }),\n previewServerPlugin(),\n {\n name: 'tanstack-start:core:capture-bundle',\n applyToEnvironment(e) {\n return (\n e.name === VITE_ENVIRONMENT_NAMES.client ||\n e.name === VITE_ENVIRONMENT_NAMES.server\n )\n },\n enforce: 'post',\n generateBundle(_options, bundle) {\n const environment = this.environment.name as ViteEnvironmentNames\n if (!Object.values(VITE_ENVIRONMENT_NAMES).includes(environment)) {\n throw new Error(`Unknown environment: ${environment}`)\n }\n capturedBundle[environment] = bundle\n },\n },\n ]\n}\n\nfunction defineReplaceEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n"],"names":["startConfig"],"mappings":";;;;;;;;;;;;;;;;;AAgCA,SAAS,UAAU,KAAsB;AACvC,MAAI;AACF,QAAI,IAAI,GAAG;AACX,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,4BACd,gBACA,iBACqB;AAGrB,QAAM,sBACJ,eAAe,UAAU,eAAe,uBAAuB;AACjE,QAAM,gBAAgB,wBAAwB,uBAAuB;AAErE,QAAM,sBAA2C;AAAA,IAC/C,MAAM;AAAA,IACN,eAAe;AAAA,IACf,gBAAgB;AAAA,IAChB,cAAc;AAAA,IACd,aAAa;AAAA,IACb;AAAA,EAAA;AAGF,MAAI;AACJ,QAAM,YAAyB,MAAM;AACnC,QAAI,CAAC,oBAAoB,MAAM;AAC7B,YAAM,IAAI,MAAM,2CAA2C;AAAA,IAC7D;AACA,QAAI,CAAC,aAAa;AAChB,oBAAc;AAAA,QACZ;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,MAAA;AAAA,IAExB;AACA,WAAO,EAAE,aAAa,qBAAqB,eAAA;AAAA,EAC7C;AAIA,MAAI,sBAAsB;AAE1B,QAAM,iBAEF,CAAA;AAEJ,WAAS,UAAU,SAAyD;AAC1E,UAAM,SAAS,eAAe,OAAO;AACrC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,uCAAuC,OAAO,EAAE;AAAA,IAClE;AACA,WAAO;AAAA,EACT;AAEA,QAAM,eAAmE;AAAA,IACvE,EAAE,MAAM,uBAAuB,QAAQ,MAAM,SAAA;AAAA,IAC7C,EAAE,MAAM,uBAAuB,QAAQ,MAAM,SAAA;AAAA,EAAS;AAExD,MACE,eAAe,UAAU,eACzB,CAAC,aAAa,KAAK,CAAC,MAAM,EAAE,SAAS,eAAe,UAAU,WAAW,GACzE;AACA,iBAAa,KAAK;AAAA,MAChB,MAAM,eAAe,SAAS;AAAA,MAC9B,MAAM;AAAA,IAAA,CACP;AAAA,EACH;AACA,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM,OAAO,YAAY,EAAE,WAAW;AACpC,4BAAoB,cAAc,WAAW,QAAQ;AACrD,YAAI,CAAC,UAAU,oBAAoB,WAAW,GAAG;AAC/C,8BAAoB,cAAc,UAAU;AAAA,YAC1C;AAAA,YACA,WAAW;AAAA,YACX;AAAA,UAAA,CACD;AAAA,QACH;AACA,cAAM,OAAO,WAAW,QAAQ,QAAQ,IAAA;AACxC,4BAAoB,OAAO;AAE3B,cAAM,EAAE,aAAAA,aAAAA,IAAgB,UAAA;AACxB,YAAIA,aAAY,OAAO,aAAa,QAAW;AAC7C,cAAI,CAAC,UAAU,oBAAoB,WAAW,GAAG;AAC/CA,yBAAY,OAAO,WACjB,oBAAoB,YAAY,QAAQ,YAAY,EAAE;AAAA,UAC1D,OAAO;AACLA,yBAAY,OAAO,WAAW;AAAA,UAChC;AAAA,QACF,OAAO;AACL,cAAI,YAAY,WAAW,CAAC,WAAW,QAAQ,gBAAgB;AAE7D,gBACE,CAAC,UAAU,CAAC,KAAKA,aAAY,OAAO,UAAU,GAAG,CAAC,EAAE;AAAA,cAClD,UAAU,CAAC,KAAK,oBAAoB,aAAa,GAAG,CAAC;AAAA,YAAA,GAEvD;AAMA,oCAAsB;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,qBAAqB,UAAU;AAAA,UACnC;AAAA,UACAA,aAAY,OAAO;AAAA,UACnBA,aAAY,UAAU;AAAA,UACtB;AAAA,QAAA,CACD;AACD,cAAM,uBAAuB,KAAK,MAAMA,aAAY,YAAY;AAChE,4BAAoB,eAAe;AAEnC,cAAM,gBAAgB,aAAa;AAAA,UACjC,MAAM;AAAA,UACN,iBAAiBA,aAAY,MAAM;AAAA,UACnC,cAAc;AAAA,UACd;AAAA,UACA,UAAU;AAAA,QAAA,CACX;AACD,4BAAoB,gBAAgB;AAEpC,cAAM,iBAAiB,aAAa;AAAA,UAClC,MAAM;AAAA,UACN,iBAAiBA,aAAY,OAAO;AAAA,UACpC,cAAc;AAAA,UACd;AAAA,UACA,UAAU;AAAA,QAAA,CACX;AACD,4BAAoB,iBAAiB;AAErC,cAAM,kBAAkB,aAAa;AAAA,UACnC,MAAM;AAAA,UACN,iBAAiBA,aAAY,OAAO;AAAA,UACpC,cAAc;AAAA,UACd;AAAA,UACA,UAAU;AAAA,QAAA,CACX;AAED,cAAM,kBAAkB,aAAa;AAAA,UACnC,MAAM;AAAA,UACN,iBAAiBA,aAAY,OAAO;AAAA,UACpC,cAAc;AAAA,UACd;AAAA,UACA,UAAU;AAAA,QAAA,CACX;AAED,cAAM,cAAc,KAAK;AAAA,UACvB,mBAAmB,eAAe,kBAAkB;AAAA,QAAA;AAEtD,cAAM,cAAc,KAAK;AAAA,UACvB,mBAAmB,eAAe,kBAAkB;AAAA,QAAA;AAEtD,cAAM,aAAa,KAAK;AAAA,UACtB,iBAAiB,eAAe,kBAAkB;AAAA,QAAA;AAEpD,cAAM,cAAc,KAAK,cAAc,cAAc;AAErD,cAAM,0BAGF;AAAA,UACF,CAAC,aAAa,MAAM,GAAG;AAAA,UACvB,CAAC,aAAa,MAAM,GAAG;AAAA,UACvB,CAAC,aAAa,KAAK,GAAG;AAAA,UACtB,CAAC,aAAa,MAAM,GAAG;AAAA,QAAA;AAGzB,cAAM,mBACJ,aAAa,eAAe,SAAS;AAQvC,cAAM,2BAA2B,MAAM,mBAAmB;AAAA,UACxD,MAAM,QAAQ,IAAA;AAAA,UACd,SAAS,YAAY;AAAA,UACrB,qBAAqB,SAAS;AAC5B,kBAAM,mBAAmB,QAAQ,kBAAkB;AAEnD,gBAAI,kBAAkB;AACpB,kBACE,oBAAoB,oBACpB,iCAAiC,kBACjC;AACA,uBAAO;AAAA,cACT;AAAA,YACF;AAEA,mBAAO;AAAA,UACT;AAAA,QAAA,CACD;AAED,eAAO;AAAA;AAAA;AAAA,UAGL,SAAS,WAAW,WAAW;AAAA,UAC/B,cAAc;AAAA,YACZ,CAAC,uBAAuB,MAAM,GAAG;AAAA,cAC/B,UAAU;AAAA,cACV,OAAO;AAAA,gBACL,eAAe;AAAA,kBACb,OAAO;AAAA,oBACL,MAAM,aAAa;AAAA,kBAAA;AAAA,gBACrB;AAAA,gBAEF,QAAQ,yBAAyB,UAAU;AAAA,cAAA;AAAA,cAE7C,cAAc;AAAA,gBACZ,SAAS,yBAAyB,aAAa;AAAA;AAAA,gBAE/C,SAAS,CAAC,aAAa,WAAW,EAAE;AAAA,kBAAI,CAAC;AAAA;AAAA,oBAEvC,WAAW,KAAK;AAAA;AAAA,gBAAA;AAAA,cAClB;AAAA,YACF;AAAA,YAEF,CAAC,uBAAuB,MAAM,GAAG;AAAA,cAC/B,UAAU;AAAA,cACV,OAAO;AAAA,gBACL,KAAK;AAAA,gBACL,eAAe;AAAA,kBACb,OACE,WAAW,eAAe,uBAAuB,MAAM,GACnD,OAAO,eAAe,SAAS;AAAA,gBAAA;AAAA,gBAEvC,QAAQ,yBAAyB,UAAU;AAAA,gBAC3C,iBAAiB;AAAA,kBACf,SAAS,CAAC,cAAc;AAAA,gBAAA;AAAA,gBAE1B,eACE,WAAW,eAAe,uBAAuB,MAAM,GACnD,OAAO,iBAAiB;AAAA,cAAA;AAAA,cAEhC,cAAc;AAAA;AAAA,gBAEZ,SAAS,CAAC,aAAa,YAAY,WAAW,EAAE;AAAA,kBAAI,CAAC;AAAA;AAAA,oBAEnD,WAAW,KAAK;AAAA;AAAA,gBAAA;AAAA,cAClB;AAAA,YACF;AAAA,UACF;AAAA,UAGF,SAAS;AAAA,YACP,YAAY;AAAA;AAAA,cAEV;AAAA,cACA,aAAa,eAAe,SAAS;AAAA,cACrC,GAAG,yBAAyB,IAAI,WAAW,KAAA;AAAA,YAAK;AAAA,YAElD,OAAO;AAAA,cACL,GAAG;AAAA,YAAA;AAAA,UACL;AAAA;AAAA,UAGF,QAAQ;AAAA;AAAA;AAAA;AAAA,YAKN,GAAG,iBAAiB,sBAAsB,kBAAkB;AAAA,YAC5D,GAAG,iBAAiB,yBAAyB,yBAAyB,UAAU,CAAC;AAAA,YACjF,GAAG,iBAAiB,uBAAuBA,aAAY,OAAO,QAAQ;AAAA,YACtE,GAAI,YAAY,UAAU,iBAAiB,aAAaA,aAAY,KAAK,UAAU,SAAS,OAAO,IAAI,CAAA;AAAA,YACvG,GAAG,iBAAiB,kBAAkB,YAAY,UAAU,SAAS,OAAO;AAAA;AAAA,YAE5E,GAAG,iBAAiB,8BAA8BA,aAAY,IAAI,UAAU,UAAU,SAAS,OAAO;AAAA,YACtG,GAAG,iBAAiB,+BAA+BA,aAAY,IAAI,UAAU,YAAY,oBAAoB,WAAW;AAAA;AAAA,YAExH,GAAI,YAAY,WAAWA,aAAY,OAAO,MAAM,gBAAgB;AAAA,cAClE,wBAAwB,KAAK,UAAU,QAAQ,IAAI,YAAY,WAAW,QAAQ,YAAY;AAAA,YAAA,IAC5F,CAAA;AAAA,UAAC;AAAA,UAEP,SAAS;AAAA,YACP,eAAe;AAAA,YACf,MAAM,SAAS,SAAS;AACtB,oBAAM,SAAS,QAAQ,aAAa,uBAAuB,MAAM;AACjE,oBAAM,SAAS,QAAQ,aAAa,uBAAuB,MAAM;AAEjE,kBAAI,CAAC,QAAQ;AACX,sBAAM,IAAI,MAAM,8BAA8B;AAAA,cAChD;AAEA,kBAAI,CAAC,QAAQ;AACX,sBAAM,IAAI,MAAM,2BAA2B;AAAA,cAC7C;AAEA,kBAAI,CAAC,OAAO,SAAS;AAEnB,sBAAM,QAAQ,MAAM,MAAM;AAAA,cAC5B;AACA,kBAAI,CAAC,OAAO,SAAS;AAEnB,sBAAM,QAAQ,MAAM,MAAM;AAAA,cAC5B;AAIA,kBAAI,CAAC,eAAe;AAClB,sBAAM,cAAc,QAAQ,aAAa,mBAAmB;AAC5D,oBAAI,CAAC,aAAa;AAChB,wBAAM,IAAI;AAAA,oBACR,yBAAyB,mBAAmB;AAAA,kBAAA;AAAA,gBAEhD;AACA,oBAAI,CAAC,YAAY,SAAS;AAGxB,wBAAM,QAAQ,MAAM,WAAW;AAAA,gBACjC;AAAA,cACF;AAAA,YACF;AAAA,UAAA;AAAA,QACF;AAAA,MAEJ;AAAA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMF;AAAA,MACE,MAAM;AAAA,MACN,SAAS;AAAA,MACT,UAAU;AAAA,QACR,OAAO;AAAA,QACP,MAAM,QAAQ,SAAS;AACrB,gBAAM,EAAE,aAAAA,aAAAA,IAAgB,UAAA;AACxB,gBAAM,gBAAgB,EAAE,SAAS,aAAAA,cAAa;AAAA,QAChD;AAAA,MAAA;AAAA,IACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAQF,oBAAoB;AAAA,MAClB,WAAW,eAAe;AAAA,MAC1B;AAAA,MACA,oBAAoB,iBAAiB,WAAW;AAAA,MAChD,iBAAiB;AAAA,IAAA,CAClB;AAAA,IACD,uBAAuB;AAAA,MACrB;AAAA,MACA,WAAW,eAAe;AAAA,MAC1B;AAAA,MACA,iBAAiB;AAAA,IAAA,CAClB;AAAA,IACD,oBAAoB,iBAAiB,WAAW,cAAc;AAAA,IAC9D,cAAA;AAAA,IACA,oBAAoB;AAAA,MAClB,iBAAiB,MAAM,UAAU,uBAAuB,MAAM;AAAA,MAC9D;AAAA,IAAA,CACD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOD;AAAA,MACE,MAAM;AAAA,MACN,gBAAgB,QAAQ;AACtB,YAAI,CAAC,qBAAqB;AACxB;AAAA,QACF;AACA,cAAM,aAAa,oBAAoB,YAAY,QAAQ,OAAO,EAAE;AACpE,eAAO,YAAY,IAAI,CAAC,KAAK,MAAM,SAAS;AAC1C,cAAI,IAAI,OAAO,CAAC,IAAI,IAAI,WAAW,UAAU,GAAG;AAC9C,gBAAI,MAAM,aAAa,IAAI;AAAA,UAC7B;AACA,eAAA;AAAA,QACF,CAAC;AAAA,MACH;AAAA,IAAA;AAAA,IAEF,gBAAgB;AAAA,MACd;AAAA,MACA,qBAAqB,iBAAiB,KAAK,WAAW,WAAW;AAAA,IAAA,CAClE;AAAA,IACD,oBAAA;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,mBAAmB,GAAG;AACpB,eACE,EAAE,SAAS,uBAAuB,UAClC,EAAE,SAAS,uBAAuB;AAAA,MAEtC;AAAA,MACA,SAAS;AAAA,MACT,eAAe,UAAU,QAAQ;AAC/B,cAAM,cAAc,KAAK,YAAY;AACrC,YAAI,CAAC,OAAO,OAAO,sBAAsB,EAAE,SAAS,WAAW,GAAG;AAChE,gBAAM,IAAI,MAAM,wBAAwB,WAAW,EAAE;AAAA,QACvD;AACA,uBAAe,WAAW,IAAI;AAAA,MAChC;AAAA,IAAA;AAAA,EACF;AAEJ;AAEA,SAAS,iBACP,KACA,OACsE;AACtE,SAAO;AAAA,IACL,CAAC,eAAe,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK;AAAA,IAC5C,CAAC,mBAAmB,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK;AAAA,EAAA;AAEpD;"}
|
package/dist/esm/schema.d.ts
CHANGED
|
@@ -249,6 +249,12 @@ export declare function parseStartConfig(opts: z.input<typeof tanstackStartOptio
|
|
|
249
249
|
headers?: Record<string, string> | undefined;
|
|
250
250
|
} | undefined;
|
|
251
251
|
}[];
|
|
252
|
+
dev: {
|
|
253
|
+
ssrStyles: {
|
|
254
|
+
enabled: boolean;
|
|
255
|
+
basepath?: string | undefined;
|
|
256
|
+
};
|
|
257
|
+
};
|
|
252
258
|
sitemap?: {
|
|
253
259
|
enabled: boolean;
|
|
254
260
|
outputPath: string;
|
|
@@ -2750,6 +2756,28 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
|
|
|
2750
2756
|
}, ...args: unknown[]) => any) | undefined;
|
|
2751
2757
|
headers?: Record<string, string> | undefined;
|
|
2752
2758
|
}>>>>;
|
|
2759
|
+
dev: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
2760
|
+
ssrStyles: z.ZodDefault<z.ZodOptional<z.ZodObject<{
|
|
2761
|
+
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
2762
|
+
basepath: z.ZodOptional<z.ZodString>;
|
|
2763
|
+
}, "strip", z.ZodTypeAny, {
|
|
2764
|
+
enabled: boolean;
|
|
2765
|
+
basepath?: string | undefined;
|
|
2766
|
+
}, {
|
|
2767
|
+
basepath?: string | undefined;
|
|
2768
|
+
enabled?: boolean | undefined;
|
|
2769
|
+
}>>>;
|
|
2770
|
+
}, "strip", z.ZodTypeAny, {
|
|
2771
|
+
ssrStyles: {
|
|
2772
|
+
enabled: boolean;
|
|
2773
|
+
basepath?: string | undefined;
|
|
2774
|
+
};
|
|
2775
|
+
}, {
|
|
2776
|
+
ssrStyles?: {
|
|
2777
|
+
basepath?: string | undefined;
|
|
2778
|
+
enabled?: boolean | undefined;
|
|
2779
|
+
} | undefined;
|
|
2780
|
+
}>>>;
|
|
2753
2781
|
spa: z.ZodOptional<z.ZodObject<{
|
|
2754
2782
|
enabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
2755
2783
|
maskPath: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
@@ -3457,6 +3485,12 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
|
|
|
3457
3485
|
headers?: Record<string, string> | undefined;
|
|
3458
3486
|
} | undefined;
|
|
3459
3487
|
}[];
|
|
3488
|
+
dev: {
|
|
3489
|
+
ssrStyles: {
|
|
3490
|
+
enabled: boolean;
|
|
3491
|
+
basepath?: string | undefined;
|
|
3492
|
+
};
|
|
3493
|
+
};
|
|
3460
3494
|
sitemap?: {
|
|
3461
3495
|
enabled: boolean;
|
|
3462
3496
|
outputPath: string;
|
|
@@ -3892,6 +3926,12 @@ declare const tanstackStartOptionsSchema: z.ZodDefault<z.ZodOptional<z.ZodObject
|
|
|
3892
3926
|
headers?: Record<string, string> | undefined;
|
|
3893
3927
|
} | undefined;
|
|
3894
3928
|
}[] | undefined;
|
|
3929
|
+
dev?: {
|
|
3930
|
+
ssrStyles?: {
|
|
3931
|
+
basepath?: string | undefined;
|
|
3932
|
+
enabled?: boolean | undefined;
|
|
3933
|
+
} | undefined;
|
|
3934
|
+
} | undefined;
|
|
3895
3935
|
spa?: {
|
|
3896
3936
|
enabled?: boolean | undefined;
|
|
3897
3937
|
prerender?: {
|
package/dist/esm/schema.js
CHANGED
|
@@ -174,6 +174,12 @@ const tanstackStartOptionsSchema = z.object({
|
|
|
174
174
|
autoStaticPathsDiscovery: z.boolean().optional(),
|
|
175
175
|
maxRedirects: z.number().min(0).optional()
|
|
176
176
|
}).and(pagePrerenderOptionsSchema.optional()).optional(),
|
|
177
|
+
dev: z.object({
|
|
178
|
+
ssrStyles: z.object({
|
|
179
|
+
enabled: z.boolean().optional().default(true),
|
|
180
|
+
basepath: z.string().optional()
|
|
181
|
+
}).optional().default({})
|
|
182
|
+
}).optional().default({}),
|
|
177
183
|
spa: spaSchema.optional(),
|
|
178
184
|
vite: z.object({ installDevServerMiddleware: z.boolean().optional() }).optional(),
|
|
179
185
|
importProtection: importProtectionOptionsSchema
|
package/dist/esm/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-plugin'\nimport type { TanStackStartVitePluginCoreOptions } from './types'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })\n .partial()\n\n// --- Import Protection Schema ---\n\nconst patternSchema = z.union([z.string(), z.instanceof(RegExp)])\n\nconst importProtectionBehaviorSchema = z.enum(['error', 'mock'])\n\nconst importProtectionEnvRulesSchema = z.object({\n specifiers: z.array(patternSchema).optional(),\n files: z.array(patternSchema).optional(),\n excludeFiles: z.array(patternSchema).optional(),\n})\n\nconst importProtectionOptionsSchema = z\n .object({\n enabled: z.boolean().optional(),\n behavior: z\n .union([\n importProtectionBehaviorSchema,\n z.object({\n dev: importProtectionBehaviorSchema.optional(),\n build: importProtectionBehaviorSchema.optional(),\n }),\n ])\n .optional(),\n /**\n * In `behavior: 'mock'`, control whether mocked imports emit a runtime\n * console diagnostic when accessed.\n *\n * - 'error': console.error(new Error(...)) (default)\n * - 'warn': console.warn(new Error(...))\n * - 'off': disable runtime diagnostics\n */\n mockAccess: z.enum(['error', 'warn', 'off']).optional(),\n onViolation: z\n .function()\n .args(z.any())\n .returns(\n z.union([\n z.boolean(),\n z.void(),\n z.promise(z.union([z.boolean(), z.void()])),\n ]),\n )\n .optional(),\n include: z.array(patternSchema).optional(),\n exclude: z.array(patternSchema).optional(),\n client: importProtectionEnvRulesSchema.optional(),\n server: importProtectionEnvRulesSchema.optional(),\n ignoreImporters: z.array(patternSchema).optional(),\n maxTraceDepth: z.number().optional(),\n log: z.enum(['once', 'always']).optional(),\n })\n .optional()\n\nexport function parseStartConfig(\n opts: z.input<typeof tanstackStartOptionsSchema>,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n root: string,\n) {\n const options = tanstackStartOptionsSchema.parse(opts)\n\n const srcDirectory = options.srcDirectory\n\n const routesDirectory = path.resolve(\n root,\n srcDirectory,\n options.router.routesDirectory ?? 'routes',\n )\n\n const generatedRouteTree = path.resolve(\n root,\n srcDirectory,\n options.router.generatedRouteTree ?? 'routeTree.gen.ts',\n )\n\n return {\n ...options,\n router: {\n ...options.router,\n ...getConfig(\n {\n ...options.router,\n routesDirectory,\n generatedRouteTree,\n },\n root,\n ),\n target: corePluginOpts.framework,\n },\n }\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n headers: z.record(z.string(), z.string()).optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nconst pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nconst tanstackStartOptionsSchema = z\n .object({\n srcDirectory: z.string().optional().default('src'),\n start: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n router: z\n .object({\n entry: z.string().optional(),\n basepath: z.string().optional(),\n })\n .and(tsrConfig.optional().default({}))\n .optional()\n .default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n build: z\n .object({\n staticNodeEnv: z.boolean().optional().default(true),\n })\n .optional()\n .default({}),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n generateFunctionId: z\n .function()\n .args(\n z.object({\n filename: z.string(),\n functionName: z.string(),\n }),\n )\n .returns(z.string().optional())\n .optional(),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n autoStaticPathsDiscovery: z.boolean().optional(),\n maxRedirects: z.number().min(0).optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n spa: spaSchema.optional(),\n vite: z\n .object({ installDevServerMiddleware: z.boolean().optional() })\n .optional(),\n importProtection: importProtectionOptionsSchema,\n })\n .optional()\n .default({})\n\nexport type Page = z.infer<typeof pageSchema>\n\nexport type TanStackStartInputConfig = z.input<\n typeof tanstackStartOptionsSchema\n>\nexport type TanStackStartOutputConfig = ReturnType<typeof parseStartConfig>\n\nexport type ImportProtectionBehavior = z.infer<\n typeof importProtectionBehaviorSchema\n>\nexport type ImportProtectionEnvRules = z.infer<\n typeof importProtectionEnvRulesSchema\n>\nexport type ImportProtectionOptions = z.input<\n typeof importProtectionOptionsSchema\n>\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"schema.js","sources":["../../src/schema.ts"],"sourcesContent":["import path from 'node:path'\nimport { z } from 'zod'\nimport { configSchema, getConfig } from '@tanstack/router-plugin'\nimport type { TanStackStartVitePluginCoreOptions } from './types'\n\nconst tsrConfig = configSchema\n .omit({ autoCodeSplitting: true, target: true, verboseFileRoutes: true })\n .partial()\n\n// --- Import Protection Schema ---\n\nconst patternSchema = z.union([z.string(), z.instanceof(RegExp)])\n\nconst importProtectionBehaviorSchema = z.enum(['error', 'mock'])\n\nconst importProtectionEnvRulesSchema = z.object({\n specifiers: z.array(patternSchema).optional(),\n files: z.array(patternSchema).optional(),\n excludeFiles: z.array(patternSchema).optional(),\n})\n\nconst importProtectionOptionsSchema = z\n .object({\n enabled: z.boolean().optional(),\n behavior: z\n .union([\n importProtectionBehaviorSchema,\n z.object({\n dev: importProtectionBehaviorSchema.optional(),\n build: importProtectionBehaviorSchema.optional(),\n }),\n ])\n .optional(),\n /**\n * In `behavior: 'mock'`, control whether mocked imports emit a runtime\n * console diagnostic when accessed.\n *\n * - 'error': console.error(new Error(...)) (default)\n * - 'warn': console.warn(new Error(...))\n * - 'off': disable runtime diagnostics\n */\n mockAccess: z.enum(['error', 'warn', 'off']).optional(),\n onViolation: z\n .function()\n .args(z.any())\n .returns(\n z.union([\n z.boolean(),\n z.void(),\n z.promise(z.union([z.boolean(), z.void()])),\n ]),\n )\n .optional(),\n include: z.array(patternSchema).optional(),\n exclude: z.array(patternSchema).optional(),\n client: importProtectionEnvRulesSchema.optional(),\n server: importProtectionEnvRulesSchema.optional(),\n ignoreImporters: z.array(patternSchema).optional(),\n maxTraceDepth: z.number().optional(),\n log: z.enum(['once', 'always']).optional(),\n })\n .optional()\n\nexport function parseStartConfig(\n opts: z.input<typeof tanstackStartOptionsSchema>,\n corePluginOpts: TanStackStartVitePluginCoreOptions,\n root: string,\n) {\n const options = tanstackStartOptionsSchema.parse(opts)\n\n const srcDirectory = options.srcDirectory\n\n const routesDirectory = path.resolve(\n root,\n srcDirectory,\n options.router.routesDirectory ?? 'routes',\n )\n\n const generatedRouteTree = path.resolve(\n root,\n srcDirectory,\n options.router.generatedRouteTree ?? 'routeTree.gen.ts',\n )\n\n return {\n ...options,\n router: {\n ...options.router,\n ...getConfig(\n {\n ...options.router,\n routesDirectory,\n generatedRouteTree,\n },\n root,\n ),\n target: corePluginOpts.framework,\n },\n }\n}\n\nconst pageSitemapOptionsSchema = z.object({\n exclude: z.boolean().optional(),\n priority: z.number().min(0).max(1).optional(),\n changefreq: z\n .enum(['always', 'hourly', 'daily', 'weekly', 'monthly', 'yearly', 'never'])\n .optional(),\n lastmod: z.union([z.string(), z.date()]).optional(),\n alternateRefs: z\n .array(\n z.object({\n href: z.string(),\n hreflang: z.string(),\n }),\n )\n .optional(),\n images: z\n .array(\n z.object({\n loc: z.string(),\n caption: z.string().optional(),\n title: z.string().optional(),\n }),\n )\n .optional(),\n news: z\n .object({\n publication: z.object({\n name: z.string(),\n language: z.string(),\n }),\n publicationDate: z.union([z.string(), z.date()]),\n title: z.string(),\n })\n .optional(),\n})\n\nconst pageBaseSchema = z.object({\n path: z.string(),\n sitemap: pageSitemapOptionsSchema.optional(),\n fromCrawl: z.boolean().optional(),\n})\n\nconst pagePrerenderOptionsSchema = z.object({\n enabled: z.boolean().optional(),\n outputPath: z.string().optional(),\n autoSubfolderIndex: z.boolean().optional(),\n crawlLinks: z.boolean().optional(),\n retryCount: z.number().optional(),\n retryDelay: z.number().optional(),\n onSuccess: z\n .function()\n .args(\n z.object({\n page: pageBaseSchema,\n html: z.string(),\n }),\n )\n .returns(z.any())\n .optional(),\n headers: z.record(z.string(), z.string()).optional(),\n})\n\nconst spaSchema = z.object({\n enabled: z.boolean().optional().default(true),\n maskPath: z.string().optional().default('/'),\n prerender: pagePrerenderOptionsSchema\n .optional()\n .default({})\n .transform((opts) => ({\n outputPath: opts.outputPath ?? '/_shell',\n crawlLinks: false,\n retryCount: 0,\n ...opts,\n enabled: true,\n })),\n})\n\nconst pageSchema = pageBaseSchema.extend({\n prerender: pagePrerenderOptionsSchema.optional(),\n})\n\nconst tanstackStartOptionsSchema = z\n .object({\n srcDirectory: z.string().optional().default('src'),\n start: z\n .object({\n entry: z.string().optional(),\n })\n .optional()\n .default({}),\n router: z\n .object({\n entry: z.string().optional(),\n basepath: z.string().optional(),\n })\n .and(tsrConfig.optional().default({}))\n .optional()\n .default({}),\n client: z\n .object({\n entry: z.string().optional(),\n base: z.string().optional().default('/_build'),\n })\n .optional()\n .default({}),\n server: z\n .object({\n entry: z.string().optional(),\n build: z\n .object({\n staticNodeEnv: z.boolean().optional().default(true),\n })\n .optional()\n .default({}),\n })\n .optional()\n .default({}),\n serverFns: z\n .object({\n base: z.string().optional().default('/_serverFn'),\n generateFunctionId: z\n .function()\n .args(\n z.object({\n filename: z.string(),\n functionName: z.string(),\n }),\n )\n .returns(z.string().optional())\n .optional(),\n })\n .optional()\n .default({}),\n pages: z.array(pageSchema).optional().default([]),\n sitemap: z\n .object({\n enabled: z.boolean().optional().default(true),\n host: z.string().optional(),\n outputPath: z.string().optional().default('sitemap.xml'),\n })\n .optional(),\n prerender: z\n .object({\n enabled: z.boolean().optional(),\n concurrency: z.number().optional(),\n filter: z.function().args(pageSchema).returns(z.any()).optional(),\n failOnError: z.boolean().optional(),\n autoStaticPathsDiscovery: z.boolean().optional(),\n maxRedirects: z.number().min(0).optional(),\n })\n .and(pagePrerenderOptionsSchema.optional())\n .optional(),\n dev: z\n .object({\n ssrStyles: z\n .object({\n enabled: z.boolean().optional().default(true),\n basepath: z.string().optional(),\n })\n .optional()\n .default({}),\n })\n .optional()\n .default({}),\n spa: spaSchema.optional(),\n vite: z\n .object({ installDevServerMiddleware: z.boolean().optional() })\n .optional(),\n importProtection: importProtectionOptionsSchema,\n })\n .optional()\n .default({})\n\nexport type Page = z.infer<typeof pageSchema>\n\nexport type TanStackStartInputConfig = z.input<\n typeof tanstackStartOptionsSchema\n>\nexport type TanStackStartOutputConfig = ReturnType<typeof parseStartConfig>\n\nexport type ImportProtectionBehavior = z.infer<\n typeof importProtectionBehaviorSchema\n>\nexport type ImportProtectionEnvRules = z.infer<\n typeof importProtectionEnvRulesSchema\n>\nexport type ImportProtectionOptions = z.input<\n typeof importProtectionOptionsSchema\n>\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.166.0",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -60,12 +60,12 @@
|
|
|
60
60
|
"vitefu": "^1.1.1",
|
|
61
61
|
"xmlbuilder2": "^4.0.3",
|
|
62
62
|
"zod": "^3.24.2",
|
|
63
|
+
"@tanstack/router-generator": "1.164.0",
|
|
63
64
|
"@tanstack/router-core": "1.163.3",
|
|
65
|
+
"@tanstack/router-plugin": "1.164.0",
|
|
64
66
|
"@tanstack/router-utils": "1.161.4",
|
|
65
67
|
"@tanstack/start-client-core": "1.164.1",
|
|
66
|
-
"@tanstack/
|
|
67
|
-
"@tanstack/router-plugin": "1.164.0",
|
|
68
|
-
"@tanstack/start-server-core": "1.164.1"
|
|
68
|
+
"@tanstack/start-server-core": "1.166.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/babel__code-frame": "^7.0.6",
|
|
@@ -14,8 +14,10 @@ import type { GetConfigFn } from '../types'
|
|
|
14
14
|
|
|
15
15
|
export function devServerPlugin({
|
|
16
16
|
getConfig,
|
|
17
|
+
devSsrStylesEnabled,
|
|
17
18
|
}: {
|
|
18
19
|
getConfig: GetConfigFn
|
|
20
|
+
devSsrStylesEnabled: boolean
|
|
19
21
|
}): PluginOption {
|
|
20
22
|
let isTest = false
|
|
21
23
|
|
|
@@ -63,59 +65,61 @@ export function devServerPlugin({
|
|
|
63
65
|
// This makes the CSS endpoint work regardless of plugin order in the Vite config.
|
|
64
66
|
// We check pathname.endsWith() to handle basepaths (e.g., /my-app/@tanstack-start/styles.css)
|
|
65
67
|
// since pre-phase runs before Vite's base middleware strips the basepath.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
if (devSsrStylesEnabled) {
|
|
69
|
+
viteDevServer.middlewares.use(async (req, res, next) => {
|
|
70
|
+
const url = req.url ?? ''
|
|
71
|
+
const pathname = url.split('?')[0]
|
|
72
|
+
if (!pathname?.endsWith('/@tanstack-start/styles.css')) {
|
|
73
|
+
return next()
|
|
74
|
+
}
|
|
72
75
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
try {
|
|
77
|
+
// Parse route IDs from query param
|
|
78
|
+
const urlObj = new URL(url, 'http://localhost')
|
|
79
|
+
const routesParam = urlObj.searchParams.get('routes')
|
|
80
|
+
const routeIds = routesParam ? routesParam.split(',') : []
|
|
78
81
|
|
|
79
|
-
|
|
80
|
-
|
|
82
|
+
// Build entries list from route file paths
|
|
83
|
+
const entries: Array<string> = []
|
|
81
84
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
// Look up route file paths from manifest
|
|
86
|
+
// Only routes registered in the manifest are used - this prevents path injection
|
|
87
|
+
const routesManifest = (globalThis as any).TSS_ROUTES_MANIFEST as
|
|
88
|
+
| Record<string, { filePath: string; children?: Array<string> }>
|
|
89
|
+
| undefined
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
if (routesManifest && routeIds.length > 0) {
|
|
92
|
+
for (const routeId of routeIds) {
|
|
93
|
+
const route = routesManifest[routeId]
|
|
94
|
+
if (route?.filePath) {
|
|
95
|
+
entries.push(route.filePath)
|
|
96
|
+
}
|
|
93
97
|
}
|
|
94
98
|
}
|
|
95
|
-
}
|
|
96
99
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
100
|
+
const css =
|
|
101
|
+
entries.length > 0
|
|
102
|
+
? await collectDevStyles({
|
|
103
|
+
viteDevServer,
|
|
104
|
+
entries,
|
|
105
|
+
cssModulesCache,
|
|
106
|
+
})
|
|
107
|
+
: undefined
|
|
105
108
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
109
|
+
res.setHeader('Content-Type', 'text/css')
|
|
110
|
+
res.setHeader('Cache-Control', 'no-store')
|
|
111
|
+
res.end(css ?? '')
|
|
112
|
+
} catch (e) {
|
|
113
|
+
// Log error but still return valid CSS response to avoid MIME type issues
|
|
114
|
+
console.error('[tanstack-start] Error collecting dev styles:', e)
|
|
115
|
+
res.setHeader('Content-Type', 'text/css')
|
|
116
|
+
res.setHeader('Cache-Control', 'no-store')
|
|
117
|
+
res.end(
|
|
118
|
+
`/* Error collecting styles: ${e instanceof Error ? e.message : String(e)} */`,
|
|
119
|
+
)
|
|
120
|
+
}
|
|
121
|
+
})
|
|
122
|
+
}
|
|
119
123
|
|
|
120
124
|
return () => {
|
|
121
125
|
const serverEnv = viteDevServer.environments[
|
package/src/plugin.ts
CHANGED
|
@@ -73,6 +73,10 @@ export function TanStackStartVitePluginCore(
|
|
|
73
73
|
return { startConfig, resolvedStartConfig, corePluginOpts }
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
// When the router basepath and vite base are misaligned during dev,
|
|
77
|
+
// we install a URL rewrite middleware instead of erroring.
|
|
78
|
+
let needsDevBaseRewrite = false
|
|
79
|
+
|
|
76
80
|
const capturedBundle: Partial<
|
|
77
81
|
Record<ViteEnvironmentNames, vite.Rollup.OutputBundle>
|
|
78
82
|
> = {}
|
|
@@ -130,9 +134,12 @@ export function TanStackStartVitePluginCore(
|
|
|
130
134
|
joinPaths(['/', resolvedStartConfig.viteAppBase, '/']),
|
|
131
135
|
)
|
|
132
136
|
) {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
137
|
+
// The router basepath and vite base are misaligned.
|
|
138
|
+
// Instead of erroring, we install a dev-server middleware that
|
|
139
|
+
// rewrites incoming request URLs to prepend the vite base prefix.
|
|
140
|
+
// This allows users to have e.g. base: '/_ui/' for asset URLs
|
|
141
|
+
// while keeping router basepath at '/' for page navigation.
|
|
142
|
+
needsDevBaseRewrite = true
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
}
|
|
@@ -302,6 +309,9 @@ export function TanStackStartVitePluginCore(
|
|
|
302
309
|
...defineReplaceEnv('TSS_ROUTER_BASEPATH', startConfig.router.basepath),
|
|
303
310
|
...(command === 'serve' ? defineReplaceEnv('TSS_SHELL', startConfig.spa?.enabled ? 'true' : 'false') : {}),
|
|
304
311
|
...defineReplaceEnv('TSS_DEV_SERVER', command === 'serve' ? 'true' : 'false'),
|
|
312
|
+
// Dev SSR styles: enabled flag and basepath (defaults to vite base for asset URL alignment)
|
|
313
|
+
...defineReplaceEnv('TSS_DEV_SSR_STYLES_ENABLED', startConfig.dev.ssrStyles.enabled ? 'true' : 'false'),
|
|
314
|
+
...defineReplaceEnv('TSS_DEV_SSR_STYLES_BASEPATH', startConfig.dev.ssrStyles.basepath ?? resolvedStartConfig.viteAppBase),
|
|
305
315
|
// Replace NODE_ENV during build (unless opted out) for dead code elimination in server bundles
|
|
306
316
|
...(command === 'build' && startConfig.server.build.staticNodeEnv ? {
|
|
307
317
|
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || viteConfig.mode || 'production'),
|
|
@@ -389,7 +399,31 @@ export function TanStackStartVitePluginCore(
|
|
|
389
399
|
getClientBundle: () => getBundle(VITE_ENVIRONMENT_NAMES.client),
|
|
390
400
|
getConfig,
|
|
391
401
|
}),
|
|
392
|
-
|
|
402
|
+
// When the vite base and router basepath are misaligned (e.g. base: '/_ui/', basepath: '/'),
|
|
403
|
+
// install a middleware that rewrites incoming request URLs to prepend the vite base prefix.
|
|
404
|
+
// This allows Vite's internal base middleware to accept the requests, then strips the prefix
|
|
405
|
+
// before passing to the SSR handler.
|
|
406
|
+
// Registered BEFORE devServerPlugin so this middleware is added to the Connect stack first,
|
|
407
|
+
// ensuring all subsequent middlewares (CSS, SSR, etc.) see the rewritten URL.
|
|
408
|
+
{
|
|
409
|
+
name: 'tanstack-start-core:dev-base-rewrite',
|
|
410
|
+
configureServer(server) {
|
|
411
|
+
if (!needsDevBaseRewrite) {
|
|
412
|
+
return
|
|
413
|
+
}
|
|
414
|
+
const basePrefix = resolvedStartConfig.viteAppBase.replace(/\/$/, '')
|
|
415
|
+
server.middlewares.use((req, _res, next) => {
|
|
416
|
+
if (req.url && !req.url.startsWith(basePrefix)) {
|
|
417
|
+
req.url = basePrefix + req.url
|
|
418
|
+
}
|
|
419
|
+
next()
|
|
420
|
+
})
|
|
421
|
+
},
|
|
422
|
+
},
|
|
423
|
+
devServerPlugin({
|
|
424
|
+
getConfig,
|
|
425
|
+
devSsrStylesEnabled: startPluginOpts?.dev?.ssrStyles?.enabled ?? true,
|
|
426
|
+
}),
|
|
393
427
|
previewServerPlugin(),
|
|
394
428
|
{
|
|
395
429
|
name: 'tanstack-start:core:capture-bundle',
|
package/src/schema.ts
CHANGED
|
@@ -251,6 +251,18 @@ const tanstackStartOptionsSchema = z
|
|
|
251
251
|
})
|
|
252
252
|
.and(pagePrerenderOptionsSchema.optional())
|
|
253
253
|
.optional(),
|
|
254
|
+
dev: z
|
|
255
|
+
.object({
|
|
256
|
+
ssrStyles: z
|
|
257
|
+
.object({
|
|
258
|
+
enabled: z.boolean().optional().default(true),
|
|
259
|
+
basepath: z.string().optional(),
|
|
260
|
+
})
|
|
261
|
+
.optional()
|
|
262
|
+
.default({}),
|
|
263
|
+
})
|
|
264
|
+
.optional()
|
|
265
|
+
.default({}),
|
|
254
266
|
spa: spaSchema.optional(),
|
|
255
267
|
vite: z
|
|
256
268
|
.object({ installDevServerMiddleware: z.boolean().optional() })
|