@tanstack/start-plugin-core 1.121.29 → 1.121.30

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.
@@ -56,17 +56,6 @@ function TanStackStartVitePluginCore(opts, startConfig) {
56
56
  await dummyNitroApp.close();
57
57
  return nitroOutputPublicDir2;
58
58
  })();
59
- const getClientEntryPath = (startConfig2) => {
60
- const entry = startConfig2.clientEntryPath.startsWith(
61
- "/~start/default-client-entry"
62
- ) ? startConfig2.clientEntryPath : vite__namespace.normalizePath(
63
- path.join(
64
- "/@fs",
65
- path.resolve(startConfig2.root, startConfig2.clientEntryPath)
66
- )
67
- );
68
- return entry;
69
- };
70
59
  return {
71
60
  base: viteAppBase,
72
61
  environments: {
@@ -138,8 +127,6 @@ function TanStackStartVitePluginCore(opts, startConfig) {
138
127
  // define is an esbuild function that replaces the any instances of given keys with the given values
139
128
  // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify("TanStack Start")
140
129
  // This is not the same as injecting environment variables.
141
- ...defineReplaceEnv("TSS_CLIENT_ENTRY", getClientEntryPath(startConfig)),
142
- // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved
143
130
  ...defineReplaceEnv("TSS_SERVER_FN_BASE", startConfig.serverFns.base),
144
131
  ...defineReplaceEnv("TSS_OUTPUT_PUBLIC_DIR", nitroOutputPublicDir),
145
132
  ...defineReplaceEnv("TSS_APP_BASE", viteAppBase)
@@ -168,7 +155,7 @@ function TanStackStartVitePluginCore(opts, startConfig) {
168
155
  }
169
156
  }),
170
157
  plugin$2.loadEnvPlugin(startConfig),
171
- plugin$3.startManifestPlugin(),
158
+ plugin$3.startManifestPlugin({ clientEntry: getClientEntryPath(startConfig) }),
172
159
  plugin$4.devServerPlugin(),
173
160
  plugin$5.nitroPlugin(startConfig, () => ssrBundle),
174
161
  {
@@ -189,5 +176,16 @@ function defineReplaceEnv(key, value) {
189
176
  [`import.meta.env.${key}`]: JSON.stringify(value)
190
177
  };
191
178
  }
179
+ const getClientEntryPath = (startConfig) => {
180
+ const entry = startConfig.clientEntryPath.startsWith(
181
+ "/~start/default-client-entry"
182
+ ) ? startConfig.clientEntryPath : vite__namespace.normalizePath(
183
+ path.join(
184
+ "/@fs",
185
+ path.resolve(startConfig.root, startConfig.clientEntryPath)
186
+ )
187
+ );
188
+ return entry;
189
+ };
192
190
  exports.TanStackStartVitePluginCore = TanStackStartVitePluginCore;
193
191
  //# sourceMappingURL=plugin.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { trimPathRight } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport { createTanStackConfig } from './schema'\nimport { nitroPlugin } from './nitro-plugin/plugin'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin'\nimport {\n CLIENT_DIST_DIR,\n SSR_ENTRY_FILE,\n VITE_ENVIRONMENT_NAMES,\n} from './constants'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'\nimport type { createTanStackStartOptionsSchema } from './schema'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nexport type TanStackStartInputConfig = z.input<\n ReturnType<typeof createTanStackStartOptionsSchema>\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 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 tanStackStartRouter({\n ...startConfig.tsr,\n target: opts.framework,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config(viteConfig) {\n const viteAppBase = trimPathRight(viteConfig.base || '/')\n globalThis.TSS_APP_BASE = viteAppBase\n\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 base: viteAppBase,\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, CLIENT_DIST_DIR),\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: SSR_ENTRY_FILE,\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 'nitropack',\n '@tanstack/**start**',\n ...Object.values(VIRTUAL_MODULES),\n ],\n },\n optimizeDeps: {\n exclude: [...Object.values(VIRTUAL_MODULES)],\n },\n /* prettier-ignore */\n define: {\n // define is an esbuild function that replaces the any instances of given keys with the given values\n // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify(\"TanStack Start\")\n // This is not the same as injecting environment variables.\n\n ...defineReplaceEnv('TSS_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 ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n ...defineReplaceEnv('TSS_APP_BASE', viteAppBase)\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n startCompilerPlugin(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: VIRTUAL_MODULES.serverFnManifest,\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 }),\n loadEnvPlugin(startConfig),\n startManifestPlugin(startConfig),\n devServerPlugin(),\n nitroPlugin(startConfig, () => ssrBundle),\n {\n name: 'tanstack-start:core:capture-client-bundle',\n applyToEnvironment(e) {\n return e.config.consumer === 'client'\n },\n enforce: 'post',\n generateBundle(_options, bundle) {\n globalThis.TSS_CLIENT_BUNDLE = bundle\n },\n },\n ]\n}\n\nfunction defineReplaceEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n"],"names":["createTanStackConfig","tanStackStartRouter","resolveVirtualEntriesPlugin","trimPathRight","createNitro","nitroOutputPublicDir","startConfig","vite","VITE_ENVIRONMENT_NAMES","CLIENT_DIST_DIR","SSR_ENTRY_FILE","VIRTUAL_MODULES","startCompilerPlugin","TanStackServerFnPluginEnv","loadEnvPlugin","startManifestPlugin","devServerPlugin","nitroPlugin"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BsBA,OAAqB,qBAAA;AAmB3C,IAAI;AAEY,SAAA,4BACd,MACA,aACqB;AACd,SAAA;AAAA,IACLC,2BAAoB;AAAA,MAClB,GAAG,YAAY;AAAA,MACf,QAAQ,KAAK;AAAA,MACb,mBAAmB;AAAA,IAAA,CACpB;AAAA,IACDC,SAAA,4BAA4B,MAAM,WAAW;AAAA,IAC7C;AAAA,MACE,MAAM;AAAA,MACN,MAAM,OAAO,YAAY;AACvB,cAAM,cAAcC,WAAA,cAAc,WAAW,QAAQ,GAAG;AACxD,mBAAW,eAAe;AAEpB,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,MAAM;AAAA,UACN,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,MAAMC,UAAe,eAAA;AAAA,kBACrD;AAAA;AAAA,kBAEA,UAAU,CAAC,WAAW,aAAa,WAAW,aAAa;AAAA,gBAAA;AAAA,cAC7D;AAAA,YAEJ;AAAA,YACA,CAACD,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,gBAAgBE,UAAAA;AAAAA,kBAClB;AAAA,kBACA,SAAS;AAAA,oBACP;AAAA,sBACE,MAAM;AAAA,sBACN,eAAe,UAAU,QAAQ;AAEnB,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,GAAG,OAAO,OAAOC,gBAAe,eAAA;AAAA,YAAA;AAAA,UAEpC;AAAA,UACA,cAAc;AAAA,YACZ,SAAS,CAAC,GAAG,OAAO,OAAOA,gBAAAA,eAAe,CAAC;AAAA,UAC7C;AAAA;AAAA,UAEA,QAAQ;AAAA;AAAA;AAAA;AAAA,YAKN,GAAG,iBAAiB,oBAAoB,mBAAmB,WAAW,CAAC;AAAA;AAAA,YACvE,GAAG,iBAAiB,sBAAsB,YAAY,UAAU,IAAI;AAAA,YACpE,GAAG,iBAAiB,yBAAyB,oBAAoB;AAAA,YACjE,GAAG,iBAAiB,gBAAgB,WAAW;AAAA,UAAA;AAAA,QAEnD;AAAA,MAAA;AAAA,IAEJ;AAAA;AAAA,IAEAC,oBAAA,oBAAoB,KAAK,WAAW;AAAA,MAClC,QAAQ,EAAE,SAASJ,UAAA,uBAAuB,OAAO;AAAA,MACjD,QAAQ,EAAE,SAASA,UAAAA,uBAAuB,OAAO;AAAA,IAAA,CAClD;AAAA,IACDK,gDAA0B;AAAA;AAAA;AAAA,MAGxB,yBAAyBF,gBAAgB,gBAAA;AAAA,MACzC,QAAQ;AAAA,QACN,gBAAgB,MACd,8CAA8C,KAAK,SAAS;AAAA,QAC9D,UAAU,CAAC,MACT,oBAAoB,EAAE,UAAU,OAAO,YAAY,UAAU,IAAI;AAAA,QACnE,SAASH,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,MAAA;AAAA,IAClC,CACD;AAAA,IACDM,SAAAA,cAAc,WAAW;AAAA,IACzBC,SAAAA,oBAA+B;AAAA,IAC/BC,yBAAgB;AAAA,IAChBC,qBAAY,aAAa,MAAM,SAAS;AAAA,IACxC;AAAA,MACE,MAAM;AAAA,MACN,mBAAmB,GAAG;AACb,eAAA,EAAE,OAAO,aAAa;AAAA,MAC/B;AAAA,MACA,SAAS;AAAA,MACT,eAAe,UAAU,QAAQ;AAC/B,mBAAW,oBAAoB;AAAA,MAAA;AAAA,IACjC;AAAA,EAEJ;AACF;AAEA,SAAS,iBACP,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;;"}
1
+ {"version":3,"file":"plugin.cjs","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { trimPathRight } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport { createTanStackConfig } from './schema'\nimport { nitroPlugin } from './nitro-plugin/plugin'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin'\nimport {\n CLIENT_DIST_DIR,\n SSR_ENTRY_FILE,\n VITE_ENVIRONMENT_NAMES,\n} from './constants'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'\nimport type { createTanStackStartOptionsSchema } from './schema'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nexport type TanStackStartInputConfig = z.input<\n ReturnType<typeof createTanStackStartOptionsSchema>\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 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 tanStackStartRouter({\n ...startConfig.tsr,\n target: opts.framework,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config(viteConfig) {\n const viteAppBase = trimPathRight(viteConfig.base || '/')\n globalThis.TSS_APP_BASE = viteAppBase\n\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 return {\n base: viteAppBase,\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, CLIENT_DIST_DIR),\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: SSR_ENTRY_FILE,\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 'nitropack',\n '@tanstack/**start**',\n ...Object.values(VIRTUAL_MODULES),\n ],\n },\n optimizeDeps: {\n exclude: [...Object.values(VIRTUAL_MODULES)],\n },\n /* prettier-ignore */\n define: {\n // define is an esbuild function that replaces the any instances of given keys with the given values\n // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify(\"TanStack Start\")\n // This is not the same as injecting environment variables.\n\n ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n ...defineReplaceEnv('TSS_APP_BASE', viteAppBase)\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n startCompilerPlugin(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: VIRTUAL_MODULES.serverFnManifest,\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 }),\n loadEnvPlugin(startConfig),\n startManifestPlugin({ clientEntry: getClientEntryPath(startConfig) }),\n devServerPlugin(),\n nitroPlugin(startConfig, () => ssrBundle),\n {\n name: 'tanstack-start:core:capture-client-bundle',\n applyToEnvironment(e) {\n return e.config.consumer === 'client'\n },\n enforce: 'post',\n generateBundle(_options, bundle) {\n globalThis.TSS_CLIENT_BUNDLE = bundle\n },\n },\n ]\n}\n\nfunction defineReplaceEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n\nconst 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"],"names":["createTanStackConfig","tanStackStartRouter","resolveVirtualEntriesPlugin","trimPathRight","createNitro","nitroOutputPublicDir","VITE_ENVIRONMENT_NAMES","CLIENT_DIST_DIR","SSR_ENTRY_FILE","VIRTUAL_MODULES","startCompilerPlugin","TanStackServerFnPluginEnv","loadEnvPlugin","startManifestPlugin","devServerPlugin","nitroPlugin","vite"],"mappings":"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"}
@@ -56,12 +56,13 @@ function startManifestPlugin(opts) {
56
56
  if (this.environment.config.consumer !== "server") {
57
57
  return `export default {}`;
58
58
  }
59
+ const APP_BASE = globalThis.TSS_APP_BASE;
59
60
  if (config.command === "serve") {
60
61
  return `export const tsrStartManifest = () => ({
61
- routes: {}
62
+ routes: {},
63
+ clientEntry: '${ufo.joinURL(APP_BASE, opts.clientEntry)}',
62
64
  })`;
63
65
  }
64
- const APP_BASE = globalThis.TSS_APP_BASE;
65
66
  const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes;
66
67
  let entryFile;
67
68
  const clientBundle = globalThis.TSS_CLIENT_BUNDLE;
@@ -133,28 +134,22 @@ function startManifestPlugin(opts) {
133
134
  });
