@tanstack/start-plugin-core 1.121.0-alpha.17 → 1.121.0-alpha.18

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.
@@ -172,7 +172,7 @@ function startManifestPlugin(opts) {
172
172
  try {
173
173
  const routesManifestOutputDirPath = path.resolve(
174
174
  opts.root,
175
- ".tanstack-start/build/routes-manifest"
175
+ ".tanstack-start/build/route-assets-manifest"
176
176
  );
177
177
  fs.rmSync(routesManifestOutputDirPath, {
178
178
  recursive: true,
@@ -1 +1 @@
1
- {"version":3,"file":"routesManifestPlugin.cjs","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { mkdirSync, readFileSync, rmSync, writeFile } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nconst getCSSRecursively = (\n file: ViteManifestChunk,\n filesByRouteFilePath: ViteManifest,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of file.css ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const imp of file.imports ?? []) {\n const importInfo = filesByRouteFilePath[imp]\n if (importInfo) {\n result.push(\n ...getCSSRecursively(importInfo, filesByRouteFilePath, basePath),\n )\n }\n }\n\n return result\n}\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {}\n })`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/generatedRouteTree.gen.ts`\n const routeTreeRoutes = routerManifest.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = (file.imports ?? []).map((d) => {\n const assetPath = joinURL(APP_BASE, viteManifest[d]!.file)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n if (file.file) {\n preloads.unshift(path.join(APP_BASE, file.file))\n }\n\n const cssAssetsList = getCSSRecursively(\n file,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.file),\n ...(entryFile.imports?.map((d) =>\n joinURL(APP_BASE, viteManifest[d]!.file),\n ) || []),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL(APP_BASE, entryFile.file),\n type: 'module',\n },\n },\n ]\n }\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routeTreeRoutes[rootRouteId])\n\n const routesManifest = {\n routes: routeTreeRoutes,\n }\n\n try {\n const routesManifestOutputDirPath = path.resolve(\n opts.root,\n '.tanstack-start/build/routes-manifest',\n )\n rmSync(routesManifestOutputDirPath, {\n recursive: true,\n force: true,\n })\n mkdirSync(routesManifestOutputDirPath, { recursive: true })\n writeFile(\n path.join(routesManifestOutputDirPath, 'manifest.json'),\n JSON.stringify(routesManifest),\n (err) => {\n if (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n },\n )\n } catch (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n }\n}\n"],"names":["joinURL","resolveViteId","readFileSync","rootRouteId","_a","rmSync","mkdirSync","writeFile"],"mappings":"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"}
1
+ {"version":3,"file":"routesManifestPlugin.cjs","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { mkdirSync, readFileSync, rmSync, writeFile } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nconst getCSSRecursively = (\n file: ViteManifestChunk,\n filesByRouteFilePath: ViteManifest,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of file.css ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const imp of file.imports ?? []) {\n const importInfo = filesByRouteFilePath[imp]\n if (importInfo) {\n result.push(\n ...getCSSRecursively(importInfo, filesByRouteFilePath, basePath),\n )\n }\n }\n\n return result\n}\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {}\n })`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/generatedRouteTree.gen.ts`\n const routeTreeRoutes = routerManifest.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = (file.imports ?? []).map((d) => {\n const assetPath = joinURL(APP_BASE, viteManifest[d]!.file)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n if (file.file) {\n preloads.unshift(path.join(APP_BASE, file.file))\n }\n\n const cssAssetsList = getCSSRecursively(\n file,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.file),\n ...(entryFile.imports?.map((d) =>\n joinURL(APP_BASE, viteManifest[d]!.file),\n ) || []),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL(APP_BASE, entryFile.file),\n type: 'module',\n },\n },\n ]\n }\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routeTreeRoutes[rootRouteId])\n\n const routesManifest = {\n routes: routeTreeRoutes,\n }\n\n try {\n const routesManifestOutputDirPath = path.resolve(\n opts.root,\n '.tanstack-start/build/route-assets-manifest',\n )\n rmSync(routesManifestOutputDirPath, {\n recursive: true,\n force: true,\n })\n mkdirSync(routesManifestOutputDirPath, { recursive: true })\n writeFile(\n path.join(routesManifestOutputDirPath, 'manifest.json'),\n JSON.stringify(routesManifest),\n (err) => {\n if (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n },\n )\n } catch (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n }\n}\n"],"names":["joinURL","resolveViteId","readFileSync","rootRouteId","_a","rmSync","mkdirSync","writeFile"],"mappings":"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"}
@@ -170,7 +170,7 @@ function startManifestPlugin(opts) {
170
170
  try {
171
171
  const routesManifestOutputDirPath = path.resolve(
172
172
  opts.root,
173
- ".tanstack-start/build/routes-manifest"
173
+ ".tanstack-start/build/route-assets-manifest"
174
174
  );
175
175
  rmSync(routesManifestOutputDirPath, {
176
176
  recursive: true,
@@ -1 +1 @@
1
- {"version":3,"file":"routesManifestPlugin.js","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { mkdirSync, readFileSync, rmSync, writeFile } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nconst getCSSRecursively = (\n file: ViteManifestChunk,\n filesByRouteFilePath: ViteManifest,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of file.css ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const imp of file.imports ?? []) {\n const importInfo = filesByRouteFilePath[imp]\n if (importInfo) {\n result.push(\n ...getCSSRecursively(importInfo, filesByRouteFilePath, basePath),\n )\n }\n }\n\n return result\n}\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {}\n })`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/generatedRouteTree.gen.ts`\n const routeTreeRoutes = routerManifest.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = (file.imports ?? []).map((d) => {\n const assetPath = joinURL(APP_BASE, viteManifest[d]!.file)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n if (file.file) {\n preloads.unshift(path.join(APP_BASE, file.file))\n }\n\n const cssAssetsList = getCSSRecursively(\n file,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.file),\n ...(entryFile.imports?.map((d) =>\n joinURL(APP_BASE, viteManifest[d]!.file),\n ) || []),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL(APP_BASE, entryFile.file),\n type: 'module',\n },\n },\n ]\n }\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routeTreeRoutes[rootRouteId])\n\n const routesManifest = {\n routes: routeTreeRoutes,\n }\n\n try {\n const routesManifestOutputDirPath = path.resolve(\n opts.root,\n '.tanstack-start/build/routes-manifest',\n )\n rmSync(routesManifestOutputDirPath, {\n recursive: true,\n force: true,\n })\n mkdirSync(routesManifestOutputDirPath, { recursive: true })\n writeFile(\n path.join(routesManifestOutputDirPath, 'manifest.json'),\n JSON.stringify(routesManifest),\n (err) => {\n if (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n },\n )\n } catch (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n }\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"routesManifestPlugin.js","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { mkdirSync, readFileSync, rmSync, writeFile } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nconst getCSSRecursively = (\n file: ViteManifestChunk,\n filesByRouteFilePath: ViteManifest,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of file.css ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const imp of file.imports ?? []) {\n const importInfo = filesByRouteFilePath[imp]\n if (importInfo) {\n result.push(\n ...getCSSRecursively(importInfo, filesByRouteFilePath, basePath),\n )\n }\n }\n\n return result\n}\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {}\n })`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/generatedRouteTree.gen.ts`\n const routeTreeRoutes = routerManifest.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = (file.imports ?? []).map((d) => {\n const assetPath = joinURL(APP_BASE, viteManifest[d]!.file)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n if (file.file) {\n preloads.unshift(path.join(APP_BASE, file.file))\n }\n\n const cssAssetsList = getCSSRecursively(\n file,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.file),\n ...(entryFile.imports?.map((d) =>\n joinURL(APP_BASE, viteManifest[d]!.file),\n ) || []),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n filesByRouteFilePath,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL(APP_BASE, entryFile.file),\n type: 'module',\n },\n },\n ]\n }\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routeTreeRoutes[rootRouteId])\n\n const routesManifest = {\n routes: routeTreeRoutes,\n }\n\n try {\n const routesManifestOutputDirPath = path.resolve(\n opts.root,\n '.tanstack-start/build/route-assets-manifest',\n )\n rmSync(routesManifestOutputDirPath, {\n recursive: true,\n force: true,\n })\n mkdirSync(routesManifestOutputDirPath, { recursive: true })\n writeFile(\n path.join(routesManifestOutputDirPath, 'manifest.json'),\n JSON.stringify(routesManifest),\n (err) => {\n if (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n },\n )\n } catch (err) {\n console.error(\n 'There was an error writing the routes manifest to disk.\\nYou can ignore this error. It does not affect the runtime of your application.',\n )\n console.error(err)\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n }\n}\n"],"names":["_a"],"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.121.0-alpha.17",
3
+ "version": "1.121.0-alpha.18",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -64,10 +64,10 @@
64
64
  "xmlbuilder2": "^3.1.1",
65
65
  "zod": "^3.24.2",
66
66
  "@tanstack/router-core": "^1.121.0-alpha.14",
67
- "@tanstack/router-generator": "^1.121.0-alpha.14",
68
- "@tanstack/router-utils": "^1.121.0-alpha.2",
69
67
  "@tanstack/router-plugin": "^1.121.0-alpha.14",
70
- "@tanstack/server-functions-plugin": "^1.121.0-alpha.8"
68
+ "@tanstack/router-utils": "^1.121.0-alpha.2",
69
+ "@tanstack/server-functions-plugin": "^1.121.0-alpha.8",
70
+ "@tanstack/router-generator": "^1.121.0-alpha.14"
71
71
  },
72
72
  "devDependencies": {
73
73
  "vite": "^6.0.0"
@@ -247,7 +247,7 @@ export function startManifestPlugin(
247
247
  try {
248
248
  const routesManifestOutputDirPath = path.resolve(
249
249
  opts.root,
250
- '.tanstack-start/build/routes-manifest',
250
+ '.tanstack-start/build/route-assets-manifest',
251
251
  )
252
252
  rmSync(routesManifestOutputDirPath, {
253
253
  recursive: true,