@tanstack/start-plugin-core 1.121.0-alpha.14 → 1.121.0-alpha.16

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.
@@ -69,7 +69,7 @@ function nitroPlugin(options, getSsrBundle) {
69
69
  await builder.build(serverEnv);
70
70
  const nitroConfig = {
71
71
  dev: false,
72
- // TODO do we need this? should this be made configurable?
72
+ // TODO: do we need this? should this be made configurable?
73
73
  compatibilityDate: "2024-11-19",
74
74
  logLevel: 3,
75
75
  preset: buildPreset,
@@ -83,8 +83,18 @@ function nitroPlugin(options, getSsrBundle) {
83
83
  },
84
84
  prerender: void 0,
85
85
  renderer: plugin.ssrEntryFile,
86
+ plugins: [],
87
+ // Nitro's plugins
88
+ appConfigFiles: [],
89
+ scanDirs: [],
90
+ imports: false,
91
+ // unjs/unimport for global/magic imports
86
92
  rollupConfig: {
87
93
  plugins: [virtualBundlePlugin(getSsrBundle())]
94
+ },
95
+ virtual: {
96
+ // This is Nitro's way of defining virtual modules
97
+ // Should we define the ones for TanStack Start's here as well?
88
98
  }
89
99
  };
90
100
  const nitro = await nitropack.createNitro(nitroConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"nitro-plugin.cjs","sources":["../../../src/nitro/nitro-plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { rmSync } from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport { build, copyPublicAssets, createNitro, prepare } from 'nitropack'\nimport { dirname, resolve } from 'pathe'\nimport { clientDistDir, ssrEntryFile } from '../plugin'\nimport { prerender } from '../prerender'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { buildSitemap } from '../build-sitemap'\nimport { devServerPlugin } from './dev-server-plugin'\nimport type {\n EnvironmentOptions,\n PluginOption,\n Rollup,\n ViteBuilder,\n} from 'vite'\nimport type { Nitro, NitroConfig } from 'nitropack'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport function nitroPlugin(\n options: TanStackStartOutputConfig,\n getSsrBundle: () => Rollup.OutputBundle,\n): Array<PluginOption> {\n const buildPreset =\n process.env['START_TARGET'] ?? (options.target as string | undefined)\n\n return [\n devServerPlugin(),\n {\n name: 'tanstack-vite-plugin-nitro',\n configEnvironment(name) {\n if (name === VITE_ENVIRONMENT_NAMES.server) {\n return {\n build: {\n commonjsOptions: {\n include: [],\n },\n ssr: true,\n sourcemap: true,\n rollupOptions: {\n input: '/~start/server-entry',\n },\n },\n } satisfies EnvironmentOptions\n }\n\n return null\n },\n config() {\n return {\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const clientEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const serverEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!clientEnv) {\n throw new Error('Client environment not found')\n }\n\n if (!serverEnv) {\n throw new Error('SSR environment not found')\n }\n\n const clientOutputDir = resolve(options.root, clientDistDir)\n rmSync(clientOutputDir, { recursive: true, force: true })\n await builder.build(clientEnv)\n\n await builder.build(serverEnv)\n\n const nitroConfig: NitroConfig = {\n dev: false,\n // TODO do we need this? should this be made configurable?\n compatibilityDate: '2024-11-19',\n logLevel: 3,\n preset: buildPreset,\n publicAssets: [\n {\n dir: path.resolve(options.root, clientDistDir),\n },\n ],\n typescript: {\n generateTsConfig: false,\n },\n prerender: undefined,\n renderer: ssrEntryFile,\n rollupConfig: {\n plugins: [virtualBundlePlugin(getSsrBundle())],\n },\n }\n\n const nitro = await createNitro(nitroConfig)\n\n await buildNitroApp(builder, nitro, options)\n },\n },\n }\n },\n },\n ]\n}\n\n/**\n * Correctly co-ordinates the nitro app build process to make sure that the\n * app is built, while also correctly handling the prerendering and sitemap\n * generation and including their outputs in the final build.\n */\nasync function buildNitroApp(\n builder: ViteBuilder,\n nitro: Nitro,\n options: TanStackStartOutputConfig,\n) {\n // Cleans the public and server directories for a fresh build\n // i.e the `.output/public` and `.output/server` directories\n await prepare(nitro)\n\n // Creates the `.output/public` directory and copies the public assets\n await copyPublicAssets(nitro)\n\n // If the user has not set a prerender option, we need to set it to true\n // if the pages array is not empty and has sub options requiring for prerendering\n if (options.prerender?.enabled !== false) {\n options.prerender = {\n ...options.prerender,\n enabled: options.pages.some((d) =>\n typeof d === 'string' ? false : !!d.prerender?.enabled,\n ),\n }\n }\n\n // Setup the options for prerendering the SPA shell (i.e `src/routes/__root.tsx`)\n if (options.spa?.enabled) {\n options.prerender = {\n ...options.prerender,\n enabled: true,\n }\n\n const maskUrl = new URL(options.spa.maskPath, 'http://localhost')\n\n maskUrl.searchParams.set('__TSS_SHELL', 'true')\n\n options.pages.push({\n path: maskUrl.toString().replace('http://localhost', ''),\n prerender: options.spa.prerender,\n sitemap: {\n exclude: true,\n },\n })\n }\n\n // Run the prerendering process\n if (options.prerender.enabled) {\n await prerender({\n options,\n nitro,\n builder,\n })\n }\n\n // Run the sitemap build process\n if (options.pages.length) {\n buildSitemap({\n options,\n publicDir: nitro.options.output.publicDir,\n })\n }\n\n // Build the nitro app\n await build(nitro)\n\n // Cleanup the vite public directory\n // As a part of the build process, a `.vite/` directory\n // is copied over from `.tanstack-start/build/client-dist/`\n // to the nitro `publicDir` (e.g. `.output/public/`).\n // This directory (and its contents including the vite client manifest)\n // should not be included in the final build, so we remove it.\n const nitroPublicDir = nitro.options.output.publicDir\n const viteDir = path.resolve(nitroPublicDir, '.vite')\n if (await fsp.stat(viteDir).catch(() => false)) {\n await fsp.rm(viteDir, { recursive: true, force: true })\n }\n\n // Close the nitro instance\n await nitro.close()\n nitro.logger.success(\n 'Client and Server bundles for TanStack Start have been successfully built.',\n )\n}\n\nfunction virtualBundlePlugin(ssrBundle: Rollup.OutputBundle): Rollup.Plugin {\n type VirtualModule = { code: string; map: string | null }\n const _modules = new Map<string, VirtualModule>()\n\n // group chunks and source maps\n for (const [fileName, content] of Object.entries(ssrBundle)) {\n if (content.type === 'chunk') {\n const virtualModule: VirtualModule = {\n code: content.code,\n map: null,\n }\n const maybeMap = ssrBundle[`${fileName}.map`]\n if (maybeMap && maybeMap.type === 'asset') {\n virtualModule.map = maybeMap.source as string\n }\n _modules.set(fileName, virtualModule)\n _modules.set(resolve(fileName), virtualModule)\n }\n }\n\n return {\n name: 'virtual-bundle',\n resolveId(id, importer) {\n if (_modules.has(id)) {\n return resolve(id)\n }\n\n if (importer) {\n const resolved = resolve(dirname(importer), id)\n if (_modules.has(resolved)) {\n return resolved\n }\n }\n return null\n },\n load(id) {\n const m = _modules.get(id)\n if (!m) {\n return null\n }\n return m\n },\n }\n}\n"],"names":["devServerPlugin","VITE_ENVIRONMENT_NAMES","resolve","clientDistDir","rmSync","ssrEntryFile","createNitro","prepare","copyPublicAssets","_a","prerender","buildSitemap","build","fsp","dirname"],"mappings":"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"}
1
+ {"version":3,"file":"nitro-plugin.cjs","sources":["../../../src/nitro/nitro-plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { rmSync } from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport { build, copyPublicAssets, createNitro, prepare } from 'nitropack'\nimport { dirname, resolve } from 'pathe'\nimport { clientDistDir, ssrEntryFile } from '../plugin'\nimport { prerender } from '../prerender'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { buildSitemap } from '../build-sitemap'\nimport { devServerPlugin } from './dev-server-plugin'\nimport type {\n EnvironmentOptions,\n PluginOption,\n Rollup,\n ViteBuilder,\n} from 'vite'\nimport type { Nitro, NitroConfig } from 'nitropack'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport function nitroPlugin(\n options: TanStackStartOutputConfig,\n getSsrBundle: () => Rollup.OutputBundle,\n): Array<PluginOption> {\n const buildPreset =\n process.env['START_TARGET'] ?? (options.target as string | undefined)\n\n return [\n devServerPlugin(),\n {\n name: 'tanstack-vite-plugin-nitro',\n configEnvironment(name) {\n if (name === VITE_ENVIRONMENT_NAMES.server) {\n return {\n build: {\n commonjsOptions: {\n include: [],\n },\n ssr: true,\n sourcemap: true,\n rollupOptions: {\n input: '/~start/server-entry',\n },\n },\n } satisfies EnvironmentOptions\n }\n\n return null\n },\n config() {\n return {\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const clientEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const serverEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!clientEnv) {\n throw new Error('Client environment not found')\n }\n\n if (!serverEnv) {\n throw new Error('SSR environment not found')\n }\n\n const clientOutputDir = resolve(options.root, clientDistDir)\n rmSync(clientOutputDir, { recursive: true, force: true })\n await builder.build(clientEnv)\n\n await builder.build(serverEnv)\n\n const nitroConfig: NitroConfig = {\n dev: false,\n // TODO: do we need this? should this be made configurable?\n compatibilityDate: '2024-11-19',\n logLevel: 3,\n preset: buildPreset,\n publicAssets: [\n {\n dir: path.resolve(options.root, clientDistDir),\n },\n ],\n typescript: {\n generateTsConfig: false,\n },\n prerender: undefined,\n renderer: ssrEntryFile,\n plugins: [], // Nitro's plugins\n appConfigFiles: [],\n scanDirs: [],\n imports: false, // unjs/unimport for global/magic imports\n rollupConfig: {\n plugins: [virtualBundlePlugin(getSsrBundle())],\n },\n virtual: {\n // This is Nitro's way of defining virtual modules\n // Should we define the ones for TanStack Start's here as well?\n },\n }\n\n const nitro = await createNitro(nitroConfig)\n\n await buildNitroApp(builder, nitro, options)\n },\n },\n }\n },\n },\n ]\n}\n\n/**\n * Correctly co-ordinates the nitro app build process to make sure that the\n * app is built, while also correctly handling the prerendering and sitemap\n * generation and including their outputs in the final build.\n */\nasync function buildNitroApp(\n builder: ViteBuilder,\n nitro: Nitro,\n options: TanStackStartOutputConfig,\n) {\n // Cleans the public and server directories for a fresh build\n // i.e the `.output/public` and `.output/server` directories\n await prepare(nitro)\n\n // Creates the `.output/public` directory and copies the public assets\n await copyPublicAssets(nitro)\n\n // If the user has not set a prerender option, we need to set it to true\n // if the pages array is not empty and has sub options requiring for prerendering\n if (options.prerender?.enabled !== false) {\n options.prerender = {\n ...options.prerender,\n enabled: options.pages.some((d) =>\n typeof d === 'string' ? false : !!d.prerender?.enabled,\n ),\n }\n }\n\n // Setup the options for prerendering the SPA shell (i.e `src/routes/__root.tsx`)\n if (options.spa?.enabled) {\n options.prerender = {\n ...options.prerender,\n enabled: true,\n }\n\n const maskUrl = new URL(options.spa.maskPath, 'http://localhost')\n\n maskUrl.searchParams.set('__TSS_SHELL', 'true')\n\n options.pages.push({\n path: maskUrl.toString().replace('http://localhost', ''),\n prerender: options.spa.prerender,\n sitemap: {\n exclude: true,\n },\n })\n }\n\n // Run the prerendering process\n if (options.prerender.enabled) {\n await prerender({\n options,\n nitro,\n builder,\n })\n }\n\n // Run the sitemap build process\n if (options.pages.length) {\n buildSitemap({\n options,\n publicDir: nitro.options.output.publicDir,\n })\n }\n\n // Build the nitro app\n await build(nitro)\n\n // Cleanup the vite public directory\n // As a part of the build process, a `.vite/` directory\n // is copied over from `.tanstack-start/build/client-dist/`\n // to the nitro `publicDir` (e.g. `.output/public/`).\n // This directory (and its contents including the vite client manifest)\n // should not be included in the final build, so we remove it.\n const nitroPublicDir = nitro.options.output.publicDir\n const viteDir = path.resolve(nitroPublicDir, '.vite')\n if (await fsp.stat(viteDir).catch(() => false)) {\n await fsp.rm(viteDir, { recursive: true, force: true })\n }\n\n // Close the nitro instance\n await nitro.close()\n nitro.logger.success(\n 'Client and Server bundles for TanStack Start have been successfully built.',\n )\n}\n\nfunction virtualBundlePlugin(ssrBundle: Rollup.OutputBundle): Rollup.Plugin {\n type VirtualModule = { code: string; map: string | null }\n const _modules = new Map<string, VirtualModule>()\n\n // group chunks and source maps\n for (const [fileName, content] of Object.entries(ssrBundle)) {\n if (content.type === 'chunk') {\n const virtualModule: VirtualModule = {\n code: content.code,\n map: null,\n }\n const maybeMap = ssrBundle[`${fileName}.map`]\n if (maybeMap && maybeMap.type === 'asset') {\n virtualModule.map = maybeMap.source as string\n }\n _modules.set(fileName, virtualModule)\n _modules.set(resolve(fileName), virtualModule)\n }\n }\n\n return {\n name: 'virtual-bundle',\n resolveId(id, importer) {\n if (_modules.has(id)) {\n return resolve(id)\n }\n\n if (importer) {\n const resolved = resolve(dirname(importer), id)\n if (_modules.has(resolved)) {\n return resolved\n }\n }\n return null\n },\n load(id) {\n const m = _modules.get(id)\n if (!m) {\n return null\n }\n return m\n },\n }\n}\n"],"names":["devServerPlugin","VITE_ENVIRONMENT_NAMES","resolve","clientDistDir","rmSync","ssrEntryFile","createNitro","prepare","copyPublicAssets","_a","prerender","buildSitemap","build","fsp","dirname"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmBgB,SAAA,YACd,SACA,cACqB;AACrB,QAAM,cACJ,QAAQ,IAAI,cAAc,KAAM,QAAQ;AAEnC,SAAA;AAAA,IACLA,gCAAgB;AAAA,IAChB;AAAA,MACE,MAAM;AAAA,MACN,kBAAkB,MAAM;AAClB,YAAA,SAASC,iCAAuB,QAAQ;AACnC,iBAAA;AAAA,YACL,OAAO;AAAA,cACL,iBAAiB;AAAA,gBACf,SAAS,CAAA;AAAA,cACX;AAAA,cACA,KAAK;AAAA,cACL,WAAW;AAAA,cACX,eAAe;AAAA,gBACb,OAAO;AAAA,cAAA;AAAA,YACT;AAAA,UAEJ;AAAA,QAAA;AAGK,eAAA;AAAA,MACT;AAAA,MACA,SAAS;AACA,eAAA;AAAA,UACL,SAAS;AAAA,YACP,eAAe;AAAA,YACf,MAAM,SAAS,SAAS;AACtB,oBAAM,YACJ,QAAQ,aAAaA,UAAAA,uBAAuB,MAAM;AACpD,oBAAM,YACJ,QAAQ,aAAaA,UAAAA,uBAAuB,MAAM;AAEpD,kBAAI,CAAC,WAAW;AACR,sBAAA,IAAI,MAAM,8BAA8B;AAAA,cAAA;AAGhD,kBAAI,CAAC,WAAW;AACR,sBAAA,IAAI,MAAM,2BAA2B;AAAA,cAAA;AAG7C,oBAAM,kBAAkBC,MAAA,QAAQ,QAAQ,MAAMC,OAAAA,aAAa;AAC3DC,iBAAA,OAAO,iBAAiB,EAAE,WAAW,MAAM,OAAO,MAAM;AAClD,oBAAA,QAAQ,MAAM,SAAS;AAEvB,oBAAA,QAAQ,MAAM,SAAS;AAE7B,oBAAM,cAA2B;AAAA,gBAC/B,KAAK;AAAA;AAAA,gBAEL,mBAAmB;AAAA,gBACnB,UAAU;AAAA,gBACV,QAAQ;AAAA,gBACR,cAAc;AAAA,kBACZ;AAAA,oBACE,KAAK,KAAK,QAAQ,QAAQ,MAAMD,OAAa,aAAA;AAAA,kBAAA;AAAA,gBAEjD;AAAA,gBACA,YAAY;AAAA,kBACV,kBAAkB;AAAA,gBACpB;AAAA,gBACA,WAAW;AAAA,gBACX,UAAUE,OAAA;AAAA,gBACV,SAAS,CAAC;AAAA;AAAA,gBACV,gBAAgB,CAAC;AAAA,gBACjB,UAAU,CAAC;AAAA,gBACX,SAAS;AAAA;AAAA,gBACT,cAAc;AAAA,kBACZ,SAAS,CAAC,oBAAoB,cAAc,CAAC;AAAA,gBAC/C;AAAA,gBACA,SAAS;AAAA;AAAA;AAAA,gBAAA;AAAA,cAIX;AAEM,oBAAA,QAAQ,MAAMC,UAAA,YAAY,WAAW;AAErC,oBAAA,cAAc,SAAS,OAAO,OAAO;AAAA,YAAA;AAAA,UAC7C;AAAA,QAEJ;AAAA,MAAA;AAAA,IACF;AAAA,EAEJ;AACF;AAOA,eAAe,cACb,SACA,OACA,SACA;;AAGA,QAAMC,UAAAA,QAAQ,KAAK;AAGnB,QAAMC,UAAAA,iBAAiB,KAAK;AAIxB,QAAA,aAAQ,cAAR,mBAAmB,aAAY,OAAO;AACxC,YAAQ,YAAY;AAAA,MAClB,GAAG,QAAQ;AAAA,MACX,SAAS,QAAQ,MAAM;AAAA,QAAK,CAAC,MAC3B;;AAAA,wBAAO,MAAM,WAAW,QAAQ,CAAC,GAACC,MAAA,EAAE,cAAF,gBAAAA,IAAa;AAAA;AAAA,MAAA;AAAA,IAEnD;AAAA,EAAA;AAIE,OAAA,aAAQ,QAAR,mBAAa,SAAS;AACxB,YAAQ,YAAY;AAAA,MAClB,GAAG,QAAQ;AAAA,MACX,SAAS;AAAA,IACX;AAEA,UAAM,UAAU,IAAI,IAAI,QAAQ,IAAI,UAAU,kBAAkB;AAExD,YAAA,aAAa,IAAI,eAAe,MAAM;AAE9C,YAAQ,MAAM,KAAK;AAAA,MACjB,MAAM,QAAQ,SAAA,EAAW,QAAQ,oBAAoB,EAAE;AAAA,MACvD,WAAW,QAAQ,IAAI;AAAA,MACvB,SAAS;AAAA,QACP,SAAS;AAAA,MAAA;AAAA,IACX,CACD;AAAA,EAAA;AAIC,MAAA,QAAQ,UAAU,SAAS;AAC7B,UAAMC,oBAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,IAAA,CACD;AAAA,EAAA;AAIC,MAAA,QAAQ,MAAM,QAAQ;AACXC,8BAAA;AAAA,MACX;AAAA,MACA,WAAW,MAAM,QAAQ,OAAO;AAAA,IAAA,CACjC;AAAA,EAAA;AAIH,QAAMC,UAAAA,MAAM,KAAK;AAQX,QAAA,iBAAiB,MAAM,QAAQ,OAAO;AAC5C,QAAM,UAAU,KAAK,QAAQ,gBAAgB,OAAO;AAChD,MAAA,MAAMC,eAAI,KAAK,OAAO,EAAE,MAAM,MAAM,KAAK,GAAG;AACxC,UAAAA,eAAI,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,MAAM;AAAA,EAAA;AAIxD,QAAM,MAAM,MAAM;AAClB,QAAM,OAAO;AAAA,IACX;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,WAA+C;AAEpE,QAAA,+BAAe,IAA2B;AAGhD,aAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,SAAS,GAAG;AACvD,QAAA,QAAQ,SAAS,SAAS;AAC5B,YAAM,gBAA+B;AAAA,QACnC,MAAM,QAAQ;AAAA,QACd,KAAK;AAAA,MACP;AACA,YAAM,WAAW,UAAU,GAAG,QAAQ,MAAM;AACxC,UAAA,YAAY,SAAS,SAAS,SAAS;AACzC,sBAAc,MAAM,SAAS;AAAA,MAAA;AAEtB,eAAA,IAAI,UAAU,aAAa;AACpC,eAAS,IAAIX,MAAAA,QAAQ,QAAQ,GAAG,aAAa;AAAA,IAAA;AAAA,EAC/C;AAGK,SAAA;AAAA,IACL,MAAM;AAAA,IACN,UAAU,IAAI,UAAU;AAClB,UAAA,SAAS,IAAI,EAAE,GAAG;AACpB,eAAOA,MAAAA,QAAQ,EAAE;AAAA,MAAA;AAGnB,UAAI,UAAU;AACZ,cAAM,WAAWA,MAAA,QAAQY,MAAQ,QAAA,QAAQ,GAAG,EAAE;AAC1C,YAAA,SAAS,IAAI,QAAQ,GAAG;AACnB,iBAAA;AAAA,QAAA;AAAA,MACT;AAEK,aAAA;AAAA,IACT;AAAA,IACA,KAAK,IAAI;AACD,YAAA,IAAI,SAAS,IAAI,EAAE;AACzB,UAAI,CAAC,GAAG;AACC,eAAA;AAAA,MAAA;AAEF,aAAA;AAAA,IAAA;AAAA,EAEX;AACF;;"}
@@ -205,16 +205,16 @@ function resolveVirtualEntriesPlugin(opts, startConfig) {
205
205
  ) ? startConfig.serverEntryPath : vite__namespace.normalizePath(
206
206
  path.resolve(resolvedConfig.root, startConfig.serverEntryPath)
207
207
  );
208
- return opts.getVirtualServerHandlerEntry({
208
+ return opts.getVirtualServerRootHandler({
209
209
  routerFilepath,
210
- ssrEntryFilepath
210
+ serverEntryFilepath: ssrEntryFilepath
211
211
  });
212
212
  }
213
213
  if (id === "/~start/default-client-entry.tsx") {
214
214
  return opts.getVirtualClientEntry({ routerFilepath });
215
215
  }
216
216
  if (id === "/~start/default-server-entry.tsx") {
217
- return opts.getVirtualSsrEntry({ routerFilepath });
217
+ return opts.getVirtualServerEntry({ routerFilepath });
218
218
  }
219
219
  return void 0;
220
220
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport {\n createTanStackConfig,\n createTanStackStartOptionsSchema,\n} from './schema'\nimport { nitroPlugin } from './nitro/nitro-plugin'\nimport { startManifestPlugin } from './routesManifestPlugin'\nimport { TanStackStartCompilerPlugin } from './start-compiler-plugin'\nimport { VITE_ENVIRONMENT_NAMES } from './constants'\nimport { TanStackStartServerRoutesVite } from './start-server-routes-plugin/plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nconst TanStackStartOptionsSchema = createTanStackStartOptionsSchema()\nexport type TanStackStartInputConfig = z.input<\n typeof TanStackStartOptionsSchema\n>\n\nconst defaultConfig = createTanStackConfig()\nexport function getTanStackStartOptions(opts?: TanStackStartInputConfig) {\n return defaultConfig.parse(opts)\n}\n\nexport type TanStackStartOutputConfig = ReturnType<\n typeof getTanStackStartOptions\n>\n\nexport const clientDistDir = '.tanstack-start/build/client-dist'\nexport const ssrEntryFile = 'ssr.mjs'\n\nexport interface TanStackStartVitePluginCoreOptions {\n framework: CompileStartFrameworkOptions\n getVirtualServerHandlerEntry: (ctx: {\n routerFilepath: string\n ssrEntryFilepath: string\n }) => string\n getVirtualSsrEntry: (ctx: { routerFilepath: string }) => string\n getVirtualClientEntry: (ctx: { routerFilepath: string }) => string\n}\n// this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite\nlet ssrBundle: Rollup.OutputBundle\n\nexport function TanStackStartVitePluginCore(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): Array<PluginOption> {\n return [\n tanstackRouter({\n verboseFileRoutes: false,\n ...startConfig.tsr,\n target: opts.framework,\n enableRouteGeneration: true,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config() {\n const nitroOutputPublicDir = await (async () => {\n // Create a dummy nitro app to get the resolved public output path\n const dummyNitroApp = await createNitro({\n preset: startConfig.target,\n compatibilityDate: '2024-12-01',\n })\n\n const nitroOutputPublicDir = dummyNitroApp.options.output.publicDir\n await dummyNitroApp.close()\n\n return nitroOutputPublicDir\n })()\n\n const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {\n // when the user specifies a custom client entry path, we need to resolve it\n // relative to the root of the project, keeping in mind that if not specified\n // it will be /~start/default-client-entry which is a virtual path\n // that is resolved by vite to the actual client entry path\n const entry = startConfig.clientEntryPath.startsWith(\n '/~start/default-client-entry',\n )\n ? startConfig.clientEntryPath\n : vite.normalizePath(\n path.join(\n '/@fs',\n path.resolve(startConfig.root, startConfig.clientEntryPath),\n ),\n )\n\n return entry\n }\n\n return {\n environments: {\n [VITE_ENVIRONMENT_NAMES.client]: {\n consumer: 'client',\n build: {\n manifest: true,\n rollupOptions: {\n input: {\n main: getClientEntryPath(startConfig),\n },\n output: {\n dir: path.resolve(startConfig.root, clientDistDir),\n },\n // TODO this should be removed\n external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],\n },\n },\n },\n [VITE_ENVIRONMENT_NAMES.server]: {\n consumer: 'server',\n build: {\n ssr: true,\n // we don't write to the file system as the below 'capture-output' plugin will\n // capture the output and write it to the virtual file system\n write: false,\n copyPublicDir: false,\n rollupOptions: {\n output: {\n entryFileNames: ssrEntryFile,\n },\n plugins: [\n {\n name: 'capture-output',\n generateBundle(options, bundle) {\n // TODO can this hook be called more than once?\n ssrBundle = bundle\n },\n },\n ],\n },\n commonjsOptions: {\n include: [/node_modules/],\n },\n },\n },\n },\n resolve: {\n noExternal: [\n '@tanstack/start-client',\n '@tanstack/start-client-core',\n '@tanstack/start-server',\n '@tanstack/start-server-core',\n '@tanstack/start-server-functions-fetcher',\n '@tanstack/start-server-functions-client',\n '@tanstack/start-server-functions-server',\n '@tanstack/start-router-manifest',\n '@tanstack/start-config',\n '@tanstack/server-functions-plugin',\n 'tanstack-start-router-manifest:v',\n 'tanstack-start-server-fn-manifest:v',\n 'nitropack',\n '@tanstack/**',\n ],\n },\n /* prettier-ignore */\n define: {\n ...injectDefineEnv('TSS_PUBLIC_BASE', startConfig.public.base),\n ...injectDefineEnv('TSS_CLIENT_BASE', startConfig.client.base),\n ...injectDefineEnv('TSS_CLIENT_ENTRY', getClientEntryPath(startConfig)), // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved\n ...injectDefineEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...injectDefineEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n TanStackStartCompilerPlugin(opts.framework, {\n client: { envName: VITE_ENVIRONMENT_NAMES.client },\n server: { envName: VITE_ENVIRONMENT_NAMES.server },\n }),\n TanStackServerFnPluginEnv({\n // This is the ID that will be available to look up and import\n // our server function manifest and resolve its module\n manifestVirtualImportId: 'tanstack-start-server-fn-manifest:v',\n manifestOutputFilename:\n '.tanstack-start/build/server/server-functions-manifest.json',\n client: {\n getRuntimeCode: () =>\n `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,\n replacer: (d) =>\n `createClientRpc('${d.functionId}', '${startConfig.serverFns.base}')`,\n envName: VITE_ENVIRONMENT_NAMES.client,\n },\n server: {\n getRuntimeCode: () =>\n `import { createServerRpc } from '@tanstack/${opts.framework}-start/server-functions-server'`,\n replacer: (d) =>\n `createServerRpc('${d.functionId}', '${startConfig.serverFns.base}', ${d.fn})`,\n envName: VITE_ENVIRONMENT_NAMES.server,\n },\n importer: (fn) => {\n const serverEnv = (globalThis as any).viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ]\n if (!serverEnv) {\n throw new Error(`'ssr' vite dev environment not found`)\n }\n return serverEnv.runner.import(fn.extractedFilename)\n },\n }),\n startManifestPlugin(startConfig),\n nitroPlugin(startConfig, () => ssrBundle),\n TanStackStartServerRoutesVite({\n ...startConfig.tsr,\n target: opts.framework,\n }),\n ]\n}\n\nfunction resolveVirtualEntriesPlugin(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): PluginOption {\n let resolvedConfig: vite.ResolvedConfig\n\n const modules = new Set<string>([\n '/~start/server-entry',\n '/~start/default-server-entry',\n '/~start/default-client-entry',\n ])\n\n return {\n name: 'tanstack-start-core:resolve-virtual-entries',\n configResolved(config) {\n resolvedConfig = config\n },\n resolveId(id) {\n if (modules.has(id)) {\n return `${id}.tsx`\n }\n\n return undefined\n },\n load(id) {\n const routerFilepath = vite.normalizePath(\n path.resolve(startConfig.root, startConfig.tsr.srcDirectory, 'router'),\n )\n\n if (id === '/~start/server-entry.tsx') {\n const ssrEntryFilepath = startConfig.serverEntryPath.startsWith(\n '/~start/default-server-entry',\n )\n ? startConfig.serverEntryPath\n : vite.normalizePath(\n path.resolve(resolvedConfig.root, startConfig.serverEntryPath),\n )\n\n return opts.getVirtualServerHandlerEntry({\n routerFilepath,\n ssrEntryFilepath,\n })\n }\n\n if (id === '/~start/default-client-entry.tsx') {\n return opts.getVirtualClientEntry({ routerFilepath })\n }\n\n if (id === '/~start/default-server-entry.tsx') {\n return opts.getVirtualSsrEntry({ routerFilepath })\n }\n\n return undefined\n },\n }\n}\n\nfunction injectDefineEnv<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":["createTanStackStartOptionsSchema","createTanStackConfig","tanstackRouter","createNitro","nitroOutputPublicDir","startConfig","vite","VITE_ENVIRONMENT_NAMES","TanStackStartCompilerPlugin","TanStackServerFnPluginEnv","startManifestPlugin","nitroPlugin","TanStackStartServerRoutesVite"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.cjs","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport {\n createTanStackConfig,\n createTanStackStartOptionsSchema,\n} from './schema'\nimport { nitroPlugin } from './nitro/nitro-plugin'\nimport { startManifestPlugin } from './routesManifestPlugin'\nimport { TanStackStartCompilerPlugin } from './start-compiler-plugin'\nimport { VITE_ENVIRONMENT_NAMES } from './constants'\nimport { TanStackStartServerRoutesVite } from './start-server-routes-plugin/plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nconst TanStackStartOptionsSchema = createTanStackStartOptionsSchema()\nexport type TanStackStartInputConfig = z.input<\n typeof TanStackStartOptionsSchema\n>\n\nconst defaultConfig = createTanStackConfig()\nexport function getTanStackStartOptions(opts?: TanStackStartInputConfig) {\n return defaultConfig.parse(opts)\n}\n\nexport type TanStackStartOutputConfig = ReturnType<\n typeof getTanStackStartOptions\n>\n\nexport const clientDistDir = '.tanstack-start/build/client-dist'\nexport const ssrEntryFile = 'ssr.mjs'\n\nexport interface TanStackStartVitePluginCoreOptions {\n framework: CompileStartFrameworkOptions\n getVirtualServerRootHandler: (ctx: {\n routerFilepath: string\n serverEntryFilepath: string\n }) => string\n getVirtualServerEntry: (ctx: { routerFilepath: string }) => string\n getVirtualClientEntry: (ctx: { routerFilepath: string }) => string\n}\n// this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite\nlet ssrBundle: Rollup.OutputBundle\n\nexport function TanStackStartVitePluginCore(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): Array<PluginOption> {\n return [\n tanstackRouter({\n verboseFileRoutes: false,\n ...startConfig.tsr,\n target: opts.framework,\n enableRouteGeneration: true,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config() {\n const nitroOutputPublicDir = await (async () => {\n // Create a dummy nitro app to get the resolved public output path\n const dummyNitroApp = await createNitro({\n preset: startConfig.target,\n compatibilityDate: '2024-12-01',\n })\n\n const nitroOutputPublicDir = dummyNitroApp.options.output.publicDir\n await dummyNitroApp.close()\n\n return nitroOutputPublicDir\n })()\n\n const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {\n // when the user specifies a custom client entry path, we need to resolve it\n // relative to the root of the project, keeping in mind that if not specified\n // it will be /~start/default-client-entry which is a virtual path\n // that is resolved by vite to the actual client entry path\n const entry = startConfig.clientEntryPath.startsWith(\n '/~start/default-client-entry',\n )\n ? startConfig.clientEntryPath\n : vite.normalizePath(\n path.join(\n '/@fs',\n path.resolve(startConfig.root, startConfig.clientEntryPath),\n ),\n )\n\n return entry\n }\n\n return {\n environments: {\n [VITE_ENVIRONMENT_NAMES.client]: {\n consumer: 'client',\n build: {\n manifest: true,\n rollupOptions: {\n input: {\n main: getClientEntryPath(startConfig),\n },\n output: {\n dir: path.resolve(startConfig.root, clientDistDir),\n },\n // TODO this should be removed\n external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],\n },\n },\n },\n [VITE_ENVIRONMENT_NAMES.server]: {\n consumer: 'server',\n build: {\n ssr: true,\n // we don't write to the file system as the below 'capture-output' plugin will\n // capture the output and write it to the virtual file system\n write: false,\n copyPublicDir: false,\n rollupOptions: {\n output: {\n entryFileNames: ssrEntryFile,\n },\n plugins: [\n {\n name: 'capture-output',\n generateBundle(options, bundle) {\n // TODO can this hook be called more than once?\n ssrBundle = bundle\n },\n },\n ],\n },\n commonjsOptions: {\n include: [/node_modules/],\n },\n },\n },\n },\n resolve: {\n noExternal: [\n '@tanstack/start-client',\n '@tanstack/start-client-core',\n '@tanstack/start-server',\n '@tanstack/start-server-core',\n '@tanstack/start-server-functions-fetcher',\n '@tanstack/start-server-functions-client',\n '@tanstack/start-server-functions-server',\n '@tanstack/start-router-manifest',\n '@tanstack/start-config',\n '@tanstack/server-functions-plugin',\n 'tanstack-start-router-manifest:v',\n 'tanstack-start-server-fn-manifest:v',\n 'nitropack',\n '@tanstack/**',\n ],\n },\n /* prettier-ignore */\n define: {\n ...injectDefineEnv('TSS_PUBLIC_BASE', startConfig.public.base),\n ...injectDefineEnv('TSS_CLIENT_BASE', startConfig.client.base),\n ...injectDefineEnv('TSS_CLIENT_ENTRY', getClientEntryPath(startConfig)), // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved\n ...injectDefineEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...injectDefineEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n TanStackStartCompilerPlugin(opts.framework, {\n client: { envName: VITE_ENVIRONMENT_NAMES.client },\n server: { envName: VITE_ENVIRONMENT_NAMES.server },\n }),\n TanStackServerFnPluginEnv({\n // This is the ID that will be available to look up and import\n // our server function manifest and resolve its module\n manifestVirtualImportId: 'tanstack-start-server-fn-manifest:v',\n manifestOutputFilename:\n '.tanstack-start/build/server/server-functions-manifest.json',\n client: {\n getRuntimeCode: () =>\n `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,\n replacer: (d) =>\n `createClientRpc('${d.functionId}', '${startConfig.serverFns.base}')`,\n envName: VITE_ENVIRONMENT_NAMES.client,\n },\n server: {\n getRuntimeCode: () =>\n `import { createServerRpc } from '@tanstack/${opts.framework}-start/server-functions-server'`,\n replacer: (d) =>\n `createServerRpc('${d.functionId}', '${startConfig.serverFns.base}', ${d.fn})`,\n envName: VITE_ENVIRONMENT_NAMES.server,\n },\n importer: (fn) => {\n const serverEnv = (globalThis as any).viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ]\n if (!serverEnv) {\n throw new Error(`'ssr' vite dev environment not found`)\n }\n return serverEnv.runner.import(fn.extractedFilename)\n },\n }),\n startManifestPlugin(startConfig),\n nitroPlugin(startConfig, () => ssrBundle),\n TanStackStartServerRoutesVite({\n ...startConfig.tsr,\n target: opts.framework,\n }),\n ]\n}\n\nfunction resolveVirtualEntriesPlugin(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): PluginOption {\n let resolvedConfig: vite.ResolvedConfig\n\n const modules = new Set<string>([\n '/~start/server-entry',\n '/~start/default-server-entry',\n '/~start/default-client-entry',\n ])\n\n return {\n name: 'tanstack-start-core:resolve-virtual-entries',\n configResolved(config) {\n resolvedConfig = config\n },\n resolveId(id) {\n if (modules.has(id)) {\n return `${id}.tsx`\n }\n\n return undefined\n },\n load(id) {\n const routerFilepath = vite.normalizePath(\n path.resolve(startConfig.root, startConfig.tsr.srcDirectory, 'router'),\n )\n\n if (id === '/~start/server-entry.tsx') {\n const ssrEntryFilepath = startConfig.serverEntryPath.startsWith(\n '/~start/default-server-entry',\n )\n ? startConfig.serverEntryPath\n : vite.normalizePath(\n path.resolve(resolvedConfig.root, startConfig.serverEntryPath),\n )\n\n return opts.getVirtualServerRootHandler({\n routerFilepath,\n serverEntryFilepath: ssrEntryFilepath,\n })\n }\n\n if (id === '/~start/default-client-entry.tsx') {\n return opts.getVirtualClientEntry({ routerFilepath })\n }\n\n if (id === '/~start/default-server-entry.tsx') {\n return opts.getVirtualServerEntry({ routerFilepath })\n }\n\n return undefined\n },\n }\n}\n\nfunction injectDefineEnv<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":["createTanStackStartOptionsSchema","createTanStackConfig","tanstackRouter","createNitro","nitroOutputPublicDir","startConfig","vite","VITE_ENVIRONMENT_NAMES","TanStackStartCompilerPlugin","TanStackServerFnPluginEnv","startManifestPlugin","nitroPlugin","TanStackStartServerRoutesVite"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBmCA,OAAiC,iCAAA;AAK9CC,OAAqB,qBAAA;AASpC,MAAM,gBAAgB;AACtB,MAAM,eAAe;AAY5B,IAAI;AAEY,SAAA,4BACd,MACA,aACqB;AACd,SAAA;AAAA,IACLC,oBAAe;AAAA,MACb,mBAAmB;AAAA,MACnB,GAAG,YAAY;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,uBAAuB;AAAA,MACvB,mBAAmB;AAAA,IAAA,CACpB;AAAA,IACD,4BAA4B,MAAM,WAAW;AAAA,IAC7C;AAAA,MACE,MAAM;AAAA,MACN,MAAM,SAAS;AACP,cAAA,uBAAuB,OAAO,YAAY;AAExC,gBAAA,gBAAgB,MAAMC,sBAAY;AAAA,YACtC,QAAQ,YAAY;AAAA,YACpB,mBAAmB;AAAA,UAAA,CACpB;AAEKC,gBAAAA,wBAAuB,cAAc,QAAQ,OAAO;AAC1D,gBAAM,cAAc,MAAM;AAEnBA,iBAAAA;AAAAA,QAAAA,GACN;AAEG,cAAA,qBAAqB,CAACC,iBAA2C;AAK/D,gBAAA,QAAQA,aAAY,gBAAgB;AAAA,YACxC;AAAA,UAAA,IAEEA,aAAY,kBACZC,gBAAK;AAAA,YACH,KAAK;AAAA,cACH;AAAA,cACA,KAAK,QAAQD,aAAY,MAAMA,aAAY,eAAe;AAAA,YAAA;AAAA,UAE9D;AAEG,iBAAA;AAAA,QACT;AAEO,eAAA;AAAA,UACL,cAAc;AAAA,YACZ,CAACE,UAAAA,uBAAuB,MAAM,GAAG;AAAA,cAC/B,UAAU;AAAA,cACV,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,eAAe;AAAA,kBACb,OAAO;AAAA,oBACL,MAAM,mBAAmB,WAAW;AAAA,kBACtC;AAAA,kBACA,QAAQ;AAAA,oBACN,KAAK,KAAK,QAAQ,YAAY,MAAM,aAAa;AAAA,kBACnD;AAAA;AAAA,kBAEA,UAAU,CAAC,WAAW,aAAa,WAAW,aAAa;AAAA,gBAAA;AAAA,cAC7D;AAAA,YAEJ;AAAA,YACA,CAACA,UAAAA,uBAAuB,MAAM,GAAG;AAAA,cAC/B,UAAU;AAAA,cACV,OAAO;AAAA,gBACL,KAAK;AAAA;AAAA;AAAA,gBAGL,OAAO;AAAA,gBACP,eAAe;AAAA,gBACf,eAAe;AAAA,kBACb,QAAQ;AAAA,oBACN,gBAAgB;AAAA,kBAClB;AAAA,kBACA,SAAS;AAAA,oBACP;AAAA,sBACE,MAAM;AAAA,sBACN,eAAe,SAAS,QAAQ;AAElB,oCAAA;AAAA,sBAAA;AAAA,oBACd;AAAA,kBACF;AAAA,gBAEJ;AAAA,gBACA,iBAAiB;AAAA,kBACf,SAAS,CAAC,cAAc;AAAA,gBAAA;AAAA,cAC1B;AAAA,YACF;AAAA,UAEJ;AAAA,UACA,SAAS;AAAA,YACP,YAAY;AAAA,cACV;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAAA;AAAA,UAEA,QAAQ;AAAA,YACN,GAAG,gBAAgB,mBAAmB,YAAY,OAAO,IAAI;AAAA,YAC7D,GAAG,gBAAgB,mBAAmB,YAAY,OAAO,IAAI;AAAA,YAC7D,GAAG,gBAAgB,oBAAoB,mBAAmB,WAAW,CAAC;AAAA;AAAA,YACtE,GAAG,gBAAgB,sBAAsB,YAAY,UAAU,IAAI;AAAA,YACnE,GAAG,gBAAgB,yBAAyB,oBAAoB;AAAA,UAAA;AAAA,QAEpE;AAAA,MAAA;AAAA,IAEJ;AAAA;AAAA,IAEAC,oBAAA,4BAA4B,KAAK,WAAW;AAAA,MAC1C,QAAQ,EAAE,SAASD,UAAA,uBAAuB,OAAO;AAAA,MACjD,QAAQ,EAAE,SAASA,UAAAA,uBAAuB,OAAO;AAAA,IAAA,CAClD;AAAA,IACDE,gDAA0B;AAAA;AAAA;AAAA,MAGxB,yBAAyB;AAAA,MACzB,wBACE;AAAA,MACF,QAAQ;AAAA,QACN,gBAAgB,MACd,8CAA8C,KAAK,SAAS;AAAA,QAC9D,UAAU,CAAC,MACT,oBAAoB,EAAE,UAAU,OAAO,YAAY,UAAU,IAAI;AAAA,QACnE,SAASF,UAAAA,uBAAuB;AAAA,MAClC;AAAA,MACA,QAAQ;AAAA,QACN,gBAAgB,MACd,8CAA8C,KAAK,SAAS;AAAA,QAC9D,UAAU,CAAC,MACT,oBAAoB,EAAE,UAAU,OAAO,YAAY,UAAU,IAAI,MAAM,EAAE,EAAE;AAAA,QAC7E,SAASA,UAAAA,uBAAuB;AAAA,MAClC;AAAA,MACA,UAAU,CAAC,OAAO;AAChB,cAAM,YAAa,WAAmB,cAAc,aAClDA,UAAAA,uBAAuB,MACzB;AACA,YAAI,CAAC,WAAW;AACR,gBAAA,IAAI,MAAM,sCAAsC;AAAA,QAAA;AAExD,eAAO,UAAU,OAAO,OAAO,GAAG,iBAAiB;AAAA,MAAA;AAAA,IACrD,CACD;AAAA,IACDG,qBAAAA,oBAAoB,WAAW;AAAA,IAC/BC,wBAAY,aAAa,MAAM,SAAS;AAAA,IACxCC,qCAA8B;AAAA,MAC5B,GAAG,YAAY;AAAA,MACf,QAAQ,KAAK;AAAA,IACd,CAAA;AAAA,EACH;AACF;AAEA,SAAS,4BACP,MACA,aACc;AACV,MAAA;AAEE,QAAA,8BAAc,IAAY;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,EAAA,CACD;AAEM,SAAA;AAAA,IACL,MAAM;AAAA,IACN,eAAe,QAAQ;AACJ,uBAAA;AAAA,IACnB;AAAA,IACA,UAAU,IAAI;AACR,UAAA,QAAQ,IAAI,EAAE,GAAG;AACnB,eAAO,GAAG,EAAE;AAAA,MAAA;AAGP,aAAA;AAAA,IACT;AAAA,IACA,KAAK,IAAI;AACP,YAAM,iBAAiBN,gBAAK;AAAA,QAC1B,KAAK,QAAQ,YAAY,MAAM,YAAY,IAAI,cAAc,QAAQ;AAAA,MACvE;AAEA,UAAI,OAAO,4BAA4B;AAC/B,cAAA,mBAAmB,YAAY,gBAAgB;AAAA,UACnD;AAAA,QAAA,IAEE,YAAY,kBACZA,gBAAK;AAAA,UACH,KAAK,QAAQ,eAAe,MAAM,YAAY,eAAe;AAAA,QAC/D;AAEJ,eAAO,KAAK,4BAA4B;AAAA,UACtC;AAAA,UACA,qBAAqB;AAAA,QAAA,CACtB;AAAA,MAAA;AAGH,UAAI,OAAO,oCAAoC;AAC7C,eAAO,KAAK,sBAAsB,EAAE,gBAAgB;AAAA,MAAA;AAGtD,UAAI,OAAO,oCAAoC;AAC7C,eAAO,KAAK,sBAAsB,EAAE,gBAAgB;AAAA,MAAA;AAG/C,aAAA;AAAA,IAAA;AAAA,EAEX;AACF;AAEA,SAAS,gBACP,KACA,OACsE;AAC/D,SAAA;AAAA,IACL,CAAC,eAAe,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK;AAAA,IAC5C,CAAC,mBAAmB,GAAG,EAAE,GAAG,KAAK,UAAU,KAAK;AAAA,EAClD;AACF;;;;"}
@@ -2929,11 +2929,11 @@ export declare const clientDistDir = ".tanstack-start/build/client-dist";
2929
2929
  export declare const ssrEntryFile = "ssr.mjs";
2930
2930
  export interface TanStackStartVitePluginCoreOptions {
2931
2931
  framework: CompileStartFrameworkOptions;
2932
- getVirtualServerHandlerEntry: (ctx: {
2932
+ getVirtualServerRootHandler: (ctx: {
2933
2933
  routerFilepath: string;
2934
- ssrEntryFilepath: string;
2934
+ serverEntryFilepath: string;
2935
2935
  }) => string;
2936
- getVirtualSsrEntry: (ctx: {
2936
+ getVirtualServerEntry: (ctx: {
2937
2937
  routerFilepath: string;
2938
2938
  }) => string;
2939
2939
  getVirtualClientEntry: (ctx: {
@@ -5,6 +5,26 @@ const path = require("node:path");
5
5
  const ufo = require("ufo");
6
6
  const routerCore = require("@tanstack/router-core");
7
7
  const utils = require("./utils.cjs");
8
+ const getCSSRecursively = (file, filesByRouteFilePath) => {
9
+ const result = [];
10
+ for (const cssFile of file.css ?? []) {
11
+ result.push({
12
+ tag: "link",
13
+ attrs: {
14
+ rel: "stylesheet",
15
+ href: ufo.joinURL("/", cssFile),
16
+ type: "text/css"
17
+ }
18
+ });
19
+ }
20
+ for (const imp of file.imports ?? []) {
21
+ const importInfo = filesByRouteFilePath[imp];
22
+ if (importInfo) {
23
+ result.push(...getCSSRecursively(importInfo, filesByRouteFilePath));
24
+ }
25
+ }
26
+ return result;
27
+ };
8
28
  function startManifestPlugin(opts) {
9
29
  let config;
10
30
  const moduleId = "tanstack-start-router-manifest:v";
@@ -90,17 +110,7 @@ function startManifestPlugin(opts) {
90
110
  if (file.file) {
91
111
  preloads.unshift(path.join("/", file.file));
92
112
  }
93
- const cssFiles = file.css ?? [];
94
- const cssAssetsList = cssFiles.map(
95
- (cssFile) => ({
96
- tag: "link",
97
- attrs: {
98
- rel: "stylesheet",
99
- href: ufo.joinURL("/", cssFile),
100
- type: "text/css"
101
- }
102
- })
103
- );
113
+ const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath);
104
114
  routes[k] = {
105
115
  ...v,
106
116
  assets: [...v.assets || [], ...cssAssetsList],
@@ -115,16 +125,9 @@ function startManifestPlugin(opts) {
115
125
  (d) => path.join("/", viteManifest[d].file)
116
126
  )) || []
117
127
  ];
118
- const entryCssFiles = entryFile.css ?? [];
119
- const entryCssAssetsList = entryCssFiles.map(
120
- (cssFile) => ({
121
- tag: "link",
122
- attrs: {
123
- rel: "stylesheet",
124
- href: ufo.joinURL("/", cssFile),
125
- type: "text/css"
126
- }
127
- })
128
+ const entryCssAssetsList = getCSSRecursively(
129
+ entryFile,
130
+ filesByRouteFilePath
128
131
  );
129
132
  routes[routerCore.rootRouteId].assets = [
130
133
  ...routes[routerCore.rootRouteId].assets || [],
@@ -1 +1 @@
1
- {"version":3,"file":"routesManifestPlugin.cjs","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } 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\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\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 const routes = routerManifest.routes\n\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(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssFiles = file.css ?? []\n const cssAssetsList: Array<RouterManagedTag> = cssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', 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 entryCssFiles = entryFile.css ?? []\n const entryCssAssetsList: Array<RouterManagedTag> = entryCssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', 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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["resolveViteId","readFileSync","joinURL","rootRouteId","_a"],"mappings":"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"}
1
+ {"version":3,"file":"routesManifestPlugin.cjs","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } 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) => {\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('/', 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(...getCSSRecursively(importInfo, filesByRouteFilePath))\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\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 const routes = routerManifest.routes\n\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(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath)\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', 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 )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', 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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["joinURL","resolveViteId","readFileSync","rootRouteId","_a"],"mappings":"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"}
@@ -50,7 +50,7 @@ function nitroPlugin(options, getSsrBundle) {
50
50
  await builder.build(serverEnv);
51
51
  const nitroConfig = {
52
52
  dev: false,
53
- // TODO do we need this? should this be made configurable?
53
+ // TODO: do we need this? should this be made configurable?
54
54
  compatibilityDate: "2024-11-19",
55
55
  logLevel: 3,
56
56
  preset: buildPreset,
@@ -64,8 +64,18 @@ function nitroPlugin(options, getSsrBundle) {
64
64
  },
65
65
  prerender: void 0,
66
66
  renderer: ssrEntryFile,
67
+ plugins: [],
68
+ // Nitro's plugins
69
+ appConfigFiles: [],
70
+ scanDirs: [],
71
+ imports: false,
72
+ // unjs/unimport for global/magic imports
67
73
  rollupConfig: {
68
74
  plugins: [virtualBundlePlugin(getSsrBundle())]
75
+ },
76
+ virtual: {
77
+ // This is Nitro's way of defining virtual modules
78
+ // Should we define the ones for TanStack Start's here as well?
69
79
  }
70
80
  };
71
81
  const nitro = await createNitro(nitroConfig);
@@ -1 +1 @@
1
- {"version":3,"file":"nitro-plugin.js","sources":["../../../src/nitro/nitro-plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { rmSync } from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport { build, copyPublicAssets, createNitro, prepare } from 'nitropack'\nimport { dirname, resolve } from 'pathe'\nimport { clientDistDir, ssrEntryFile } from '../plugin'\nimport { prerender } from '../prerender'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { buildSitemap } from '../build-sitemap'\nimport { devServerPlugin } from './dev-server-plugin'\nimport type {\n EnvironmentOptions,\n PluginOption,\n Rollup,\n ViteBuilder,\n} from 'vite'\nimport type { Nitro, NitroConfig } from 'nitropack'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport function nitroPlugin(\n options: TanStackStartOutputConfig,\n getSsrBundle: () => Rollup.OutputBundle,\n): Array<PluginOption> {\n const buildPreset =\n process.env['START_TARGET'] ?? (options.target as string | undefined)\n\n return [\n devServerPlugin(),\n {\n name: 'tanstack-vite-plugin-nitro',\n configEnvironment(name) {\n if (name === VITE_ENVIRONMENT_NAMES.server) {\n return {\n build: {\n commonjsOptions: {\n include: [],\n },\n ssr: true,\n sourcemap: true,\n rollupOptions: {\n input: '/~start/server-entry',\n },\n },\n } satisfies EnvironmentOptions\n }\n\n return null\n },\n config() {\n return {\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const clientEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const serverEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!clientEnv) {\n throw new Error('Client environment not found')\n }\n\n if (!serverEnv) {\n throw new Error('SSR environment not found')\n }\n\n const clientOutputDir = resolve(options.root, clientDistDir)\n rmSync(clientOutputDir, { recursive: true, force: true })\n await builder.build(clientEnv)\n\n await builder.build(serverEnv)\n\n const nitroConfig: NitroConfig = {\n dev: false,\n // TODO do we need this? should this be made configurable?\n compatibilityDate: '2024-11-19',\n logLevel: 3,\n preset: buildPreset,\n publicAssets: [\n {\n dir: path.resolve(options.root, clientDistDir),\n },\n ],\n typescript: {\n generateTsConfig: false,\n },\n prerender: undefined,\n renderer: ssrEntryFile,\n rollupConfig: {\n plugins: [virtualBundlePlugin(getSsrBundle())],\n },\n }\n\n const nitro = await createNitro(nitroConfig)\n\n await buildNitroApp(builder, nitro, options)\n },\n },\n }\n },\n },\n ]\n}\n\n/**\n * Correctly co-ordinates the nitro app build process to make sure that the\n * app is built, while also correctly handling the prerendering and sitemap\n * generation and including their outputs in the final build.\n */\nasync function buildNitroApp(\n builder: ViteBuilder,\n nitro: Nitro,\n options: TanStackStartOutputConfig,\n) {\n // Cleans the public and server directories for a fresh build\n // i.e the `.output/public` and `.output/server` directories\n await prepare(nitro)\n\n // Creates the `.output/public` directory and copies the public assets\n await copyPublicAssets(nitro)\n\n // If the user has not set a prerender option, we need to set it to true\n // if the pages array is not empty and has sub options requiring for prerendering\n if (options.prerender?.enabled !== false) {\n options.prerender = {\n ...options.prerender,\n enabled: options.pages.some((d) =>\n typeof d === 'string' ? false : !!d.prerender?.enabled,\n ),\n }\n }\n\n // Setup the options for prerendering the SPA shell (i.e `src/routes/__root.tsx`)\n if (options.spa?.enabled) {\n options.prerender = {\n ...options.prerender,\n enabled: true,\n }\n\n const maskUrl = new URL(options.spa.maskPath, 'http://localhost')\n\n maskUrl.searchParams.set('__TSS_SHELL', 'true')\n\n options.pages.push({\n path: maskUrl.toString().replace('http://localhost', ''),\n prerender: options.spa.prerender,\n sitemap: {\n exclude: true,\n },\n })\n }\n\n // Run the prerendering process\n if (options.prerender.enabled) {\n await prerender({\n options,\n nitro,\n builder,\n })\n }\n\n // Run the sitemap build process\n if (options.pages.length) {\n buildSitemap({\n options,\n publicDir: nitro.options.output.publicDir,\n })\n }\n\n // Build the nitro app\n await build(nitro)\n\n // Cleanup the vite public directory\n // As a part of the build process, a `.vite/` directory\n // is copied over from `.tanstack-start/build/client-dist/`\n // to the nitro `publicDir` (e.g. `.output/public/`).\n // This directory (and its contents including the vite client manifest)\n // should not be included in the final build, so we remove it.\n const nitroPublicDir = nitro.options.output.publicDir\n const viteDir = path.resolve(nitroPublicDir, '.vite')\n if (await fsp.stat(viteDir).catch(() => false)) {\n await fsp.rm(viteDir, { recursive: true, force: true })\n }\n\n // Close the nitro instance\n await nitro.close()\n nitro.logger.success(\n 'Client and Server bundles for TanStack Start have been successfully built.',\n )\n}\n\nfunction virtualBundlePlugin(ssrBundle: Rollup.OutputBundle): Rollup.Plugin {\n type VirtualModule = { code: string; map: string | null }\n const _modules = new Map<string, VirtualModule>()\n\n // group chunks and source maps\n for (const [fileName, content] of Object.entries(ssrBundle)) {\n if (content.type === 'chunk') {\n const virtualModule: VirtualModule = {\n code: content.code,\n map: null,\n }\n const maybeMap = ssrBundle[`${fileName}.map`]\n if (maybeMap && maybeMap.type === 'asset') {\n virtualModule.map = maybeMap.source as string\n }\n _modules.set(fileName, virtualModule)\n _modules.set(resolve(fileName), virtualModule)\n }\n }\n\n return {\n name: 'virtual-bundle',\n resolveId(id, importer) {\n if (_modules.has(id)) {\n return resolve(id)\n }\n\n if (importer) {\n const resolved = resolve(dirname(importer), id)\n if (_modules.has(resolved)) {\n return resolved\n }\n }\n return null\n },\n load(id) {\n const m = _modules.get(id)\n if (!m) {\n return null\n }\n return m\n },\n }\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"nitro-plugin.js","sources":["../../../src/nitro/nitro-plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { rmSync } from 'node:fs'\nimport * as fsp from 'node:fs/promises'\nimport { build, copyPublicAssets, createNitro, prepare } from 'nitropack'\nimport { dirname, resolve } from 'pathe'\nimport { clientDistDir, ssrEntryFile } from '../plugin'\nimport { prerender } from '../prerender'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { buildSitemap } from '../build-sitemap'\nimport { devServerPlugin } from './dev-server-plugin'\nimport type {\n EnvironmentOptions,\n PluginOption,\n Rollup,\n ViteBuilder,\n} from 'vite'\nimport type { Nitro, NitroConfig } from 'nitropack'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport function nitroPlugin(\n options: TanStackStartOutputConfig,\n getSsrBundle: () => Rollup.OutputBundle,\n): Array<PluginOption> {\n const buildPreset =\n process.env['START_TARGET'] ?? (options.target as string | undefined)\n\n return [\n devServerPlugin(),\n {\n name: 'tanstack-vite-plugin-nitro',\n configEnvironment(name) {\n if (name === VITE_ENVIRONMENT_NAMES.server) {\n return {\n build: {\n commonjsOptions: {\n include: [],\n },\n ssr: true,\n sourcemap: true,\n rollupOptions: {\n input: '/~start/server-entry',\n },\n },\n } satisfies EnvironmentOptions\n }\n\n return null\n },\n config() {\n return {\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const clientEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const serverEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!clientEnv) {\n throw new Error('Client environment not found')\n }\n\n if (!serverEnv) {\n throw new Error('SSR environment not found')\n }\n\n const clientOutputDir = resolve(options.root, clientDistDir)\n rmSync(clientOutputDir, { recursive: true, force: true })\n await builder.build(clientEnv)\n\n await builder.build(serverEnv)\n\n const nitroConfig: NitroConfig = {\n dev: false,\n // TODO: do we need this? should this be made configurable?\n compatibilityDate: '2024-11-19',\n logLevel: 3,\n preset: buildPreset,\n publicAssets: [\n {\n dir: path.resolve(options.root, clientDistDir),\n },\n ],\n typescript: {\n generateTsConfig: false,\n },\n prerender: undefined,\n renderer: ssrEntryFile,\n plugins: [], // Nitro's plugins\n appConfigFiles: [],\n scanDirs: [],\n imports: false, // unjs/unimport for global/magic imports\n rollupConfig: {\n plugins: [virtualBundlePlugin(getSsrBundle())],\n },\n virtual: {\n // This is Nitro's way of defining virtual modules\n // Should we define the ones for TanStack Start's here as well?\n },\n }\n\n const nitro = await createNitro(nitroConfig)\n\n await buildNitroApp(builder, nitro, options)\n },\n },\n }\n },\n },\n ]\n}\n\n/**\n * Correctly co-ordinates the nitro app build process to make sure that the\n * app is built, while also correctly handling the prerendering and sitemap\n * generation and including their outputs in the final build.\n */\nasync function buildNitroApp(\n builder: ViteBuilder,\n nitro: Nitro,\n options: TanStackStartOutputConfig,\n) {\n // Cleans the public and server directories for a fresh build\n // i.e the `.output/public` and `.output/server` directories\n await prepare(nitro)\n\n // Creates the `.output/public` directory and copies the public assets\n await copyPublicAssets(nitro)\n\n // If the user has not set a prerender option, we need to set it to true\n // if the pages array is not empty and has sub options requiring for prerendering\n if (options.prerender?.enabled !== false) {\n options.prerender = {\n ...options.prerender,\n enabled: options.pages.some((d) =>\n typeof d === 'string' ? false : !!d.prerender?.enabled,\n ),\n }\n }\n\n // Setup the options for prerendering the SPA shell (i.e `src/routes/__root.tsx`)\n if (options.spa?.enabled) {\n options.prerender = {\n ...options.prerender,\n enabled: true,\n }\n\n const maskUrl = new URL(options.spa.maskPath, 'http://localhost')\n\n maskUrl.searchParams.set('__TSS_SHELL', 'true')\n\n options.pages.push({\n path: maskUrl.toString().replace('http://localhost', ''),\n prerender: options.spa.prerender,\n sitemap: {\n exclude: true,\n },\n })\n }\n\n // Run the prerendering process\n if (options.prerender.enabled) {\n await prerender({\n options,\n nitro,\n builder,\n })\n }\n\n // Run the sitemap build process\n if (options.pages.length) {\n buildSitemap({\n options,\n publicDir: nitro.options.output.publicDir,\n })\n }\n\n // Build the nitro app\n await build(nitro)\n\n // Cleanup the vite public directory\n // As a part of the build process, a `.vite/` directory\n // is copied over from `.tanstack-start/build/client-dist/`\n // to the nitro `publicDir` (e.g. `.output/public/`).\n // This directory (and its contents including the vite client manifest)\n // should not be included in the final build, so we remove it.\n const nitroPublicDir = nitro.options.output.publicDir\n const viteDir = path.resolve(nitroPublicDir, '.vite')\n if (await fsp.stat(viteDir).catch(() => false)) {\n await fsp.rm(viteDir, { recursive: true, force: true })\n }\n\n // Close the nitro instance\n await nitro.close()\n nitro.logger.success(\n 'Client and Server bundles for TanStack Start have been successfully built.',\n )\n}\n\nfunction virtualBundlePlugin(ssrBundle: Rollup.OutputBundle): Rollup.Plugin {\n type VirtualModule = { code: string; map: string | null }\n const _modules = new Map<string, VirtualModule>()\n\n // group chunks and source maps\n for (const [fileName, content] of Object.entries(ssrBundle)) {\n if (content.type === 'chunk') {\n const virtualModule: VirtualModule = {\n code: content.code,\n map: null,\n }\n const maybeMap = ssrBundle[`${fileName}.map`]\n if (maybeMap && maybeMap.type === 'asset') {\n virtualModule.map = maybeMap.source as string\n }\n _modules.set(fileName, virtualModule)\n _modules.set(resolve(fileName), virtualModule)\n }\n }\n\n return {\n name: 'virtual-bundle',\n resolveId(id, importer) {\n if (_modules.has(id)) {\n return resolve(id)\n }\n\n if (importer) {\n const resolved = resolve(dirname(importer), id)\n if (_modules.has(resolved)) {\n return resolved\n }\n }\n return null\n },\n load(id) {\n const m = _modules.get(id)\n if (!m) {\n return null\n }\n return m\n },\n }\n}\n"],"names":["_a"],"mappings":"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"}
@@ -2929,11 +2929,11 @@ export declare const clientDistDir = ".tanstack-start/build/client-dist";
2929
2929
  export declare const ssrEntryFile = "ssr.mjs";
2930
2930
  export interface TanStackStartVitePluginCoreOptions {
2931
2931
  framework: CompileStartFrameworkOptions;
2932
- getVirtualServerHandlerEntry: (ctx: {
2932
+ getVirtualServerRootHandler: (ctx: {
2933
2933
  routerFilepath: string;
2934
- ssrEntryFilepath: string;
2934
+ serverEntryFilepath: string;
2935
2935
  }) => string;
2936
- getVirtualSsrEntry: (ctx: {
2936
+ getVirtualServerEntry: (ctx: {
2937
2937
  routerFilepath: string;
2938
2938
  }) => string;
2939
2939
  getVirtualClientEntry: (ctx: {
@@ -186,16 +186,16 @@ function resolveVirtualEntriesPlugin(opts, startConfig) {
186
186
  ) ? startConfig.serverEntryPath : vite.normalizePath(
187
187
  path.resolve(resolvedConfig.root, startConfig.serverEntryPath)
188
188
  );
189
- return opts.getVirtualServerHandlerEntry({
189
+ return opts.getVirtualServerRootHandler({
190
190
  routerFilepath,
191
- ssrEntryFilepath
191
+ serverEntryFilepath: ssrEntryFilepath
192
192
  });
193
193
  }
194
194
  if (id === "/~start/default-client-entry.tsx") {
195
195
  return opts.getVirtualClientEntry({ routerFilepath });
196
196
  }
197
197
  if (id === "/~start/default-server-entry.tsx") {
198
- return opts.getVirtualSsrEntry({ routerFilepath });
198
+ return opts.getVirtualServerEntry({ routerFilepath });
199
199
  }
200
200
  return void 0;
201
201
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport {\n createTanStackConfig,\n createTanStackStartOptionsSchema,\n} from './schema'\nimport { nitroPlugin } from './nitro/nitro-plugin'\nimport { startManifestPlugin } from './routesManifestPlugin'\nimport { TanStackStartCompilerPlugin } from './start-compiler-plugin'\nimport { VITE_ENVIRONMENT_NAMES } from './constants'\nimport { TanStackStartServerRoutesVite } from './start-server-routes-plugin/plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nconst TanStackStartOptionsSchema = createTanStackStartOptionsSchema()\nexport type TanStackStartInputConfig = z.input<\n typeof TanStackStartOptionsSchema\n>\n\nconst defaultConfig = createTanStackConfig()\nexport function getTanStackStartOptions(opts?: TanStackStartInputConfig) {\n return defaultConfig.parse(opts)\n}\n\nexport type TanStackStartOutputConfig = ReturnType<\n typeof getTanStackStartOptions\n>\n\nexport const clientDistDir = '.tanstack-start/build/client-dist'\nexport const ssrEntryFile = 'ssr.mjs'\n\nexport interface TanStackStartVitePluginCoreOptions {\n framework: CompileStartFrameworkOptions\n getVirtualServerHandlerEntry: (ctx: {\n routerFilepath: string\n ssrEntryFilepath: string\n }) => string\n getVirtualSsrEntry: (ctx: { routerFilepath: string }) => string\n getVirtualClientEntry: (ctx: { routerFilepath: string }) => string\n}\n// this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite\nlet ssrBundle: Rollup.OutputBundle\n\nexport function TanStackStartVitePluginCore(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): Array<PluginOption> {\n return [\n tanstackRouter({\n verboseFileRoutes: false,\n ...startConfig.tsr,\n target: opts.framework,\n enableRouteGeneration: true,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config() {\n const nitroOutputPublicDir = await (async () => {\n // Create a dummy nitro app to get the resolved public output path\n const dummyNitroApp = await createNitro({\n preset: startConfig.target,\n compatibilityDate: '2024-12-01',\n })\n\n const nitroOutputPublicDir = dummyNitroApp.options.output.publicDir\n await dummyNitroApp.close()\n\n return nitroOutputPublicDir\n })()\n\n const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {\n // when the user specifies a custom client entry path, we need to resolve it\n // relative to the root of the project, keeping in mind that if not specified\n // it will be /~start/default-client-entry which is a virtual path\n // that is resolved by vite to the actual client entry path\n const entry = startConfig.clientEntryPath.startsWith(\n '/~start/default-client-entry',\n )\n ? startConfig.clientEntryPath\n : vite.normalizePath(\n path.join(\n '/@fs',\n path.resolve(startConfig.root, startConfig.clientEntryPath),\n ),\n )\n\n return entry\n }\n\n return {\n environments: {\n [VITE_ENVIRONMENT_NAMES.client]: {\n consumer: 'client',\n build: {\n manifest: true,\n rollupOptions: {\n input: {\n main: getClientEntryPath(startConfig),\n },\n output: {\n dir: path.resolve(startConfig.root, clientDistDir),\n },\n // TODO this should be removed\n external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],\n },\n },\n },\n [VITE_ENVIRONMENT_NAMES.server]: {\n consumer: 'server',\n build: {\n ssr: true,\n // we don't write to the file system as the below 'capture-output' plugin will\n // capture the output and write it to the virtual file system\n write: false,\n copyPublicDir: false,\n rollupOptions: {\n output: {\n entryFileNames: ssrEntryFile,\n },\n plugins: [\n {\n name: 'capture-output',\n generateBundle(options, bundle) {\n // TODO can this hook be called more than once?\n ssrBundle = bundle\n },\n },\n ],\n },\n commonjsOptions: {\n include: [/node_modules/],\n },\n },\n },\n },\n resolve: {\n noExternal: [\n '@tanstack/start-client',\n '@tanstack/start-client-core',\n '@tanstack/start-server',\n '@tanstack/start-server-core',\n '@tanstack/start-server-functions-fetcher',\n '@tanstack/start-server-functions-client',\n '@tanstack/start-server-functions-server',\n '@tanstack/start-router-manifest',\n '@tanstack/start-config',\n '@tanstack/server-functions-plugin',\n 'tanstack-start-router-manifest:v',\n 'tanstack-start-server-fn-manifest:v',\n 'nitropack',\n '@tanstack/**',\n ],\n },\n /* prettier-ignore */\n define: {\n ...injectDefineEnv('TSS_PUBLIC_BASE', startConfig.public.base),\n ...injectDefineEnv('TSS_CLIENT_BASE', startConfig.client.base),\n ...injectDefineEnv('TSS_CLIENT_ENTRY', getClientEntryPath(startConfig)), // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved\n ...injectDefineEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...injectDefineEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n TanStackStartCompilerPlugin(opts.framework, {\n client: { envName: VITE_ENVIRONMENT_NAMES.client },\n server: { envName: VITE_ENVIRONMENT_NAMES.server },\n }),\n TanStackServerFnPluginEnv({\n // This is the ID that will be available to look up and import\n // our server function manifest and resolve its module\n manifestVirtualImportId: 'tanstack-start-server-fn-manifest:v',\n manifestOutputFilename:\n '.tanstack-start/build/server/server-functions-manifest.json',\n client: {\n getRuntimeCode: () =>\n `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,\n replacer: (d) =>\n `createClientRpc('${d.functionId}', '${startConfig.serverFns.base}')`,\n envName: VITE_ENVIRONMENT_NAMES.client,\n },\n server: {\n getRuntimeCode: () =>\n `import { createServerRpc } from '@tanstack/${opts.framework}-start/server-functions-server'`,\n replacer: (d) =>\n `createServerRpc('${d.functionId}', '${startConfig.serverFns.base}', ${d.fn})`,\n envName: VITE_ENVIRONMENT_NAMES.server,\n },\n importer: (fn) => {\n const serverEnv = (globalThis as any).viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ]\n if (!serverEnv) {\n throw new Error(`'ssr' vite dev environment not found`)\n }\n return serverEnv.runner.import(fn.extractedFilename)\n },\n }),\n startManifestPlugin(startConfig),\n nitroPlugin(startConfig, () => ssrBundle),\n TanStackStartServerRoutesVite({\n ...startConfig.tsr,\n target: opts.framework,\n }),\n ]\n}\n\nfunction resolveVirtualEntriesPlugin(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): PluginOption {\n let resolvedConfig: vite.ResolvedConfig\n\n const modules = new Set<string>([\n '/~start/server-entry',\n '/~start/default-server-entry',\n '/~start/default-client-entry',\n ])\n\n return {\n name: 'tanstack-start-core:resolve-virtual-entries',\n configResolved(config) {\n resolvedConfig = config\n },\n resolveId(id) {\n if (modules.has(id)) {\n return `${id}.tsx`\n }\n\n return undefined\n },\n load(id) {\n const routerFilepath = vite.normalizePath(\n path.resolve(startConfig.root, startConfig.tsr.srcDirectory, 'router'),\n )\n\n if (id === '/~start/server-entry.tsx') {\n const ssrEntryFilepath = startConfig.serverEntryPath.startsWith(\n '/~start/default-server-entry',\n )\n ? startConfig.serverEntryPath\n : vite.normalizePath(\n path.resolve(resolvedConfig.root, startConfig.serverEntryPath),\n )\n\n return opts.getVirtualServerHandlerEntry({\n routerFilepath,\n ssrEntryFilepath,\n })\n }\n\n if (id === '/~start/default-client-entry.tsx') {\n return opts.getVirtualClientEntry({ routerFilepath })\n }\n\n if (id === '/~start/default-server-entry.tsx') {\n return opts.getVirtualSsrEntry({ routerFilepath })\n }\n\n return undefined\n },\n }\n}\n\nfunction injectDefineEnv<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":["nitroOutputPublicDir","startConfig"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport {\n createTanStackConfig,\n createTanStackStartOptionsSchema,\n} from './schema'\nimport { nitroPlugin } from './nitro/nitro-plugin'\nimport { startManifestPlugin } from './routesManifestPlugin'\nimport { TanStackStartCompilerPlugin } from './start-compiler-plugin'\nimport { VITE_ENVIRONMENT_NAMES } from './constants'\nimport { TanStackStartServerRoutesVite } from './start-server-routes-plugin/plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nconst TanStackStartOptionsSchema = createTanStackStartOptionsSchema()\nexport type TanStackStartInputConfig = z.input<\n typeof TanStackStartOptionsSchema\n>\n\nconst defaultConfig = createTanStackConfig()\nexport function getTanStackStartOptions(opts?: TanStackStartInputConfig) {\n return defaultConfig.parse(opts)\n}\n\nexport type TanStackStartOutputConfig = ReturnType<\n typeof getTanStackStartOptions\n>\n\nexport const clientDistDir = '.tanstack-start/build/client-dist'\nexport const ssrEntryFile = 'ssr.mjs'\n\nexport interface TanStackStartVitePluginCoreOptions {\n framework: CompileStartFrameworkOptions\n getVirtualServerRootHandler: (ctx: {\n routerFilepath: string\n serverEntryFilepath: string\n }) => string\n getVirtualServerEntry: (ctx: { routerFilepath: string }) => string\n getVirtualClientEntry: (ctx: { routerFilepath: string }) => string\n}\n// this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite\nlet ssrBundle: Rollup.OutputBundle\n\nexport function TanStackStartVitePluginCore(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): Array<PluginOption> {\n return [\n tanstackRouter({\n verboseFileRoutes: false,\n ...startConfig.tsr,\n target: opts.framework,\n enableRouteGeneration: true,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config() {\n const nitroOutputPublicDir = await (async () => {\n // Create a dummy nitro app to get the resolved public output path\n const dummyNitroApp = await createNitro({\n preset: startConfig.target,\n compatibilityDate: '2024-12-01',\n })\n\n const nitroOutputPublicDir = dummyNitroApp.options.output.publicDir\n await dummyNitroApp.close()\n\n return nitroOutputPublicDir\n })()\n\n const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {\n // when the user specifies a custom client entry path, we need to resolve it\n // relative to the root of the project, keeping in mind that if not specified\n // it will be /~start/default-client-entry which is a virtual path\n // that is resolved by vite to the actual client entry path\n const entry = startConfig.clientEntryPath.startsWith(\n '/~start/default-client-entry',\n )\n ? startConfig.clientEntryPath\n : vite.normalizePath(\n path.join(\n '/@fs',\n path.resolve(startConfig.root, startConfig.clientEntryPath),\n ),\n )\n\n return entry\n }\n\n return {\n environments: {\n [VITE_ENVIRONMENT_NAMES.client]: {\n consumer: 'client',\n build: {\n manifest: true,\n rollupOptions: {\n input: {\n main: getClientEntryPath(startConfig),\n },\n output: {\n dir: path.resolve(startConfig.root, clientDistDir),\n },\n // TODO this should be removed\n external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],\n },\n },\n },\n [VITE_ENVIRONMENT_NAMES.server]: {\n consumer: 'server',\n build: {\n ssr: true,\n // we don't write to the file system as the below 'capture-output' plugin will\n // capture the output and write it to the virtual file system\n write: false,\n copyPublicDir: false,\n rollupOptions: {\n output: {\n entryFileNames: ssrEntryFile,\n },\n plugins: [\n {\n name: 'capture-output',\n generateBundle(options, bundle) {\n // TODO can this hook be called more than once?\n ssrBundle = bundle\n },\n },\n ],\n },\n commonjsOptions: {\n include: [/node_modules/],\n },\n },\n },\n },\n resolve: {\n noExternal: [\n '@tanstack/start-client',\n '@tanstack/start-client-core',\n '@tanstack/start-server',\n '@tanstack/start-server-core',\n '@tanstack/start-server-functions-fetcher',\n '@tanstack/start-server-functions-client',\n '@tanstack/start-server-functions-server',\n '@tanstack/start-router-manifest',\n '@tanstack/start-config',\n '@tanstack/server-functions-plugin',\n 'tanstack-start-router-manifest:v',\n 'tanstack-start-server-fn-manifest:v',\n 'nitropack',\n '@tanstack/**',\n ],\n },\n /* prettier-ignore */\n define: {\n ...injectDefineEnv('TSS_PUBLIC_BASE', startConfig.public.base),\n ...injectDefineEnv('TSS_CLIENT_BASE', startConfig.client.base),\n ...injectDefineEnv('TSS_CLIENT_ENTRY', getClientEntryPath(startConfig)), // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved\n ...injectDefineEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...injectDefineEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n TanStackStartCompilerPlugin(opts.framework, {\n client: { envName: VITE_ENVIRONMENT_NAMES.client },\n server: { envName: VITE_ENVIRONMENT_NAMES.server },\n }),\n TanStackServerFnPluginEnv({\n // This is the ID that will be available to look up and import\n // our server function manifest and resolve its module\n manifestVirtualImportId: 'tanstack-start-server-fn-manifest:v',\n manifestOutputFilename:\n '.tanstack-start/build/server/server-functions-manifest.json',\n client: {\n getRuntimeCode: () =>\n `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,\n replacer: (d) =>\n `createClientRpc('${d.functionId}', '${startConfig.serverFns.base}')`,\n envName: VITE_ENVIRONMENT_NAMES.client,\n },\n server: {\n getRuntimeCode: () =>\n `import { createServerRpc } from '@tanstack/${opts.framework}-start/server-functions-server'`,\n replacer: (d) =>\n `createServerRpc('${d.functionId}', '${startConfig.serverFns.base}', ${d.fn})`,\n envName: VITE_ENVIRONMENT_NAMES.server,\n },\n importer: (fn) => {\n const serverEnv = (globalThis as any).viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ]\n if (!serverEnv) {\n throw new Error(`'ssr' vite dev environment not found`)\n }\n return serverEnv.runner.import(fn.extractedFilename)\n },\n }),\n startManifestPlugin(startConfig),\n nitroPlugin(startConfig, () => ssrBundle),\n TanStackStartServerRoutesVite({\n ...startConfig.tsr,\n target: opts.framework,\n }),\n ]\n}\n\nfunction resolveVirtualEntriesPlugin(\n opts: TanStackStartVitePluginCoreOptions,\n startConfig: TanStackStartOutputConfig,\n): PluginOption {\n let resolvedConfig: vite.ResolvedConfig\n\n const modules = new Set<string>([\n '/~start/server-entry',\n '/~start/default-server-entry',\n '/~start/default-client-entry',\n ])\n\n return {\n name: 'tanstack-start-core:resolve-virtual-entries',\n configResolved(config) {\n resolvedConfig = config\n },\n resolveId(id) {\n if (modules.has(id)) {\n return `${id}.tsx`\n }\n\n return undefined\n },\n load(id) {\n const routerFilepath = vite.normalizePath(\n path.resolve(startConfig.root, startConfig.tsr.srcDirectory, 'router'),\n )\n\n if (id === '/~start/server-entry.tsx') {\n const ssrEntryFilepath = startConfig.serverEntryPath.startsWith(\n '/~start/default-server-entry',\n )\n ? startConfig.serverEntryPath\n : vite.normalizePath(\n path.resolve(resolvedConfig.root, startConfig.serverEntryPath),\n )\n\n return opts.getVirtualServerRootHandler({\n routerFilepath,\n serverEntryFilepath: ssrEntryFilepath,\n })\n }\n\n if (id === '/~start/default-client-entry.tsx') {\n return opts.getVirtualClientEntry({ routerFilepath })\n }\n\n if (id === '/~start/default-server-entry.tsx') {\n return opts.getVirtualServerEntry({ routerFilepath })\n }\n\n return undefined\n },\n }\n}\n\nfunction injectDefineEnv<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":["nitroOutputPublicDir","startConfig"],"mappings":"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"}
@@ -3,6 +3,26 @@ import path from "node:path";
3
3
  import { joinURL } from "ufo";
4
4
  import { rootRouteId } from "@tanstack/router-core";
5
5
  import { resolveViteId } from "./utils.js";
6
+ const getCSSRecursively = (file, filesByRouteFilePath) => {
7
+ const result = [];
8
+ for (const cssFile of file.css ?? []) {
9
+ result.push({
10
+ tag: "link",
11
+ attrs: {
12
+ rel: "stylesheet",
13
+ href: joinURL("/", cssFile),
14
+ type: "text/css"
15
+ }
16
+ });
17
+ }
18
+ for (const imp of file.imports ?? []) {
19
+ const importInfo = filesByRouteFilePath[imp];
20
+ if (importInfo) {
21
+ result.push(...getCSSRecursively(importInfo, filesByRouteFilePath));
22
+ }
23
+ }
24
+ return result;
25
+ };
6
26
  function startManifestPlugin(opts) {
7
27
  let config;
8
28
  const moduleId = "tanstack-start-router-manifest:v";
@@ -88,17 +108,7 @@ function startManifestPlugin(opts) {
88
108
  if (file.file) {
89
109
  preloads.unshift(path.join("/", file.file));
90
110
  }
91
- const cssFiles = file.css ?? [];
92
- const cssAssetsList = cssFiles.map(
93
- (cssFile) => ({
94
- tag: "link",
95
- attrs: {
96
- rel: "stylesheet",
97
- href: joinURL("/", cssFile),
98
- type: "text/css"
99
- }
100
- })
101
- );
111
+ const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath);
102
112
  routes[k] = {
103
113
  ...v,
104
114
  assets: [...v.assets || [], ...cssAssetsList],
@@ -113,16 +123,9 @@ function startManifestPlugin(opts) {
113
123
  (d) => path.join("/", viteManifest[d].file)
114
124
  )) || []
115
125
  ];
116
- const entryCssFiles = entryFile.css ?? [];
117
- const entryCssAssetsList = entryCssFiles.map(
118
- (cssFile) => ({
119
- tag: "link",
120
- attrs: {
121
- rel: "stylesheet",
122
- href: joinURL("/", cssFile),
123
- type: "text/css"
124
- }
125
- })
126
+ const entryCssAssetsList = getCSSRecursively(
127
+ entryFile,
128
+ filesByRouteFilePath
126
129
  );
127
130
  routes[rootRouteId].assets = [
128
131
  ...routes[rootRouteId].assets || [],
@@ -1 +1 @@
1
- {"version":3,"file":"routesManifestPlugin.js","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } 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\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\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 const routes = routerManifest.routes\n\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(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssFiles = file.css ?? []\n const cssAssetsList: Array<RouterManagedTag> = cssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', 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 entryCssFiles = entryFile.css ?? []\n const entryCssAssetsList: Array<RouterManagedTag> = entryCssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', 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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["_a"],"mappings":"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"}
1
+ {"version":3,"file":"routesManifestPlugin.js","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } 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) => {\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('/', 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(...getCSSRecursively(importInfo, filesByRouteFilePath))\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\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 const routes = routerManifest.routes\n\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(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath)\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', 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 )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', 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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\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.14",
3
+ "version": "1.121.0-alpha.16",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -63,11 +63,11 @@
63
63
  "ufo": "^1.5.4",
64
64
  "xmlbuilder2": "^3.1.1",
65
65
  "zod": "^3.24.2",
66
- "@tanstack/router-core": "^1.121.0-alpha.14",
66
+ "@tanstack/router-generator": "^1.121.0-alpha.14",
67
67
  "@tanstack/router-plugin": "^1.121.0-alpha.14",
68
- "@tanstack/router-utils": "^1.121.0-alpha.2",
68
+ "@tanstack/router-core": "^1.121.0-alpha.14",
69
69
  "@tanstack/server-functions-plugin": "^1.121.0-alpha.8",
70
- "@tanstack/router-generator": "^1.121.0-alpha.14"
70
+ "@tanstack/router-utils": "^1.121.0-alpha.2"
71
71
  },
72
72
  "devDependencies": {
73
73
  "vite": "^6.0.0"
@@ -72,7 +72,7 @@ export function nitroPlugin(
72
72
 
73
73
  const nitroConfig: NitroConfig = {
74
74
  dev: false,
75
- // TODO do we need this? should this be made configurable?
75
+ // TODO: do we need this? should this be made configurable?
76
76
  compatibilityDate: '2024-11-19',
77
77
  logLevel: 3,
78
78
  preset: buildPreset,
@@ -86,9 +86,17 @@ export function nitroPlugin(
86
86
  },
87
87
  prerender: undefined,
88
88
  renderer: ssrEntryFile,
89
+ plugins: [], // Nitro's plugins
90
+ appConfigFiles: [],
91
+ scanDirs: [],
92
+ imports: false, // unjs/unimport for global/magic imports
89
93
  rollupConfig: {
90
94
  plugins: [virtualBundlePlugin(getSsrBundle())],
91
95
  },
96
+ virtual: {
97
+ // This is Nitro's way of defining virtual modules
98
+ // Should we define the ones for TanStack Start's here as well?
99
+ },
92
100
  }
93
101
 
94
102
  const nitro = await createNitro(nitroConfig)
package/src/plugin.ts CHANGED
@@ -35,11 +35,11 @@ export const ssrEntryFile = 'ssr.mjs'
35
35
 
36
36
  export interface TanStackStartVitePluginCoreOptions {
37
37
  framework: CompileStartFrameworkOptions
38
- getVirtualServerHandlerEntry: (ctx: {
38
+ getVirtualServerRootHandler: (ctx: {
39
39
  routerFilepath: string
40
- ssrEntryFilepath: string
40
+ serverEntryFilepath: string
41
41
  }) => string
42
- getVirtualSsrEntry: (ctx: { routerFilepath: string }) => string
42
+ getVirtualServerEntry: (ctx: { routerFilepath: string }) => string
43
43
  getVirtualClientEntry: (ctx: { routerFilepath: string }) => string
44
44
  }
45
45
  // this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite
@@ -250,9 +250,9 @@ function resolveVirtualEntriesPlugin(
250
250
  path.resolve(resolvedConfig.root, startConfig.serverEntryPath),
251
251
  )
252
252
 
253
- return opts.getVirtualServerHandlerEntry({
253
+ return opts.getVirtualServerRootHandler({
254
254
  routerFilepath,
255
- ssrEntryFilepath,
255
+ serverEntryFilepath: ssrEntryFilepath,
256
256
  })
257
257
  }
258
258
 
@@ -261,7 +261,7 @@ function resolveVirtualEntriesPlugin(
261
261
  }
262
262
 
263
263
  if (id === '/~start/default-server-entry.tsx') {
264
- return opts.getVirtualSsrEntry({ routerFilepath })
264
+ return opts.getVirtualServerEntry({ routerFilepath })
265
265
  }
266
266
 
267
267
  return undefined
@@ -12,6 +12,35 @@ import type {
12
12
  import type { Manifest, RouterManagedTag } from '@tanstack/router-core'
13
13
  import type { TanStackStartOutputConfig } from './plugin'
14
14
 
15
+ const getCSSRecursively = (
16
+ file: ViteManifestChunk,
17
+ filesByRouteFilePath: ViteManifest,
18
+ ) => {
19
+ const result: Array<RouterManagedTag> = []
20
+
21
+ // Get all css imports from the file
22
+ for (const cssFile of file.css ?? []) {
23
+ result.push({
24
+ tag: 'link',
25
+ attrs: {
26
+ rel: 'stylesheet',
27
+ href: joinURL('/', cssFile),
28
+ type: 'text/css',
29
+ },
30
+ })
31
+ }
32
+
33
+ // Recursively get CSS from imports
34
+ for (const imp of file.imports ?? []) {
35
+ const importInfo = filesByRouteFilePath[imp]
36
+ if (importInfo) {
37
+ result.push(...getCSSRecursively(importInfo, filesByRouteFilePath))
38
+ }
39
+ }
40
+
41
+ return result
42
+ }
43
+
15
44
  export function startManifestPlugin(
16
45
  opts: TanStackStartOutputConfig,
17
46
  ): PluginOption {
@@ -127,17 +156,7 @@ export function startManifestPlugin(
127
156
  preloads.unshift(path.join('/', file.file))
128
157
  }
129
158
 
130
- const cssFiles = file.css ?? []
131
- const cssAssetsList: Array<RouterManagedTag> = cssFiles.map(
132
- (cssFile) => ({
133
- tag: 'link',
134
- attrs: {
135
- rel: 'stylesheet',
136
- href: joinURL('/', cssFile),
137
- type: 'text/css',
138
- },
139
- }),
140
- )
159
+ const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath)
141
160
 
142
161
  routes[k] = {
143
162
  ...v,
@@ -157,16 +176,9 @@ export function startManifestPlugin(
157
176
 
158
177
  // Gather all the CSS files from the entry file in
159
178
  // the `css` key and add them to the root route
160
- const entryCssFiles = entryFile.css ?? []
161
- const entryCssAssetsList: Array<RouterManagedTag> = entryCssFiles.map(
162
- (cssFile) => ({
163
- tag: 'link',
164
- attrs: {
165
- rel: 'stylesheet',
166
- href: joinURL('/', cssFile),
167
- type: 'text/css',
168
- },
169
- }),
179
+ const entryCssAssetsList = getCSSRecursively(
180
+ entryFile,
181
+ filesByRouteFilePath,
170
182
  )
171
183
 
172
184
  routes[rootRouteId]!.assets = [