134
135
  }
135
136
  });
136
- if (entryFile) {
137
- routeTreeRoutes[routerCore.rootRouteId].preloads = [
138
- ufo.joinURL(APP_BASE, entryFile.fileName),
139
- ...entryFile.imports.map((d) => ufo.joinURL(APP_BASE, d))
140
- ];
141
- const entryCssAssetsList = getCSSRecursively(
142
- entryFile,
143
- chunksByFileName,
144
- APP_BASE
145
- );
146
- routeTreeRoutes[routerCore.rootRouteId].assets = [
147
- ...routeTreeRoutes[routerCore.rootRouteId].assets || [],
148
- ...entryCssAssetsList,
149
- {
150
- tag: "script",
151
- attrs: {
152
- src: ufo.joinURL(APP_BASE, entryFile.fileName),
153
- type: "module"
154
- }
155
- }
156
- ];
137
+ if (!entryFile) {
138
+ throw new Error("No entry file found");
157
139
  }
140
+ routeTreeRoutes[routerCore.rootRouteId].preloads = [
141
+ ufo.joinURL(APP_BASE, entryFile.fileName),
142
+ ...entryFile.imports.map((d) => ufo.joinURL(APP_BASE, d))
143
+ ];
144
+ const entryCssAssetsList = getCSSRecursively(
145
+ entryFile,
146
+ chunksByFileName,
147
+ APP_BASE
148
+ );
149
+ routeTreeRoutes[routerCore.rootRouteId].assets = [
150
+ ...routeTreeRoutes[routerCore.rootRouteId].assets || [],
151
+ ...entryCssAssetsList
152
+ ];
158
153
  const recurseRoute = (route, seenPreloads = {}) => {
159
154
  var _a;
160
155
  route.preloads = (_a = route.preloads) == null ? void 0 : _a.filter((preload) => {
@@ -173,7 +168,8 @@ function startManifestPlugin(opts) {
173
168
  };
174
169
  recurseRoute(routeTreeRoutes[routerCore.rootRouteId]);
175
170
  const routesManifest = {
176
- routes: routeTreeRoutes
171
+ routes: routeTreeRoutes,
172
+ clientEntry: ufo.joinURL(APP_BASE, entryFile.fileName)
177
173
  };
178
174
  return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`;
179
175
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport type { PluginOption, ResolvedConfig, Rollup } from 'vite'\nimport type { RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport const getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(importedChunk, chunksByFileName, basePath),\n )\n }\n }\n\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {}\n })`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = globalThis.TSS_CLIENT_BUNDLE\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const assetPath = joinURL(APP_BASE, d)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(path.join(APP_BASE, chunk.fileName))\n\n const cssAssetsList = getCSSRecursively(\n chunk,\n chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads: [...(v.preloads || []), ...preloads],\n }\n })\n }\n })\n\n if (entryFile) {\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.fileName),\n ...entryFile.imports.map((d) => joinURL(APP_BASE, d)),\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 chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL(APP_BASE, entryFile.fileName),\n type: 'module',\n },\n },\n ]\n }\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(routeTreeRoutes[rootRouteId]!)\n\n const routesManifest = {\n routes: routeTreeRoutes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["joinURL","resolveViteId","VIRTUAL_MODULES","id","tsrSplit","rootRouteId"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.cjs","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport type { PluginOption, ResolvedConfig, Rollup } from 'vite'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nexport const getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(importedChunk, chunksByFileName, basePath),\n )\n }\n }\n\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(opts: {\n clientEntry: string\n}): PluginOption {\n let config: ResolvedConfig\n\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(APP_BASE, opts.clientEntry)}',\n })`\n }\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = globalThis.TSS_CLIENT_BUNDLE\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const assetPath = joinURL(APP_BASE, d)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(path.join(APP_BASE, chunk.fileName))\n\n const cssAssetsList = getCSSRecursively(\n chunk,\n chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads: [...(v.preloads || []), ...preloads],\n }\n })\n }\n })\n\n if (!entryFile) {\n throw new Error('No entry file found')\n }\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.fileName),\n ...entryFile.imports.map((d) => joinURL(APP_BASE, d)),\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 chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n ]\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(routeTreeRoutes[rootRouteId]!)\n\n const routesManifest = {\n routes: routeTreeRoutes,\n clientEntry: joinURL(APP_BASE, entryFile.fileName),\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["joinURL","resolveViteId","VIRTUAL_MODULES","id","tsrSplit","rootRouteId"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { PluginOption, Rollup } from 'vite';
2
2
  import { RouterManagedTag } from '@tanstack/router-core';
