@tanstack/start-plugin-core 1.131.10 → 1.132.0-alpha.1

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.
Files changed (145) hide show
  1. package/dist/esm/{nitro-plugin/build-sitemap.d.ts → build-sitemap.d.ts} +3 -3
  2. package/dist/esm/{nitro-plugin/build-sitemap.js → build-sitemap.js} +19 -24
  3. package/dist/esm/build-sitemap.js.map +1 -0
  4. package/dist/esm/compilers.js +7 -10
  5. package/dist/esm/compilers.js.map +1 -1
  6. package/dist/esm/constants.d.ts +6 -2
  7. package/dist/esm/constants.js +7 -10
  8. package/dist/esm/constants.js.map +1 -1
  9. package/dist/esm/debug.js.map +1 -1
  10. package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +1 -1
  11. package/dist/esm/dev-server-plugin/plugin.d.ts +5 -5
  12. package/dist/esm/dev-server-plugin/plugin.js +117 -79
  13. package/dist/esm/dev-server-plugin/plugin.js.map +1 -1
  14. package/dist/esm/index.d.ts +2 -1
  15. package/dist/esm/index.js +2 -4
  16. package/dist/esm/load-env-plugin/plugin.d.ts +2 -3
  17. package/dist/esm/load-env-plugin/plugin.js +5 -8
  18. package/dist/esm/load-env-plugin/plugin.js.map +1 -1
  19. package/dist/esm/output-directory.d.ts +3 -0
  20. package/dist/esm/output-directory.js +14 -0
  21. package/dist/esm/output-directory.js.map +1 -0
  22. package/dist/esm/plugin.d.ts +6 -290
  23. package/dist/esm/plugin.js +135 -76
  24. package/dist/esm/plugin.js.map +1 -1
  25. package/dist/esm/post-server-build.d.ts +7 -0
  26. package/dist/esm/post-server-build.js +55 -0
  27. package/dist/esm/post-server-build.js.map +1 -0
  28. package/dist/esm/prerender.d.ts +11 -0
  29. package/dist/esm/{nitro-plugin/prerender.js → prerender.js} +85 -73
  30. package/dist/esm/prerender.js.map +1 -0
  31. package/dist/esm/{nitro-plugin/queue.js → queue.js} +7 -10
  32. package/dist/esm/queue.js.map +1 -0
  33. package/dist/esm/resolve-entries.d.ts +8 -0
  34. package/dist/esm/resolve-entries.js +37 -0
  35. package/dist/esm/resolve-entries.js.map +1 -0
  36. package/dist/esm/schema.d.ts +1369 -6719
  37. package/dist/esm/schema.js +52 -85
  38. package/dist/esm/schema.js.map +1 -1
  39. package/dist/esm/start-compiler-plugin.js +2 -2
  40. package/dist/esm/start-compiler-plugin.js.map +1 -1
  41. package/dist/esm/start-manifest-plugin/plugin.d.ts +1 -1
  42. package/dist/esm/start-manifest-plugin/plugin.js +8 -13
  43. package/dist/esm/start-manifest-plugin/plugin.js.map +1 -1
  44. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +2 -3
  45. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -1
  46. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js +2 -4
  47. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js.map +1 -1
  48. package/dist/esm/start-router-plugin/plugin.js.map +1 -1
  49. package/dist/esm/start-router-plugin/route-tree-client-plugin.js.map +1 -1
  50. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js.map +1 -1
  51. package/dist/esm/utils.js.map +1 -1
  52. package/package.json +13 -18
  53. package/src/{nitro-plugin/build-sitemap.ts → build-sitemap.ts} +8 -8
  54. package/src/constants.ts +12 -9
  55. package/src/dev-server-plugin/plugin.ts +140 -99
  56. package/src/global.d.ts +0 -2
  57. package/src/index.ts +3 -5
  58. package/src/load-env-plugin/plugin.ts +6 -11
  59. package/src/output-directory.ts +18 -0
  60. package/src/plugin.ts +172 -98
  61. package/src/post-server-build.ts +73 -0
  62. package/src/{nitro-plugin/prerender.ts → prerender.ts} +93 -86
  63. package/src/resolve-entries.ts +52 -0
  64. package/src/schema.ts +88 -121
  65. package/src/start-manifest-plugin/plugin.ts +8 -14
  66. package/dist/cjs/compilers.cjs +0 -416
  67. package/dist/cjs/compilers.cjs.map +0 -1
  68. package/dist/cjs/compilers.d.cts +0 -21
  69. package/dist/cjs/constants.cjs +0 -20
  70. package/dist/cjs/constants.cjs.map +0 -1
  71. package/dist/cjs/constants.d.cts +0 -6
  72. package/dist/cjs/debug.cjs +0 -5
  73. package/dist/cjs/debug.cjs.map +0 -1
  74. package/dist/cjs/debug.d.cts +0 -1
  75. package/dist/cjs/dev-server-plugin/extract-html-scripts.cjs +0 -35
  76. package/dist/cjs/dev-server-plugin/extract-html-scripts.cjs.map +0 -1
  77. package/dist/cjs/dev-server-plugin/extract-html-scripts.d.cts +0 -4
  78. package/dist/cjs/dev-server-plugin/plugin.cjs +0 -121
  79. package/dist/cjs/dev-server-plugin/plugin.cjs.map +0 -1
  80. package/dist/cjs/dev-server-plugin/plugin.d.cts +0 -5
  81. package/dist/cjs/index.cjs +0 -11
  82. package/dist/cjs/index.cjs.map +0 -1
  83. package/dist/cjs/index.d.cts +0 -3
  84. package/dist/cjs/load-env-plugin/plugin.cjs +0 -34
  85. package/dist/cjs/load-env-plugin/plugin.cjs.map +0 -1
  86. package/dist/cjs/load-env-plugin/plugin.d.cts +0 -3
  87. package/dist/cjs/nitro-plugin/build-sitemap.cjs +0 -138
  88. package/dist/cjs/nitro-plugin/build-sitemap.cjs.map +0 -1
  89. package/dist/cjs/nitro-plugin/build-sitemap.d.cts +0 -31
  90. package/dist/cjs/nitro-plugin/plugin.cjs +0 -187
  91. package/dist/cjs/nitro-plugin/plugin.cjs.map +0 -1
  92. package/dist/cjs/nitro-plugin/plugin.d.cts +0 -3
  93. package/dist/cjs/nitro-plugin/prerender.cjs +0 -178
  94. package/dist/cjs/nitro-plugin/prerender.cjs.map +0 -1
  95. package/dist/cjs/nitro-plugin/prerender.d.cts +0 -8
  96. package/dist/cjs/nitro-plugin/queue.cjs +0 -131
  97. package/dist/cjs/nitro-plugin/queue.cjs.map +0 -1
  98. package/dist/cjs/nitro-plugin/queue.d.cts +0 -32
  99. package/dist/cjs/plugin.cjs +0 -227
  100. package/dist/cjs/plugin.cjs.map +0 -1
  101. package/dist/cjs/plugin.d.cts +0 -300
  102. package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs +0 -80
  103. package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs.map +0 -1
  104. package/dist/cjs/resolve-virtual-entries-plugin/plugin.d.cts +0 -3
  105. package/dist/cjs/schema.cjs +0 -158
  106. package/dist/cjs/schema.cjs.map +0 -1
  107. package/dist/cjs/schema.d.cts +0 -8878
  108. package/dist/cjs/start-compiler-plugin.cjs +0 -78
  109. package/dist/cjs/start-compiler-plugin.cjs.map +0 -1
  110. package/dist/cjs/start-compiler-plugin.d.cts +0 -13
  111. package/dist/cjs/start-manifest-plugin/plugin.cjs +0 -182
  112. package/dist/cjs/start-manifest-plugin/plugin.cjs.map +0 -1
  113. package/dist/cjs/start-manifest-plugin/plugin.d.cts +0 -6
  114. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs +0 -39
  115. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs.map +0 -1
  116. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.d.cts +0 -6
  117. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs +0 -121
  118. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs.map +0 -1
  119. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.d.cts +0 -2
  120. package/dist/cjs/start-router-plugin/plugin.cjs +0 -45
  121. package/dist/cjs/start-router-plugin/plugin.cjs.map +0 -1
  122. package/dist/cjs/start-router-plugin/plugin.d.cts +0 -3
  123. package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs +0 -73
  124. package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs.map +0 -1
  125. package/dist/cjs/start-router-plugin/route-tree-client-plugin.d.cts +0 -6
  126. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs +0 -29
  127. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs.map +0 -1
  128. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.d.cts +0 -3
  129. package/dist/cjs/utils.cjs +0 -18
  130. package/dist/cjs/utils.cjs.map +0 -1
  131. package/dist/cjs/utils.d.cts +0 -8
  132. package/dist/esm/nitro-plugin/build-sitemap.js.map +0 -1
  133. package/dist/esm/nitro-plugin/plugin.d.ts +0 -3
  134. package/dist/esm/nitro-plugin/plugin.js +0 -187
  135. package/dist/esm/nitro-plugin/plugin.js.map +0 -1
  136. package/dist/esm/nitro-plugin/prerender.d.ts +0 -8
  137. package/dist/esm/nitro-plugin/prerender.js.map +0 -1
  138. package/dist/esm/nitro-plugin/queue.js.map +0 -1
  139. package/dist/esm/resolve-virtual-entries-plugin/plugin.d.ts +0 -3
  140. package/dist/esm/resolve-virtual-entries-plugin/plugin.js +0 -63
  141. package/dist/esm/resolve-virtual-entries-plugin/plugin.js.map +0 -1
  142. package/src/nitro-plugin/plugin.ts +0 -252
  143. package/src/resolve-virtual-entries-plugin/plugin.ts +0 -77
  144. /package/dist/esm/{nitro-plugin/queue.d.ts → queue.d.ts} +0 -0
  145. /package/src/{nitro-plugin/queue.ts → queue.ts} +0 -0