3
- import { TanStackStartOutputConfig } from '../plugin.cjs';
4
3
  export declare const getCSSRecursively: (chunk: Rollup.OutputChunk, chunksByFileName: Map<string, Rollup.OutputChunk>, basePath: string) => RouterManagedTag[];
5
- export declare function startManifestPlugin(opts: TanStackStartOutputConfig): PluginOption;
4
+ export declare function startManifestPlugin(opts: {
5
+ clientEntry: string;
6
+ }): PluginOption;
@@ -37,17 +37,6 @@ function TanStackStartVitePluginCore(opts, startConfig) {
37
37
  await dummyNitroApp.close();
38
38
  return nitroOutputPublicDir2;
39
39
  })();
40
- const getClientEntryPath = (startConfig2) => {
41
- const entry = startConfig2.clientEntryPath.startsWith(
42
- "/~start/default-client-entry"
43
- ) ? startConfig2.clientEntryPath : vite.normalizePath(
44
- path.join(
45
- "/@fs",
46
- path.resolve(startConfig2.root, startConfig2.clientEntryPath)
47
- )
48
- );
49
- return entry;
50
- };
51
40
  return {
52
41
  base: viteAppBase,
53
42
  environments: {
@@ -119,8 +108,6 @@ function TanStackStartVitePluginCore(opts, startConfig) {
119
108
  // define is an esbuild function that replaces the any instances of given keys with the given values
120
109
  // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify("TanStack Start")
121
110
  // This is not the same as injecting environment variables.
122
- ...defineReplaceEnv("TSS_CLIENT_ENTRY", getClientEntryPath(startConfig)),
123
- // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved
124
111
  ...defineReplaceEnv("TSS_SERVER_FN_BASE", startConfig.serverFns.base),
125
112
  ...defineReplaceEnv("TSS_OUTPUT_PUBLIC_DIR", nitroOutputPublicDir),
126
113
  ...defineReplaceEnv("TSS_APP_BASE", viteAppBase)
@@ -149,7 +136,7 @@ function TanStackStartVitePluginCore(opts, startConfig) {
149
136
  }
150
137
  }),
151
138
  loadEnvPlugin(startConfig),
152
- startManifestPlugin(),
139
+ startManifestPlugin({ clientEntry: getClientEntryPath(startConfig) }),
153
140
  devServerPlugin(),
154
141
  nitroPlugin(startConfig, () => ssrBundle),
155
142
  {
@@ -170,6 +157,17 @@ function defineReplaceEnv(key, value) {
170
157
  [`import.meta.env.${key}`]: JSON.stringify(value)
171
158
  };
172
159
  }
160
+ const getClientEntryPath = (startConfig) => {
161
+ const entry = startConfig.clientEntryPath.startsWith(
162
+ "/~start/default-client-entry"
163
+ ) ? startConfig.clientEntryPath : vite.normalizePath(
164
+ path.join(
165
+ "/@fs",
166
+ path.resolve(startConfig.root, startConfig.clientEntryPath)
167
+ )
168
+ );
169
+ return entry;
170
+ };
173
171
  export {
174
172
  TanStackStartVitePluginCore
175
173
  };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../src/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { createNitro } from 'nitropack'\nimport { trimPathRight } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport { createTanStackConfig } from './schema'\nimport { nitroPlugin } from './nitro-plugin/plugin'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin'\nimport {\n CLIENT_DIST_DIR,\n SSR_ENTRY_FILE,\n VITE_ENVIRONMENT_NAMES,\n} from './constants'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'\nimport type { createTanStackStartOptionsSchema } from './schema'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nexport type TanStackStartInputConfig = z.input<\n ReturnType<typeof createTanStackStartOptionsSchema>\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 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 tanStackStartRouter({\n ...startConfig.tsr,\n target: opts.framework,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config(viteConfig) {\n const viteAppBase = trimPathRight(viteConfig.base || '/')\n globalThis.TSS_APP_BASE = viteAppBase\n\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 base: viteAppBase,\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, CLIENT_DIST_DIR),\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: SSR_ENTRY_FILE,\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 'nitropack',\n '@tanstack/**start**',\n ...Object.values(VIRTUAL_MODULES),\n ],\n },\n optimizeDeps: {\n exclude: [...Object.values(VIRTUAL_MODULES)],\n },\n /* prettier-ignore */\n define: {\n // define is an esbuild function that replaces the any instances of given keys with the given values\n // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify(\"TanStack Start\")\n // This is not the same as injecting environment variables.\n\n ...defineReplaceEnv('TSS_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 ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n ...defineReplaceEnv('TSS_APP_BASE', viteAppBase)\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n startCompilerPlugin(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: VIRTUAL_MODULES.serverFnManifest,\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 }),\n loadEnvPlugin(startConfig),\n startManifestPlugin(startConfig),\n devServerPlugin(),\n nitroPlugin(startConfig, () => ssrBundle),\n {\n name: 'tanstack-start:core:capture-client-bundle',\n applyToEnvironment(e) {\n return e.config.consumer === 'client'\n },\n enforce: 'post',\n generateBundle(_options, bundle) {\n globalThis.TSS_CLIENT_BUNDLE = bundle\n },\n },\n ]\n}\n\nfunction defineReplaceEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n"],"names":["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 { trimPathRight } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'\nimport * as vite from 'vite'\nimport { createTanStackConfig } from './schema'\nimport { nitroPlugin } from './nitro-plugin/plugin'\nimport { startManifestPlugin } from './start-manifest-plugin/plugin'\nimport { startCompilerPlugin } from './start-compiler-plugin'\nimport {\n CLIENT_DIST_DIR,\n SSR_ENTRY_FILE,\n VITE_ENVIRONMENT_NAMES,\n} from './constants'\nimport { tanStackStartRouter } from './start-router-plugin/plugin'\nimport { loadEnvPlugin } from './load-env-plugin/plugin'\nimport { devServerPlugin } from './dev-server-plugin/plugin'\nimport { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'\nimport type { createTanStackStartOptionsSchema } from './schema'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { z } from 'zod'\nimport type { CompileStartFrameworkOptions } from './compilers'\n\nexport type TanStackStartInputConfig = z.input<\n ReturnType<typeof createTanStackStartOptionsSchema>\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 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 tanStackStartRouter({\n ...startConfig.tsr,\n target: opts.framework,\n autoCodeSplitting: true,\n }),\n resolveVirtualEntriesPlugin(opts, startConfig),\n {\n name: 'tanstack-start-core:config-client',\n async config(viteConfig) {\n const viteAppBase = trimPathRight(viteConfig.base || '/')\n globalThis.TSS_APP_BASE = viteAppBase\n\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 return {\n base: viteAppBase,\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, CLIENT_DIST_DIR),\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: SSR_ENTRY_FILE,\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 'nitropack',\n '@tanstack/**start**',\n ...Object.values(VIRTUAL_MODULES),\n ],\n },\n optimizeDeps: {\n exclude: [...Object.values(VIRTUAL_MODULES)],\n },\n /* prettier-ignore */\n define: {\n // define is an esbuild function that replaces the any instances of given keys with the given values\n // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify(\"TanStack Start\")\n // This is not the same as injecting environment variables.\n\n ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),\n ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),\n ...defineReplaceEnv('TSS_APP_BASE', viteAppBase)\n },\n }\n },\n },\n // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv\n startCompilerPlugin(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: VIRTUAL_MODULES.serverFnManifest,\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 }),\n loadEnvPlugin(startConfig),\n startManifestPlugin({ clientEntry: getClientEntryPath(startConfig) }),\n devServerPlugin(),\n nitroPlugin(startConfig, () => ssrBundle),\n {\n name: 'tanstack-start:core:capture-client-bundle',\n applyToEnvironment(e) {\n return e.config.consumer === 'client'\n },\n enforce: 'post',\n generateBundle(_options, bundle) {\n globalThis.TSS_CLIENT_BUNDLE = bundle\n },\n },\n ]\n}\n\nfunction defineReplaceEnv<TKey extends string, TValue extends string>(\n key: TKey,\n value: TValue,\n): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {\n return {\n [`process.env.${key}`]: JSON.stringify(value),\n [`import.meta.env.${key}`]: JSON.stringify(value),\n } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }\n}\n\nconst 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"],"names":["nitroOutputPublicDir"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  import { PluginOption, Rollup } from 'vite';
2
2
  import { RouterManagedTag } from '@tanstack/router-core';
3
- import { TanStackStartOutputConfig } from '../plugin.js';
4
3
  export declare const getCSSRecursively: (chunk: Rollup.OutputChunk, chunksByFileName: Map<string, Rollup.OutputChunk>, basePath: string) => RouterManagedTag[];
5
- export declare function startManifestPlugin(opts: TanStackStartOutputConfig): PluginOption;
4
+ export declare function startManifestPlugin(opts: {
5
+ clientEntry: string;
6
+ }): PluginOption;
@@ -54,12 +54,13 @@ function startManifestPlugin(opts) {
54
54
  if (this.environment.config.consumer !== "server") {
55
55
  return `export default {}`;
56
56
  }
57
+ const APP_BASE = globalThis.TSS_APP_BASE;
57
58
  if (config.command === "serve") {
58
59
  return `export const tsrStartManifest = () => ({
59
- routes: {}
60
+ routes: {},
61
+ clientEntry: '${joinURL(APP_BASE, opts.clientEntry)}',
60
62
  })`;
61
63
  }
62
- const APP_BASE = globalThis.TSS_APP_BASE;
63
64
  const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes;
64
65
  let entryFile;
65
66
  const clientBundle = globalThis.TSS_CLIENT_BUNDLE;
@@ -131,28 +132,22 @@ function startManifestPlugin(opts) {
131
132
  });
132
133
  }
133
134
  });
134
- if (entryFile) {
135
- routeTreeRoutes[rootRouteId].preloads = [
136
- joinURL(APP_BASE, entryFile.fileName),
137
- ...entryFile.imports.map((d) => joinURL(APP_BASE, d))
138
- ];
139
- const entryCssAssetsList = getCSSRecursively(
140
- entryFile,
141
- chunksByFileName,
142
- APP_BASE
143
- );
144
- routeTreeRoutes[rootRouteId].assets = [
145
- ...routeTreeRoutes[rootRouteId].assets || [],
146
- ...entryCssAssetsList,
147
- {
148
- tag: "script",
149
- attrs: {
150
- src: joinURL(APP_BASE, entryFile.fileName),
151
- type: "module"
152
- }
153
- }
154
- ];
135
+ if (!entryFile) {
136
+ throw new Error("No entry file found");
155
137
  }
138
+ routeTreeRoutes[rootRouteId].preloads = [
139
+ joinURL(APP_BASE, entryFile.fileName),
140
+ ...entryFile.imports.map((d) => joinURL(APP_BASE, d))
141
+ ];
142
+ const entryCssAssetsList = getCSSRecursively(
143
+ entryFile,
144
+ chunksByFileName,
145
+ APP_BASE
146
+ );
147
+ routeTreeRoutes[rootRouteId].assets = [
148
+ ...routeTreeRoutes[rootRouteId].assets || [],
149
+ ...entryCssAssetsList
150
+ ];
156
151
  const recurseRoute = (route, seenPreloads = {}) => {
157
152
  var _a;
158
153
  route.preloads = (_a = route.preloads) == null ? void 0 : _a.filter((preload) => {
@@ -171,7 +166,8 @@ function startManifestPlugin(opts) {
171
166
  };
172
167
  recurseRoute(routeTreeRoutes[rootRouteId]);
173
168
  const routesManifest = {
174
- routes: routeTreeRoutes
169
+ routes: routeTreeRoutes,
170
+ clientEntry: joinURL(APP_BASE, entryFile.fileName)
175
171
  };
176
172
  return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`;
177
173
  }
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport type { PluginOption, ResolvedConfig, Rollup } from 'vite'\nimport type { RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport const getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(importedChunk, chunksByFileName, basePath),\n )\n }\n }\n\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {}\n })`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = globalThis.TSS_CLIENT_BUNDLE\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const assetPath = joinURL(APP_BASE, d)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(path.join(APP_BASE, chunk.fileName))\n\n const cssAssetsList = getCSSRecursively(\n chunk,\n chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads: [...(v.preloads || []), ...preloads],\n }\n })\n }\n })\n\n if (entryFile) {\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.fileName),\n ...entryFile.imports.map((d) => joinURL(APP_BASE, d)),\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 chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL(APP_BASE, entryFile.fileName),\n type: 'module',\n },\n },\n ]\n }\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(routeTreeRoutes[rootRouteId]!)\n\n const routesManifest = {\n routes: routeTreeRoutes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["id"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.js","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport type { PluginOption, ResolvedConfig, Rollup } from 'vite'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nexport const getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(importedChunk, chunksByFileName, basePath),\n )\n }\n }\n\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(opts: {\n clientEntry: string\n}): PluginOption {\n let config: ResolvedConfig\n\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // This is the basepath for the application\n const APP_BASE = globalThis.TSS_APP_BASE\n\n // If we're in development, return a dummy manifest\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(APP_BASE, opts.clientEntry)}',\n })`\n }\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = globalThis.TSS_CLIENT_BUNDLE\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const assetPath = joinURL(APP_BASE, d)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(path.join(APP_BASE, chunk.fileName))\n\n const cssAssetsList = getCSSRecursively(\n chunk,\n chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads: [...(v.preloads || []), ...preloads],\n }\n })\n }\n })\n\n if (!entryFile) {\n throw new Error('No entry file found')\n }\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(APP_BASE, entryFile.fileName),\n ...entryFile.imports.map((d) => joinURL(APP_BASE, d)),\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 chunksByFileName,\n APP_BASE,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n ]\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(routeTreeRoutes[rootRouteId]!)\n\n const routesManifest = {\n routes: routeTreeRoutes,\n clientEntry: joinURL(APP_BASE, entryFile.fileName),\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["id"],"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.29",
3
+ "version": "1.121.30",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -63,12 +63,12 @@
63
63
  "ufo": "^1.5.4",
64
64
  "xmlbuilder2": "^3.1.1",
65
65
  "zod": "^3.24.2",
66
- "@tanstack/router-generator": "1.121.27",
66
+ "@tanstack/router-core": "1.121.27",
67
67
  "@tanstack/router-plugin": "1.121.29",
68
+ "@tanstack/router-generator": "1.121.27",
68
69
  "@tanstack/router-utils": "1.121.21",
69
- "@tanstack/server-functions-plugin": "1.121.28",
70
- "@tanstack/start-server-core": "1.121.27",
71
- "@tanstack/router-core": "1.121.27"
70
+ "@tanstack/server-functions-plugin": "1.121.30",
71
+ "@tanstack/start-server-core": "1.121.30"
72
72
  },