package/src/plugin.ts CHANGED
@@ -1,76 +1,125 @@
1
1
  import path from 'node:path'
2
- import { createNitro } from 'nitropack'
3
2
  import { trimPathRight } from '@tanstack/router-core'
4
3
  import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
5
4
  import { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'
6
5
  import * as vite from 'vite'
7
6
  import { crawlFrameworkPkgs } from 'vitefu'
8
- import { createTanStackConfig } from './schema'
9
- import { nitroPlugin } from './nitro-plugin/plugin'
7
+ import { join } from 'pathe'
10
8
  import { startManifestPlugin } from './start-manifest-plugin/plugin'
11
9
  import { startCompilerPlugin } from './start-compiler-plugin'
12
- import {
13
- CLIENT_DIST_DIR,
14
- SSR_ENTRY_FILE,
15
- VITE_ENVIRONMENT_NAMES,
16
- } from './constants'
10
+ import { ENTRY_POINTS, VITE_ENVIRONMENT_NAMES } from './constants'
17
11
  import { tanStackStartRouter } from './start-router-plugin/plugin'
18
12
  import { loadEnvPlugin } from './load-env-plugin/plugin'
19
13
  import { devServerPlugin } from './dev-server-plugin/plugin'
20
- import { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'
21
- import type { createTanStackStartOptionsSchema } from './schema'
22
- import type { PluginOption, Rollup } from 'vite'
23
- import type { z } from 'zod'
14
+ import { parseStartConfig } from './schema'
15
+ import { resolveEntry } from './resolve-entries'
16
+ import {
17
+ getClientOutputDirectory,
18
+ getServerOutputDirectory,
19
+ } from './output-directory'
20
+ import { postServerBuild } from './post-server-build'
21
+ import type { ViteEnvironmentNames } from './constants'
22
+ import type { TanStackStartInputConfig } from './schema'
23
+ import type { PluginOption } from 'vite'
24
24
  import type { CompileStartFrameworkOptions } from './compilers'
25
25
 
26
- export type TanStackStartInputConfig = z.input<
27
- ReturnType<typeof createTanStackStartOptionsSchema>
28
- >
29
-
30
- const defaultConfig = createTanStackConfig()
31
- export function getTanStackStartOptions(opts?: TanStackStartInputConfig) {
32
- return defaultConfig.parse(opts)
33
- }
34
-
35
- export type TanStackStartOutputConfig = ReturnType<
36
- typeof getTanStackStartOptions
37
- >
38
-
39
26
  export interface TanStackStartVitePluginCoreOptions {
40
27
  framework: CompileStartFrameworkOptions
41
- getVirtualServerRootHandler: (ctx: {
42
- routerFilepath: string
43
- serverEntryFilepath: string
44
- }) => string
45
- getVirtualServerEntry: (ctx: { routerFilepath: string }) => string
46
- getVirtualClientEntry: (ctx: { routerFilepath: string }) => string
28
+ defaultEntryPaths: {
29
+ client: string
30
+ server: string
31
+ }
47
32
  crawlPackages?: (opts: {
48
33
  name: string
49
34
  peerDependencies: Record<string, any>
50
35
  exports?: Record<string, any> | string
51
36
  }) => 'include' | 'exclude' | undefined
52
37
  }
53
- // this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite
54
- let ssrBundle: Rollup.OutputBundle
55
38
 
56
39
  export function TanStackStartVitePluginCore(
57
- opts: TanStackStartVitePluginCoreOptions,
58
- startConfig: TanStackStartOutputConfig,
40
+ corePluginOpts: TanStackStartVitePluginCoreOptions,
41
+ startPluginOpts: TanStackStartInputConfig,
59
42
  ): Array<PluginOption> {
43
+ const startConfig = parseStartConfig(startPluginOpts)
44
+
45
+ const capturedBundle: Partial<
46
+ Record<ViteEnvironmentNames, vite.Rollup.OutputBundle>
47
+ > = {}
48
+
49
+ function getBundle(envName: ViteEnvironmentNames): vite.Rollup.OutputBundle {
50
+ const bundle = capturedBundle[envName]
51
+ if (!bundle) {
52
+ throw new Error(`No bundle captured for environment: ${envName}`)
53
+ }
54
+ return bundle
55
+ }
56
+
60
57
  return [
61
58
  tanStackStartRouter({
62
59
  ...startConfig.tsr,
63
- target: opts.framework,
60
+ target: corePluginOpts.framework,
64
61
  autoCodeSplitting: true,
65
62
  }),
66
- resolveVirtualEntriesPlugin(opts, startConfig),
67
63
  {
68
- name: 'tanstack-start-core:config-client',
64
+ name: 'tanstack-start-core:config',
69
65
  async config(viteConfig, { command }) {
70
66
  const viteAppBase = trimPathRight(viteConfig.base || '/')
71
67
  globalThis.TSS_APP_BASE = viteAppBase
72
68
 
73
- const nitroOutputPublicDir = await (async () => {
69
+ const root = viteConfig.root || process.cwd()
70
+ const resolvedSrcDirectory = join(root, startConfig.tsr.srcDirectory)
71
+
72
+ const routerFilePath = resolveEntry({
73
+ type: 'router entry',
74
+ configuredEntry: startConfig.router.entry,
75
+ defaultEntry: 'router',
76
+ root,
77
+ resolvedSrcDirectory,
78
+ required: true,
79
+ })
80
+ const clientEntryPath = resolveEntry({
81
+ type: 'client entry',
82
+ configuredEntry: startConfig.client.entry,
83
+ defaultEntry: 'client',
84
+ root,
85
+ resolvedSrcDirectory,
86
+ required: false,
87
+ })
88
+
89
+ const serverEntryPath = resolveEntry({
90
+ type: 'server entry',
91
+ configuredEntry: startConfig.server.entry,
92
+ defaultEntry: 'server',
93
+ root,
94
+ resolvedSrcDirectory,
95
+ required: false,
96
+ })
97
+
98
+ let clientAlias: string
99
+ if (clientEntryPath) {
100
+ clientAlias = vite.normalizePath(
101
+ path.join('/@fs', path.resolve(root, clientEntryPath)),
102
+ )
103
+ } else {
104
+ clientAlias = corePluginOpts.defaultEntryPaths.client
105
+ }
106
+ let serverAlias: string
107
+ if (serverEntryPath) {
108
+ serverAlias = vite.normalizePath(path.resolve(root, serverEntryPath))
109
+ } else {
110
+ serverAlias = corePluginOpts.defaultEntryPaths.server
111
+ }
112
+ const entryAliasConfiguration: Record<
113
+ (typeof ENTRY_POINTS)[keyof typeof ENTRY_POINTS],
114
+ string
115
+ > = {
116
+ [ENTRY_POINTS.router]: routerFilePath,
117
+ [ENTRY_POINTS.client]: clientAlias,
118
+ [ENTRY_POINTS.server]: serverAlias,
119
+ }
120
+
121
+ // TODO
122
+ /* const nitroOutputPublicDir = await (async () => {
74
123
  // Create a dummy nitro app to get the resolved public output path
75
124
  const dummyNitroApp = await createNitro({
76
125
  preset: startConfig.target,
@@ -81,10 +130,10 @@ export function TanStackStartVitePluginCore(
81
130
  await dummyNitroApp.close()
82
131
 
83
132
  return nitroOutputPublicDir
84
- })()
133
+ })()*/
85
134
 
86
- const startPackageName = `@tanstack/${opts.framework}-start`
87
- const routerPackageName = `@tanstack/${opts.framework}-router`
135
+ const startPackageName = `@tanstack/${corePluginOpts.framework}-start`
136
+ const routerPackageName = `@tanstack/${corePluginOpts.framework}-router`
88
137
 
89
138
  const additionalOptimizeDeps = {
90
139
  include: new Set<string>(),
@@ -108,7 +157,7 @@ export function TanStackStartVitePluginCore(
108
157
  const peerDependencies = pkgJson['peerDependencies']
109
158
 
110
159
  if (peerDependencies) {
111
- const internalResult = opts.crawlPackages?.({
160
+ const internalResult = corePluginOpts.crawlPackages?.({
112
161
  name: pkgJson.name,
113
162
  peerDependencies,
114
163
  exports: pkgJson.exports,
@@ -131,61 +180,70 @@ export function TanStackStartVitePluginCore(
131
180
 
132
181
  return {
133
182
  base: viteAppBase,
183
+ // see https://vite.dev/config/shared-options.html#apptype
184
+ // this will prevent vite from injecting middlewares that we don't want
185
+ appType: viteConfig.appType ?? 'custom',
134
186
  environments: {
135
187
  [VITE_ENVIRONMENT_NAMES.client]: {
136
188
  consumer: 'client',
137
189
  build: {
138
- manifest: true,
190
+ emptyOutDir:
191
+ viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.client]
192
+ ?.build?.emptyOutDir ?? true,
139
193
  rollupOptions: {
140
194
  input: {
141
- main: getClientEntryPath(startConfig),
195
+ main: ENTRY_POINTS.client,
142
196
  },
143
- output: {
144
- dir: path.resolve(startConfig.root, CLIENT_DIST_DIR),
145
- },
146
- // TODO: this should be removed
147
- external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],
148
197
  },
198
+ outDir: getClientOutputDirectory(viteConfig),
149
199
  },
150
200
  },
151
201
  [VITE_ENVIRONMENT_NAMES.server]: {
152
202
  consumer: 'server',
153
203
  build: {
204
+ emptyOutDir:
205
+ viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]
206
+ ?.build?.emptyOutDir ?? false,
154
207
  ssr: true,
155
- // we don't write to the file system as the below 'capture-output' plugin will
156
- // capture the output and write it to the virtual file system
157
- write: false,
158
- copyPublicDir: false,
159
208
  rollupOptions: {
160
- output: {
161
- entryFileNames: SSR_ENTRY_FILE,
162
- },
163
- plugins: [
164
- {
165
- name: 'capture-output',
166
- generateBundle(_options, bundle) {
167
- // TODO: can this hook be called more than once?
168
- ssrBundle = bundle
169
- },
170
- },
171
- ],
209
+ input:
210
+ viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]
211
+ ?.build?.rollupOptions?.input ?? ENTRY_POINTS.server,
172
212
  },
213
+ outDir: getServerOutputDirectory(viteConfig),
173
214
  commonjsOptions: {
174
215
  include: [/node_modules/],
175
216
  },
217
+ copyPublicDir:
218
+ viteConfig.environments?.[VITE_ENVIRONMENT_NAMES.server]
219
+ ?.build?.copyPublicDir ?? false,
220
+ },
221
+ optimizeDeps: {
222
+ exclude: [
223
+ ...Object.values(VIRTUAL_MODULES),
224
+ ...result.optimizeDeps.exclude.sort(),
225
+ ...additionalOptimizeDeps.exclude,
226
+ `@tanstack/${corePluginOpts.framework}-start/server-functions-server`,
227
+ ],
228
+ include: [
229
+ ...additionalOptimizeDeps.include,
230
+ ...result.optimizeDeps.include.sort(),
231
+ ],
176
232
  },
177
233
  },
178
234
  },
179
235
  resolve: {
180
236
  noExternal: [
181
237
  '@tanstack/start**',
182
- `@tanstack/${opts.framework}-start**`,
238
+ `@tanstack/${corePluginOpts.framework}-start**`,
183
239
  ...Object.values(VIRTUAL_MODULES),
184
240
  startPackageName,
185
241
  ...result.ssr.noExternal.sort(),
186
242
  ],
187
- external: [...result.ssr.external.sort()],
188
243
  dedupe: [startPackageName],
244
+ alias: {
245
+ ...entryAliasConfiguration,
246
+ },
189
247
  },
190
248
  optimizeDeps: {
191
249
  exclude: [
@@ -203,15 +261,42 @@ export function TanStackStartVitePluginCore(
203
261
  // This is not the same as injecting environment variables.
204
262
 
205
263
  ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),
206
- ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),
264
+ ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', getClientOutputDirectory(viteConfig)),
207
265
  ...defineReplaceEnv('TSS_APP_BASE', viteAppBase),
208
266
  ...(command === 'serve' ? defineReplaceEnv('TSS_SHELL', startConfig.spa?.enabled ? 'true' : 'false') : {}),
267
+ ...defineReplaceEnv('TSS_DEV_SERVER', command === 'serve' ? 'true' : 'false'),
268
+ },
269
+ builder: {
270
+ sharedPlugins: true,
271
+ async buildApp(builder) {
272
+ const client = builder.environments[VITE_ENVIRONMENT_NAMES.client]
273
+ const server = builder.environments[VITE_ENVIRONMENT_NAMES.server]
274
+
275
+ if (!client) {
276
+ throw new Error('Client environment not found')
277
+ }
278
+
279
+ if (!server) {
280
+ throw new Error('SSR environment not found')
281
+ }
282
+
283
+ if (!client.isBuilt) {
284
+ // Build the client bundle first
285
+ await builder.build(client)
286
+ }
287
+ if (!server.isBuilt) {
288
+ // Build the SSR bundle
289
+ await builder.build(server)
290
+ }
291
+ const serverBundle = getBundle(VITE_ENVIRONMENT_NAMES.server)
292
+ await postServerBuild({ builder, startConfig, serverBundle })
293
+ },
209
294
  },
210
295
  }
211
296
  },
212
297
  },
213
298
  // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv
214
- startCompilerPlugin(opts.framework, {
299
+ startCompilerPlugin(corePluginOpts.framework, {
215
300
  client: { envName: VITE_ENVIRONMENT_NAMES.client },
216
301
  server: { envName: VITE_ENVIRONMENT_NAMES.server },
217
302
  }),
@@ -221,31 +306,39 @@ export function TanStackStartVitePluginCore(
221
306
  manifestVirtualImportId: VIRTUAL_MODULES.serverFnManifest,
222
307
  client: {
223
308
  getRuntimeCode: () =>
224
- `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,
309
+ `import { createClientRpc } from '@tanstack/${corePluginOpts.framework}-start/server-functions-client'`,
225
310
  replacer: (d) =>
226
311
  `createClientRpc('${d.functionId}', '${startConfig.serverFns.base}')`,
227
312
  envName: VITE_ENVIRONMENT_NAMES.client,
228
313
  },
229
314
  server: {
230
315
  getRuntimeCode: () =>
231
- `import { createServerRpc } from '@tanstack/${opts.framework}-start/server-functions-server'`,
316
+ `import { createServerRpc } from '@tanstack/${corePluginOpts.framework}-start/server-functions-server'`,
232
317
  replacer: (d) =>
233
318
  `createServerRpc('${d.functionId}', '${startConfig.serverFns.base}', ${d.fn})`,
234
319
  envName: VITE_ENVIRONMENT_NAMES.server,
235
320
  },
236
321
  }),
237
- loadEnvPlugin(startConfig),
238
- startManifestPlugin({ clientEntry: getClientEntryPath(startConfig) }),
239
- devServerPlugin(),
240
- nitroPlugin(startConfig, () => ssrBundle),
322
+ loadEnvPlugin(),
323
+ startManifestPlugin({
324
+ getClientBundle: () => getBundle(VITE_ENVIRONMENT_NAMES.client),
325
+ }),
326
+ devServerPlugin({ startConfig }),
241
327
  {
242
- name: 'tanstack-start:core:capture-client-bundle',
328
+ name: 'tanstack-start:core:capture-bundle',
243
329
  applyToEnvironment(e) {
244
- return e.name === VITE_ENVIRONMENT_NAMES.client
330
+ return (
331
+ e.name === VITE_ENVIRONMENT_NAMES.client ||
332
+ e.name === VITE_ENVIRONMENT_NAMES.server
333
+ )
245
334
  },
246
335
  enforce: 'post',
247
336
  generateBundle(_options, bundle) {
248
- globalThis.TSS_CLIENT_BUNDLE = bundle
337
+ const environment = this.environment.name as ViteEnvironmentNames
338
+ if (!Object.values(VITE_ENVIRONMENT_NAMES).includes(environment)) {
339
+ throw new Error(`Unknown environment: ${environment}`)
340
+ }
341
+ capturedBundle[environment] = bundle
249
342
  },
250
343
  },
251
344
  ]
@@ -260,22 +353,3 @@ function defineReplaceEnv<TKey extends string, TValue extends string>(
260
353
  [`import.meta.env.${key}`]: JSON.stringify(value),
261
354
  } as { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue }
262
355
  }
263
-
264
- const getClientEntryPath = (startConfig: TanStackStartOutputConfig) => {
265
- // when the user specifies a custom client entry path, we need to resolve it
266
- // relative to the root of the project, keeping in mind that if not specified
267
- // it will be /~start/default-client-entry which is a virtual path
268
- // that is resolved by vite to the actual client entry path
269
- const entry = startConfig.clientEntryPath.startsWith(
270
- '/~start/default-client-entry',
271
- )
272
- ? startConfig.clientEntryPath
273
- : vite.normalizePath(
274
- path.join(
275
- '/@fs',
276
- path.resolve(startConfig.root, startConfig.clientEntryPath),
277
- ),
278
- )
279
-
280
- return entry
281
- }
@@ -0,0 +1,73 @@
1
+ import { HEADERS } from '@tanstack/start-server-core'
2
+ import { buildSitemap } from './build-sitemap'
3
+ import { VITE_ENVIRONMENT_NAMES } from './constants'
4
+ import { prerender } from './prerender'
5
+ import type { TanStackStartOutputConfig } from './schema'
6
+ import type { Rollup, ViteBuilder } from 'vite'
7
+
8
+ export async function postServerBuild({
9
+ builder,
10
+ startConfig,
11
+ serverBundle,
12
+ }: {
13
+ builder: ViteBuilder
14
+ startConfig: TanStackStartOutputConfig
15
+ serverBundle: Rollup.OutputBundle
16
+ }) {
17
+ // If the user has not set a prerender option, we need to set it to true
18
+ // if the pages array is not empty and has sub options requiring for prerendering
19
+ // If the user has explicitly set prerender.enabled, this should be respected
20
+ if (startConfig.prerender?.enabled !== false) {
21
+ startConfig.prerender = {
22
+ ...startConfig.prerender,
23
+ enabled:
24
+ startConfig.prerender?.enabled ??
25
+ startConfig.pages.some((d) =>
26
+ typeof d === 'string' ? false : !!d.prerender?.enabled,
27
+ ),
28
+ }
29
+ }
30
+
31
+ // Setup the options for prerendering the SPA shell (i.e `src/routes/__root.tsx`)
32
+ if (startConfig.spa?.enabled) {
33
+ startConfig.prerender = {
34
+ ...startConfig.prerender,
35
+ enabled: true,
36
+ }
37
+
38
+ const maskUrl = new URL(startConfig.spa.maskPath, 'http://localhost')
39
+
40
+ startConfig.pages.push({
41
+ path: maskUrl.toString().replace('http://localhost', ''),
42
+ prerender: {
43
+ ...startConfig.spa.prerender,
44
+ headers: {
45
+ ...startConfig.spa.prerender.headers,
46
+ [HEADERS.TSS_SHELL]: 'true',
47
+ },
48
+ },
49
+ sitemap: {
50
+ exclude: true,
51
+ },
52
+ })
53
+ }
54
+
55
+ // Run the prerendering process
56
+ if (startConfig.prerender.enabled) {
57
+ await prerender({
58
+ startConfig,
59
+ builder,
60
+ serverBundle,
61
+ })
62
+ }
63
+
64
+ // Run the sitemap build process
65
+ if (startConfig.pages.length) {
66
+ buildSitemap({
67
+ startConfig,
68
+ publicDir:
69
+ builder.environments[VITE_ENVIRONMENT_NAMES.client]?.config.build
70
+ .outDir ?? builder.config.build.outDir,
71
+ })
72
+ }
73
+ }