73
73
  "devDependencies": {
74
74
  "vite": "^6.0.0"
package/src/plugin.ts CHANGED
@@ -77,25 +77,6 @@ export function TanStackStartVitePluginCore(
77
77
  return nitroOutputPublicDir
78
78
  })()
79
79
 
80
- const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {
81
- // when the user specifies a custom client entry path, we need to resolve it
82
- // relative to the root of the project, keeping in mind that if not specified
83
- // it will be /~start/default-client-entry which is a virtual path
84
- // that is resolved by vite to the actual client entry path
85
- const entry = startConfig.clientEntryPath.startsWith(
86
- '/~start/default-client-entry',
87
- )
88
- ? startConfig.clientEntryPath
89
- : vite.normalizePath(
90
- path.join(
91
- '/@fs',
92
- path.resolve(startConfig.root, startConfig.clientEntryPath),
93
- ),
94
- )
95
-
96
- return entry
97
- }
98
-
99
80
  return {
100
81
  base: viteAppBase,
101
82
  environments: {
@@ -169,7 +150,6 @@ export function TanStackStartVitePluginCore(
169
150
  // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify("TanStack Start")
170
151
  // This is not the same as injecting environment variables.
171
152
 
172
- ...defineReplaceEnv('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
173
153
  ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),
174
154
  ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),
175
155
  ...defineReplaceEnv('TSS_APP_BASE', viteAppBase)
@@ -202,7 +182,7 @@ export function TanStackStartVitePluginCore(
202
182
  },
203
183
  }),
204
184
  loadEnvPlugin(startConfig),
205
- startManifestPlugin(startConfig),
185
+ startManifestPlugin({ clientEntry: getClientEntryPath(startConfig) }),
206
186
  devServerPlugin(),
207
187
  nitroPlugin(startConfig, () => ssrBundle),
208
188
  {
@@ -227,3 +207,22 @@ function defineReplaceEnv<TKey extends string, TValue extends string>(
227
207
  [`import.meta.env.${key}`]: JSON.stringify(value),
228
208
  } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }
229
209
  }
210
+
211
+ const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {
212
+ // when the user specifies a custom client entry path, we need to resolve it
213
+ // relative to the root of the project, keeping in mind that if not specified
214
+ // it will be /~start/default-client-entry which is a virtual path
215
+ // that is resolved by vite to the actual client entry path
216
+ const entry = startConfig.clientEntryPath.startsWith(
217
+ '/~start/default-client-entry',
218
+ )
219
+ ? startConfig.clientEntryPath
220
+ : vite.normalizePath(
221
+ path.join(
222
+ '/@fs',
223
+ path.resolve(startConfig.root, startConfig.clientEntryPath),
224
+ ),
225
+ )
226
+
227
+ return entry
228
+ }
@@ -6,7 +6,6 @@ import { tsrSplit } from '@tanstack/router-plugin'
6
6
  import { resolveViteId } from '../utils'
7
7
  import type { PluginOption, ResolvedConfig, Rollup } from 'vite'
8
8
  import type { RouterManagedTag } from '@tanstack/router-core'
9
- import type { TanStackStartOutputConfig } from '../plugin'
10
9
 
11
10
  export const getCSSRecursively = (
12
11
  chunk: Rollup.OutputChunk,
@@ -41,9 +40,9 @@ export const getCSSRecursively = (
41
40
  }
42
41
 
43
42
  const resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)
44
- export function startManifestPlugin(
45
- opts: TanStackStartOutputConfig,
46
- ): PluginOption {
43
+ export function startManifestPlugin(opts: {
44
+ clientEntry: string
45
+ }): PluginOption {
47
46
  let config: ResolvedConfig
48
47
 
49
48
  return {
@@ -74,16 +73,17 @@ export function startManifestPlugin(
74
73
  return `export default {}`
75
74
  }
76
75
 
76
+ // This is the basepath for the application
77
+ const APP_BASE = globalThis.TSS_APP_BASE
78
+
77
79
  // If we're in development, return a dummy manifest
78
80
  if (config.command === 'serve') {
79
81
  return `export const tsrStartManifest = () => ({
80
- routes: {}
82
+ routes: {},
83
+ clientEntry: '${joinURL(APP_BASE, opts.clientEntry)}',
81
84
  })`
82
85
  }
83
86
 
84
- // This is the basepath for the application
85
- const APP_BASE = globalThis.TSS_APP_BASE
86
-
87
87
  // This the manifest pulled from the generated route tree and later used by the Router.
88
88
  // i.e what's located in `src/routeTree.gen.ts`
89
89
  const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes
@@ -177,32 +177,26 @@ export function startManifestPlugin(
177
177
  }
178
178
  })
179
179
 
180
- if (entryFile) {
181
- routeTreeRoutes[rootRouteId]!.preloads = [
182
- joinURL(APP_BASE, entryFile.fileName),
183
- ...entryFile.imports.map((d) => joinURL(APP_BASE, d)),
184
- ]
185
-
186
- // Gather all the CSS files from the entry file in
187
- // the `css` key and add them to the root route
188
- const entryCssAssetsList = getCSSRecursively(
189
- entryFile,
190
- chunksByFileName,
191
- APP_BASE,
192
- )
193
-
194
- routeTreeRoutes[rootRouteId]!.assets = [
195
- ...(routeTreeRoutes[rootRouteId]!.assets || []),
196
- ...entryCssAssetsList,
197
- {
198
- tag: 'script',
199
- attrs: {
200
- src: joinURL(APP_BASE, entryFile.fileName),
201
- type: 'module',
202
- },
203
- },
204
- ]
180
+ if (!entryFile) {
181
+ throw new Error('No entry file found')
205
182
  }
183
+ routeTreeRoutes[rootRouteId]!.preloads = [
184
+ joinURL(APP_BASE, entryFile.fileName),
185
+ ...entryFile.imports.map((d) => joinURL(APP_BASE, d)),
186
+ ]
187
+
188
+ // Gather all the CSS files from the entry file in
189
+ // the `css` key and add them to the root route
190
+ const entryCssAssetsList = getCSSRecursively(
191
+ entryFile,
192
+ chunksByFileName,
193
+ APP_BASE,
194
+ )
195
+
196
+ routeTreeRoutes[rootRouteId]!.assets = [
197
+ ...(routeTreeRoutes[rootRouteId]!.assets || []),
198
+ ...entryCssAssetsList,
199
+ ]
206
200
 
207
201
  const recurseRoute = (
208
202
  route: {
@@ -231,6 +225,7 @@ export function startManifestPlugin(
231
225
 
232
226
  const routesManifest = {
233
227
  routes: routeTreeRoutes,
228
+ clientEntry: joinURL(APP_BASE, entryFile.fileName),
234
229
  }
235
230
 
236
231
  return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`