@tanstack/start-plugin-core 1.121.0-alpha.8 → 1.121.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (187) hide show
  1. package/dist/cjs/compilers.cjs +24 -10
  2. package/dist/cjs/compilers.cjs.map +1 -1
  3. package/dist/cjs/constants.cjs +10 -0
  4. package/dist/cjs/constants.cjs.map +1 -1
  5. package/dist/cjs/constants.d.cts +2 -0
  6. package/dist/cjs/debug.cjs +5 -0
  7. package/dist/cjs/debug.cjs.map +1 -0
  8. package/dist/cjs/debug.d.cts +1 -0
  9. package/dist/cjs/{extractHtmlScripts.cjs → dev-server-plugin/extract-html-scripts.cjs} +1 -1
  10. package/dist/cjs/dev-server-plugin/extract-html-scripts.cjs.map +1 -0
  11. package/dist/cjs/{nitro/dev-server-plugin.cjs → dev-server-plugin/plugin.cjs} +2 -2
  12. package/dist/cjs/dev-server-plugin/plugin.cjs.map +1 -0
  13. package/dist/cjs/load-env-plugin/plugin.cjs +34 -0
  14. package/dist/cjs/load-env-plugin/plugin.cjs.map +1 -0
  15. package/dist/cjs/load-env-plugin/plugin.d.cts +3 -0
  16. package/dist/cjs/{build-sitemap.cjs → nitro-plugin/build-sitemap.cjs} +12 -10
  17. package/dist/cjs/nitro-plugin/build-sitemap.cjs.map +1 -0
  18. package/dist/cjs/{build-sitemap.d.cts → nitro-plugin/build-sitemap.d.cts} +2 -2
  19. package/dist/cjs/{nitro/nitro-plugin.cjs → nitro-plugin/plugin.cjs} +79 -65
  20. package/dist/cjs/nitro-plugin/plugin.cjs.map +1 -0
  21. package/dist/cjs/{prerender.cjs → nitro-plugin/prerender.cjs} +18 -14
  22. package/dist/cjs/nitro-plugin/prerender.cjs.map +1 -0
  23. package/dist/cjs/{prerender.d.cts → nitro-plugin/prerender.d.cts} +1 -1
  24. package/dist/cjs/nitro-plugin/queue.cjs.map +1 -0
  25. package/dist/cjs/plugin.cjs +50 -38
  26. package/dist/cjs/plugin.cjs.map +1 -1
  27. package/dist/cjs/plugin.d.cts +14 -2657
  28. package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs +66 -0
  29. package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs.map +1 -0
  30. package/dist/cjs/resolve-virtual-entries-plugin/plugin.d.cts +3 -0
  31. package/dist/cjs/schema.cjs +5 -5
  32. package/dist/cjs/schema.cjs.map +1 -1
  33. package/dist/cjs/schema.d.cts +32 -16
  34. package/dist/cjs/start-compiler-plugin.cjs +21 -19
  35. package/dist/cjs/start-compiler-plugin.cjs.map +1 -1
  36. package/dist/cjs/start-compiler-plugin.d.cts +1 -1
  37. package/dist/cjs/start-manifest-plugin/plugin.cjs +182 -0
  38. package/dist/cjs/start-manifest-plugin/plugin.cjs.map +1 -0
  39. package/dist/{esm/routesManifestPlugin.d.ts → cjs/start-manifest-plugin/plugin.d.cts} +1 -1
  40. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs +39 -0
  41. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs.map +1 -0
  42. package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.d.cts +6 -0
  43. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs +121 -0
  44. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs.map +1 -0
  45. package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.d.cts +2 -0
  46. package/dist/cjs/start-router-plugin/plugin.cjs +21 -0
  47. package/dist/cjs/start-router-plugin/plugin.cjs.map +1 -0
  48. package/dist/cjs/start-router-plugin/plugin.d.cts +3 -0
  49. package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs +72 -0
  50. package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs.map +1 -0
  51. package/dist/cjs/start-router-plugin/route-tree-client-plugin.d.cts +6 -0
  52. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs +30 -0
  53. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs.map +1 -0
  54. package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.d.cts +4 -0
  55. package/dist/cjs/utils.cjs +11 -0
  56. package/dist/cjs/utils.cjs.map +1 -1
  57. package/dist/cjs/utils.d.cts +7 -0
  58. package/dist/esm/compilers.js +24 -10
  59. package/dist/esm/compilers.js.map +1 -1
  60. package/dist/esm/constants.d.ts +2 -0
  61. package/dist/esm/constants.js +10 -0
  62. package/dist/esm/constants.js.map +1 -1
  63. package/dist/esm/debug.d.ts +1 -0
  64. package/dist/esm/debug.js +5 -0
  65. package/dist/esm/debug.js.map +1 -0
  66. package/dist/esm/{extractHtmlScripts.js → dev-server-plugin/extract-html-scripts.js} +1 -1
  67. package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +1 -0
  68. package/dist/esm/{nitro/dev-server-plugin.js → dev-server-plugin/plugin.js} +2 -2
  69. package/dist/esm/dev-server-plugin/plugin.js.map +1 -0
  70. package/dist/esm/load-env-plugin/plugin.d.ts +3 -0
  71. package/dist/esm/load-env-plugin/plugin.js +17 -0
  72. package/dist/esm/load-env-plugin/plugin.js.map +1 -0
  73. package/dist/esm/{build-sitemap.d.ts → nitro-plugin/build-sitemap.d.ts} +2 -2
  74. package/dist/esm/{build-sitemap.js → nitro-plugin/build-sitemap.js} +9 -7
  75. package/dist/esm/nitro-plugin/build-sitemap.js.map +1 -0
  76. package/dist/esm/nitro-plugin/plugin.js +181 -0
  77. package/dist/esm/nitro-plugin/plugin.js.map +1 -0
  78. package/dist/esm/{prerender.d.ts → nitro-plugin/prerender.d.ts} +1 -1
  79. package/dist/esm/{prerender.js → nitro-plugin/prerender.js} +15 -11
  80. package/dist/esm/nitro-plugin/prerender.js.map +1 -0
  81. package/dist/esm/nitro-plugin/queue.js.map +1 -0
  82. package/dist/esm/plugin.d.ts +14 -2657
  83. package/dist/esm/plugin.js +51 -39
  84. package/dist/esm/plugin.js.map +1 -1
  85. package/dist/esm/resolve-virtual-entries-plugin/plugin.d.ts +3 -0
  86. package/dist/esm/resolve-virtual-entries-plugin/plugin.js +49 -0
  87. package/dist/esm/resolve-virtual-entries-plugin/plugin.js.map +1 -0
  88. package/dist/esm/schema.d.ts +32 -16
  89. package/dist/esm/start-compiler-plugin.d.ts +1 -1
  90. package/dist/esm/start-compiler-plugin.js +21 -19
  91. package/dist/esm/start-compiler-plugin.js.map +1 -1
  92. package/dist/{cjs/routesManifestPlugin.d.cts → esm/start-manifest-plugin/plugin.d.ts} +1 -1
  93. package/dist/esm/start-manifest-plugin/plugin.js +182 -0
  94. package/dist/esm/start-manifest-plugin/plugin.js.map +1 -0
  95. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.d.ts +6 -0
  96. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +39 -0
  97. package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -0
  98. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.d.ts +2 -0
  99. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js +121 -0
  100. package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js.map +1 -0
  101. package/dist/esm/start-router-plugin/plugin.d.ts +3 -0
  102. package/dist/esm/start-router-plugin/plugin.js +21 -0
  103. package/dist/esm/start-router-plugin/plugin.js.map +1 -0
  104. package/dist/esm/start-router-plugin/route-tree-client-plugin.d.ts +6 -0
  105. package/dist/esm/start-router-plugin/route-tree-client-plugin.js +55 -0
  106. package/dist/esm/start-router-plugin/route-tree-client-plugin.js.map +1 -0
  107. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.d.ts +4 -0
  108. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js +30 -0
  109. package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js.map +1 -0
  110. package/dist/esm/utils.d.ts +7 -0
  111. package/dist/esm/utils.js +11 -0
  112. package/dist/esm/utils.js.map +1 -1
  113. package/package.json +8 -7
  114. package/src/compilers.ts +31 -131
  115. package/src/constants.ts +10 -0
  116. package/src/debug.ts +3 -0
  117. package/src/{nitro/dev-server-plugin.ts → dev-server-plugin/plugin.ts} +11 -1
  118. package/src/global.d.ts +8 -0
  119. package/src/load-env-plugin/plugin.ts +17 -0
  120. package/src/{build-sitemap.ts → nitro-plugin/build-sitemap.ts} +11 -8
  121. package/src/nitro-plugin/plugin.ts +244 -0
  122. package/src/{prerender.ts → nitro-plugin/prerender.ts} +17 -13
  123. package/src/plugin.ts +63 -41
  124. package/src/resolve-virtual-entries-plugin/plugin.ts +63 -0
  125. package/src/start-compiler-plugin.ts +25 -25
  126. package/src/start-manifest-plugin/plugin.ts +249 -0
  127. package/src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts +43 -0
  128. package/src/start-router-plugin/generator-plugins/server-routes-plugin.ts +138 -0
  129. package/src/start-router-plugin/plugin.ts +35 -0
  130. package/src/start-router-plugin/route-tree-client-plugin.ts +76 -0
  131. package/src/start-router-plugin/virtual-route-tree-plugin.ts +30 -0
  132. package/src/utils.ts +11 -0
  133. package/dist/cjs/build-sitemap.cjs.map +0 -1
  134. package/dist/cjs/extractHtmlScripts.cjs.map +0 -1
  135. package/dist/cjs/nitro/build-nitro.cjs +0 -18
  136. package/dist/cjs/nitro/build-nitro.cjs.map +0 -1
  137. package/dist/cjs/nitro/build-nitro.d.cts +0 -2
  138. package/dist/cjs/nitro/dev-server-plugin.cjs.map +0 -1
  139. package/dist/cjs/nitro/nitro-plugin.cjs.map +0 -1
  140. package/dist/cjs/prerender.cjs.map +0 -1
  141. package/dist/cjs/queue.cjs.map +0 -1
  142. package/dist/cjs/routesManifestPlugin.cjs +0 -168
  143. package/dist/cjs/routesManifestPlugin.cjs.map +0 -1
  144. package/dist/cjs/start-server-routes-plugin/config.d.cts +0 -49
  145. package/dist/cjs/start-server-routes-plugin/plugin.cjs +0 -613
  146. package/dist/cjs/start-server-routes-plugin/plugin.cjs.map +0 -1
  147. package/dist/cjs/start-server-routes-plugin/plugin.d.cts +0 -3
  148. package/dist/cjs/start-server-routes-plugin/template.cjs +0 -111
  149. package/dist/cjs/start-server-routes-plugin/template.cjs.map +0 -1
  150. package/dist/cjs/start-server-routes-plugin/template.d.cts +0 -34
  151. package/dist/esm/build-sitemap.js.map +0 -1
  152. package/dist/esm/extractHtmlScripts.js.map +0 -1
  153. package/dist/esm/nitro/build-nitro.d.ts +0 -2
  154. package/dist/esm/nitro/build-nitro.js +0 -18
  155. package/dist/esm/nitro/build-nitro.js.map +0 -1
  156. package/dist/esm/nitro/dev-server-plugin.js.map +0 -1
  157. package/dist/esm/nitro/nitro-plugin.js +0 -167
  158. package/dist/esm/nitro/nitro-plugin.js.map +0 -1
  159. package/dist/esm/prerender.js.map +0 -1
  160. package/dist/esm/queue.js.map +0 -1
  161. package/dist/esm/routesManifestPlugin.js +0 -168
  162. package/dist/esm/routesManifestPlugin.js.map +0 -1
  163. package/dist/esm/start-server-routes-plugin/config.d.ts +0 -49
  164. package/dist/esm/start-server-routes-plugin/plugin.d.ts +0 -3
  165. package/dist/esm/start-server-routes-plugin/plugin.js +0 -613
  166. package/dist/esm/start-server-routes-plugin/plugin.js.map +0 -1
  167. package/dist/esm/start-server-routes-plugin/template.d.ts +0 -34
  168. package/dist/esm/start-server-routes-plugin/template.js +0 -111
  169. package/dist/esm/start-server-routes-plugin/template.js.map +0 -1
  170. package/src/nitro/build-nitro.ts +0 -27
  171. package/src/nitro/nitro-plugin.ts +0 -195
  172. package/src/routesManifestPlugin.ts +0 -220
  173. package/src/start-server-routes-plugin/config.ts +0 -8
  174. package/src/start-server-routes-plugin/plugin.ts +0 -899
  175. package/src/start-server-routes-plugin/template.ts +0 -164
  176. /package/dist/cjs/{extractHtmlScripts.d.cts → dev-server-plugin/extract-html-scripts.d.cts} +0 -0
  177. /package/dist/cjs/{nitro/dev-server-plugin.d.cts → dev-server-plugin/plugin.d.cts} +0 -0
  178. /package/dist/cjs/{nitro/nitro-plugin.d.cts → nitro-plugin/plugin.d.cts} +0 -0
  179. /package/dist/cjs/{queue.cjs → nitro-plugin/queue.cjs} +0 -0
  180. /package/dist/cjs/{queue.d.cts → nitro-plugin/queue.d.cts} +0 -0
  181. /package/dist/esm/{extractHtmlScripts.d.ts → dev-server-plugin/extract-html-scripts.d.ts} +0 -0
  182. /package/dist/esm/{nitro/dev-server-plugin.d.ts → dev-server-plugin/plugin.d.ts} +0 -0
  183. /package/dist/esm/{nitro/nitro-plugin.d.ts → nitro-plugin/plugin.d.ts} +0 -0
  184. /package/dist/esm/{queue.d.ts → nitro-plugin/queue.d.ts} +0 -0
  185. /package/dist/esm/{queue.js → nitro-plugin/queue.js} +0 -0
  186. /package/src/{extractHtmlScripts.ts → dev-server-plugin/extract-html-scripts.ts} +0 -0
  187. /package/src/{queue.ts → nitro-plugin/queue.ts} +0 -0
@@ -4,13 +4,13 @@ import path from 'node:path'
4
4
  import { getRollupConfig } from 'nitropack/rollup'
5
5
  import { build as buildNitro, createNitro } from 'nitropack'
6
6
  import { joinURL, withBase, withoutBase } from 'ufo'
7
+ import { VITE_ENVIRONMENT_NAMES } from '../constants'
8
+ import { createLogger } from '../utils'
7
9
  import { Queue } from './queue'
8
- import { buildNitroEnvironment } from './nitro/build-nitro'
9
- import { VITE_ENVIRONMENT_NAMES } from './constants'
10
10
  import type { ViteBuilder } from 'vite'
11
11
  import type { $Fetch, Nitro } from 'nitropack'
12
- import type { TanStackStartOutputConfig } from './plugin'
13
- import type { Page } from './schema'
12
+ import type { TanStackStartOutputConfig } from '../plugin'
13
+ import type { Page } from '../schema'
14
14
 
15
15
  export async function prerender({
16
16
  options,
@@ -21,7 +21,8 @@ export async function prerender({
21
21
  nitro: Nitro
22
22
  builder: ViteBuilder
23
23
  }) {
24
- console.info('Prendering pages...')
24
+ const logger = createLogger('prerender')
25
+ logger.info('Prendering pages...')
25
26
 
26
27
  // If prerender is enabled but no pages are provided, default to prerendering the root page
27
28
  if (options.prerender?.enabled && !options.pages.length) {
@@ -42,7 +43,10 @@ export async function prerender({
42
43
 
43
44
  const prerenderOutputDir = path.resolve(
44
45
  options.root,
45
- '.tanstack-start/build/prerenderer',
46
+ '.tanstack',
47
+ 'start',
48
+ 'build',
49
+ 'prerenderer',
46
50
  )
47
51
 
48
52
  const nodeNitro = await createNitro({
@@ -72,7 +76,7 @@ export async function prerender({
72
76
  },
73
77
  }
74
78
 
75
- await buildNitroEnvironment(nodeNitro, () => buildNitro(nodeNitro))
79
+ await buildNitro(nodeNitro)
76
80
 
77
81
  // Import renderer entry
78
82
  const serverFilename =
@@ -93,14 +97,14 @@ export async function prerender({
93
97
  // Crawl all pages
94
98
  const pages = await prerenderPages()
95
99
 
96
- console.info(`Prerendered ${pages.length} pages:`)
100
+ logger.info(`Prerendered ${pages.length} pages:`)
97
101
  pages.forEach((page) => {
98
- console.info(`- ${page}`)
102
+ logger.info(`- ${page}`)
99
103
  })
100
104
 
101
105
  // TODO: Write the prerendered pages to the output directory
102
106
  } catch (error) {
103
- console.error(error)
107
+ logger.error(error)
104
108
  } finally {
105
109
  // Ensure server is always closed
106
110
  // server.process.kill()
@@ -126,7 +130,7 @@ export async function prerender({
126
130
  const seen = new Set<string>()
127
131
  const retriesByPath = new Map<string, number>()
128
132
  const concurrency = options.prerender?.concurrency ?? os.cpus().length
129
- console.info(`Concurrency: ${concurrency}`)
133
+ logger.info(`Concurrency: ${concurrency}`)
130
134
  const queue = new Queue({ concurrency })
131
135
 
132
136
  options.pages.forEach((page) => addCrawlPageTask(page))
@@ -160,7 +164,7 @@ export async function prerender({
160
164
 
161
165
  // Add the task
162
166
  queue.add(async () => {
163
- console.info(`Crawling: ${page.path}`)
167
+ logger.info(`Crawling: ${page.path}`)
164
168
  const retries = retriesByPath.get(page.path) || 0
165
169
  try {
166
170
  // Fetch the route
@@ -228,7 +232,7 @@ export async function prerender({
228
232
  }
229
233
  } catch (error) {
230
234
  if (retries < (prerenderOptions.retryCount ?? 0)) {
231
- console.warn(`Encountered error, retrying: ${page.path} in 500ms`)
235
+ logger.warn(`Encountered error, retrying: ${page.path} in 500ms`)
232
236
  await new Promise((resolve) =>
233
237
  setTimeout(resolve, prerenderOptions.retryDelay),
234
238
  )
package/src/plugin.ts CHANGED
@@ -1,24 +1,29 @@
1
1
  import path from 'node:path'
2
2
  import { createNitro } from 'nitropack'
3
- import { tanstackRouter } from '@tanstack/router-plugin/vite'
3
+ import { trimPathRight } from '@tanstack/router-core'
4
+ import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
4
5
  import { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'
5
6
  import * as vite from 'vite'
7
+ import { createTanStackConfig } from './schema'
8
+ import { nitroPlugin } from './nitro-plugin/plugin'
9
+ import { startManifestPlugin } from './start-manifest-plugin/plugin'
10
+ import { startCompilerPlugin } from './start-compiler-plugin'
6
11
  import {
7
- createTanStackConfig,
8
- createTanStackStartOptionsSchema,
9
- } from './schema'
10
- import { nitroPlugin } from './nitro/nitro-plugin'
11
- import { startManifestPlugin } from './routesManifestPlugin'
12
- import { TanStackStartCompilerPlugin } from './start-compiler-plugin'
13
- import { VITE_ENVIRONMENT_NAMES } from './constants'
14
- import { TanStackStartServerRoutesVite } from './start-server-routes-plugin/plugin'
12
+ CLIENT_DIST_DIR,
13
+ SSR_ENTRY_FILE,
14
+ VITE_ENVIRONMENT_NAMES,
15
+ } from './constants'
16
+ import { tanStackStartRouter } from './start-router-plugin/plugin'
17
+ import { loadEnvPlugin } from './load-env-plugin/plugin'
18
+ import { devServerPlugin } from './dev-server-plugin/plugin'
19
+ import { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'
20
+ import type { createTanStackStartOptionsSchema } from './schema'
15
21
  import type { PluginOption, Rollup } from 'vite'
16
22
  import type { z } from 'zod'
17
23
  import type { CompileStartFrameworkOptions } from './compilers'
18
24
 
19
- const TanStackStartOptionsSchema = createTanStackStartOptionsSchema()
20
25
  export type TanStackStartInputConfig = z.input<
21
- typeof TanStackStartOptionsSchema
26
+ ReturnType<typeof createTanStackStartOptionsSchema>
22
27
  >
23
28
 
24
29
  const defaultConfig = createTanStackConfig()
@@ -30,11 +35,14 @@ export type TanStackStartOutputConfig = ReturnType<
30
35
  typeof getTanStackStartOptions
31
36
  >
32
37
 
33
- export const clientDistDir = '.tanstack-start/build/client-dist'
34
- export const ssrEntryFile = 'ssr.mjs'
35
-
36
38
  export interface TanStackStartVitePluginCoreOptions {
37
39
  framework: CompileStartFrameworkOptions
40
+ getVirtualServerRootHandler: (ctx: {
41
+ routerFilepath: string
42
+ serverEntryFilepath: string
43
+ }) => string
44
+ getVirtualServerEntry: (ctx: { routerFilepath: string }) => string
45
+ getVirtualClientEntry: (ctx: { routerFilepath: string }) => string
38
46
  }
39
47
  // this needs to live outside of the TanStackStartVitePluginCore since it will be invoked multiple times by vite
40
48
  let ssrBundle: Rollup.OutputBundle
@@ -44,16 +52,18 @@ export function TanStackStartVitePluginCore(
44
52
  startConfig: TanStackStartOutputConfig,
45
53
  ): Array<PluginOption> {
46
54
  return [
47
- tanstackRouter({
48
- verboseFileRoutes: false,
55
+ tanStackStartRouter({
49
56
  ...startConfig.tsr,
50
57
  target: opts.framework,
51
- enableRouteGeneration: true,
52
58
  autoCodeSplitting: true,
53
59
  }),
60
+ resolveVirtualEntriesPlugin(opts, startConfig),
54
61
  {
55
62
  name: 'tanstack-start-core:config-client',
56
- async config() {
63
+ async config(viteConfig) {
64
+ const viteAppBase = trimPathRight(viteConfig.base || '/')
65
+ globalThis.TSS_APP_BASE = viteAppBase
66
+
57
67
  const nitroOutputPublicDir = await (async () => {
58
68
  // Create a dummy nitro app to get the resolved public output path
59
69
  const dummyNitroApp = await createNitro({
@@ -77,13 +87,17 @@ export function TanStackStartVitePluginCore(
77
87
  )
78
88
  ? startConfig.clientEntryPath
79
89
  : vite.normalizePath(
80
- path.resolve(startConfig.root, startConfig.clientEntryPath),
90
+ path.join(
91
+ '/@fs',
92
+ path.resolve(startConfig.root, startConfig.clientEntryPath),
93
+ ),
81
94
  )
82
95
 
83
96
  return entry
84
97
  }
85
98
 
86
99
  return {
100
+ base: viteAppBase,
87
101
  environments: {
88
102
  [VITE_ENVIRONMENT_NAMES.client]: {
89
103
  consumer: 'client',
@@ -94,9 +108,9 @@ export function TanStackStartVitePluginCore(
94
108
  main: getClientEntryPath(startConfig),
95
109
  },
96
110
  output: {
97
- dir: path.resolve(startConfig.root, clientDistDir),
111
+ dir: path.resolve(startConfig.root, CLIENT_DIST_DIR),
98
112
  },
99
- // TODO this should be removed
113
+ // TODO: this should be removed
100
114
  external: ['node:fs', 'node:path', 'node:os', 'node:crypto'],
101
115
  },
102
116
  },
@@ -111,13 +125,13 @@ export function TanStackStartVitePluginCore(
111
125
  copyPublicDir: false,
112
126
  rollupOptions: {
113
127
  output: {
114
- entryFileNames: ssrEntryFile,
128
+ entryFileNames: SSR_ENTRY_FILE,
115
129
  },
116
130
  plugins: [
117
131
  {
118
132
  name: 'capture-output',
119
- generateBundle(options, bundle) {
120
- // TODO can this hook be called more than once?
133
+ generateBundle(_options, bundle) {
134
+ // TODO: can this hook be called more than once?
121
135
  ssrBundle = bundle
122
136
  },
123
137
  },
@@ -141,34 +155,44 @@ export function TanStackStartVitePluginCore(
141
155
  '@tanstack/start-router-manifest',
142
156
  '@tanstack/start-config',
143
157
  '@tanstack/server-functions-plugin',
144
- 'tanstack-start-router-manifest:v',
145
- 'tanstack-start-server-fn-manifest:v',
146
158
  'nitropack',
147
- '@tanstack/**',
159
+ '@tanstack/**start**',
160
+ ...Object.values(VIRTUAL_MODULES),
148
161
  ],
149
162
  },
163
+ optimizeDeps: {
164
+ exclude: [...Object.values(VIRTUAL_MODULES)],
165
+ },
150
166
  /* prettier-ignore */
151
167
  define: {
152
- ...injectDefineEnv('TSS_PUBLIC_BASE', startConfig.public.base),
153
- ...injectDefineEnv('TSS_CLIENT_BASE', startConfig.client.base),
154
- ...injectDefineEnv('TSS_CLIENT_ENTRY', getClientEntryPath(startConfig)), // This is consumed by the router-manifest, where the entry point is imported after the dev refresh runtime is resolved
155
- ...injectDefineEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),
156
- ...injectDefineEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),
168
+ // define is an esbuild function that replaces the any instances of given keys with the given values
169
+ // i.e: __FRAMEWORK_NAME__ can be replaced with JSON.stringify("TanStack Start")
170
+ // This is not the same as injecting environment variables.
171
+
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
+ ...defineReplaceEnv('TSS_SERVER_FN_BASE', startConfig.serverFns.base),
174
+ ...defineReplaceEnv('TSS_OUTPUT_PUBLIC_DIR', nitroOutputPublicDir),
175
+ ...defineReplaceEnv('TSS_APP_BASE', viteAppBase)
157
176
  },
158
177
  }
159
178
  },
160
179
  },
161
180
  // N.B. TanStackStartCompilerPlugin must be before the TanStackServerFnPluginEnv
162
- TanStackStartCompilerPlugin(opts.framework, {
181
+ startCompilerPlugin(opts.framework, {
163
182
  client: { envName: VITE_ENVIRONMENT_NAMES.client },
164
183
  server: { envName: VITE_ENVIRONMENT_NAMES.server },
165
184
  }),
166
185
  TanStackServerFnPluginEnv({
167
186
  // This is the ID that will be available to look up and import
168
187
  // our server function manifest and resolve its module
169
- manifestVirtualImportId: 'tanstack-start-server-fn-manifest:v',
170
- manifestOutputFilename:
171
- '.tanstack-start/build/server/server-functions-manifest.json',
188
+ manifestVirtualImportId: VIRTUAL_MODULES.serverFnManifest,
189
+ manifestOutputFilename: path.join(
190
+ '.tanstack',
191
+ 'start',
192
+ 'build',
193
+ 'server',
194
+ 'server-functions-manifest.json',
195
+ ),
172
196
  client: {
173
197
  getRuntimeCode: () =>
174
198
  `import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,
@@ -193,16 +217,14 @@ export function TanStackStartVitePluginCore(
193
217
  return serverEnv.runner.import(fn.extractedFilename)
194
218
  },
195
219
  }),
220
+ loadEnvPlugin(startConfig),
196
221
  startManifestPlugin(startConfig),
222
+ devServerPlugin(),
197
223
  nitroPlugin(startConfig, () => ssrBundle),
198
- TanStackStartServerRoutesVite({
199
- ...startConfig.tsr,
200
- target: opts.framework,
201
- }),
202
224
  ]
203
225
  }
204
226
 
205
- function injectDefineEnv<TKey extends string, TValue extends string>(
227
+ function defineReplaceEnv<TKey extends string, TValue extends string>(
206
228
  key: TKey,
207
229
  value: TValue,
208
230
  ): { [P in `process.env.${TKey}` | `import.meta.env.${TKey}`]: TValue } {
@@ -0,0 +1,63 @@
1
+ import path from 'node:path'
2
+ import * as vite from 'vite'
3
+ import type {
4
+ TanStackStartOutputConfig,
5
+ TanStackStartVitePluginCoreOptions,
6
+ } from '../plugin'
7
+
8
+ export function resolveVirtualEntriesPlugin(
9
+ opts: TanStackStartVitePluginCoreOptions,
10
+ startConfig: TanStackStartOutputConfig,
11
+ ): vite.Plugin {
12
+ let resolvedConfig: vite.ResolvedConfig
13
+
14
+ const modules = new Set<string>([
15
+ '/~start/server-entry',
16
+ '/~start/default-server-entry',
17
+ '/~start/default-client-entry',
18
+ ])
19
+
20
+ return {
21
+ name: 'tanstack-start-core:resolve-virtual-entries',
22
+ configResolved(config) {
23
+ resolvedConfig = config
24
+ },
25
+ resolveId(id) {
26
+ if (modules.has(id)) {
27
+ return `${id}.tsx`
28
+ }
29
+
30
+ return undefined
31
+ },
32
+ load(id) {
33
+ const routerFilepath = vite.normalizePath(
34
+ path.resolve(startConfig.root, startConfig.tsr.srcDirectory, 'router'),
35
+ )
36
+
37
+ if (id === '/~start/server-entry.tsx') {
38
+ const ssrEntryFilepath = startConfig.serverEntryPath.startsWith(
39
+ '/~start/default-server-entry',
40
+ )
41
+ ? startConfig.serverEntryPath
42
+ : vite.normalizePath(
43
+ path.resolve(resolvedConfig.root, startConfig.serverEntryPath),
44
+ )
45
+
46
+ return opts.getVirtualServerRootHandler({
47
+ routerFilepath,
48
+ serverEntryFilepath: ssrEntryFilepath,
49
+ })
50
+ }
51
+
52
+ if (id === '/~start/default-client-entry.tsx') {
53
+ return opts.getVirtualClientEntry({ routerFilepath })
54
+ }
55
+
56
+ if (id === '/~start/default-server-entry.tsx') {
57
+ return opts.getVirtualServerEntry({ routerFilepath })
58
+ }
59
+
60
+ return undefined
61
+ },
62
+ }
63
+ }
@@ -20,11 +20,12 @@ const transformFuncs = [
20
20
  'clientOnly',
21
21
  'createIsomorphicFn',
22
22
  'createServerFileRoute',
23
+ 'createServerRootRoute',
23
24
  ]
24
25
 
25
26
  const tokenRegex = new RegExp(transformFuncs.join('|'))
26
27
 
27
- export function TanStackStartCompilerPlugin(
28
+ export function startCompilerPlugin(
28
29
  framework: CompileStartFrameworkOptions,
29
30
  inputOpts?: {
30
31
  client?: {
@@ -52,24 +53,29 @@ export function TanStackStartCompilerPlugin(
52
53
  applyToEnvironment(env) {
53
54
  return [opts.client.envName, opts.server.envName].includes(env.name)
54
55
  },
55
- transform(code, id) {
56
- const env =
57
- this.environment.name === opts.client.envName
58
- ? 'client'
59
- : this.environment.name === opts.server.envName
60
- ? 'server'
61
- : (() => {
62
- throw new Error(
63
- `Environment ${this.environment.name} not configured`,
64
- )
65
- })()
66
-
67
- return transformCode({
68
- code,
69
- id,
70
- env,
71
- framework,
72
- })
56
+ transform: {
57
+ filter: {
58
+ code: tokenRegex,
59
+ },
60
+ handler(code, id) {
61
+ const env =
62
+ this.environment.name === opts.client.envName
63
+ ? 'client'
64
+ : this.environment.name === opts.server.envName
65
+ ? 'server'
66
+ : (() => {
67
+ throw new Error(
68
+ `Environment ${this.environment.name} not configured`,
69
+ )
70
+ })()
71
+
72
+ return transformCode({
73
+ code,
74
+ id,
75
+ env,
76
+ framework,
77
+ })
78
+ },
73
79
  },
74
80
  }
75
81
  }
@@ -87,12 +93,6 @@ function transformCode(opts: {
87
93
  url.searchParams.delete('v')
88
94
  id = fileURLToPath(url).replace(/\\/g, '/')
89
95
 
90
- const includesToken = tokenRegex.test(code)
91
-
92
- if (!includesToken) {
93
- return null
94
- }
95
-
96
96
  if (debug) console.info(`${env} Compiling Start: `, id)
97
97
 
98
98
  const compileStartOutput = compileStartOutputFactory(framework)
@@ -0,0 +1,249 @@
1
+ import { readFileSync } from 'node:fs'
2
+ import path from 'node:path'
3
+ import { joinURL } from 'ufo'
4
+ import { rootRouteId } from '@tanstack/router-core'
5
+ import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
6
+ import { resolveViteId } from '../utils'
7
+ import { CLIENT_DIST_DIR } from '../constants'
8
+ import type {
9
+ PluginOption,
10
+ ResolvedConfig,
11
+ Manifest as ViteManifest,
12
+ ManifestChunk as ViteManifestChunk,
13
+ } from 'vite'
14
+ import type { RouterManagedTag } from '@tanstack/router-core'
15
+ import type { TanStackStartOutputConfig } from '../plugin'
16
+
17
+ const getCSSRecursively = (
18
+ file: ViteManifestChunk,
19
+ filesByRouteFilePath: ViteManifest,
20
+ basePath: string,
21
+ ) => {
22
+ const result: Array<RouterManagedTag> = []
23
+
24
+ // Get all css imports from the file
25
+ for (const cssFile of file.css ?? []) {
26
+ result.push({
27
+ tag: 'link',
28
+ attrs: {
29
+ rel: 'stylesheet',
30
+ href: joinURL(basePath, cssFile),
31
+ type: 'text/css',
32
+ },
33
+ })
34
+ }
35
+
36
+ // Recursively get CSS from imports
37
+ for (const imp of file.imports ?? []) {
38
+ const importInfo = filesByRouteFilePath[imp]
39
+ if (importInfo) {
40
+ result.push(
41
+ ...getCSSRecursively(importInfo, filesByRouteFilePath, basePath),
42
+ )
43
+ }
44
+ }
45
+
46
+ return result
47
+ }
48
+
49
+ const resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)
50
+ export function startManifestPlugin(
51
+ opts: TanStackStartOutputConfig,
52
+ ): PluginOption {
53
+ let config: ResolvedConfig
54
+
55
+ return {
56
+ name: 'tanstack-start:start-manifest-plugin',
57
+ enforce: 'pre',
58
+
59
+ configResolved(resolvedConfig) {
60
+ config = resolvedConfig
61
+ },
62
+ // configEnvironment(env, envConfig) {
63
+ // config = envConfig.
64
+ // },
65
+ resolveId: {
66
+ filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },
67
+ handler(id) {
68
+ if (id === VIRTUAL_MODULES.startManifest) {
69
+ return resolvedModuleId
70
+ }
71
+ return undefined
72
+ },
73
+ },
74
+ load: {
75
+ filter: {
76
+ id: new RegExp(resolvedModuleId),
77
+ },
78
+ handler(id) {
79
+ if (id === resolvedModuleId) {
80
+ if (this.environment.config.consumer !== 'server') {
81
+ // this will ultimately fail the build if the plugin is used outside the server environment
82
+ // TODO: do we need special handling for `serve`?
83
+ return `export default {}`
84
+ }
85
+
86
+ // If we're in development, return a dummy manifest
87
+ if (config.command === 'serve') {
88
+ return `export const tsrStartManifest = () => ({
89
+ routes: {}
90
+ })`
91
+ }
92
+
93
+ // This is the basepath for the application
94
+ const APP_BASE = globalThis.TSS_APP_BASE
95
+
96
+ const clientViteManifestPath = path.resolve(
97
+ opts.root,
98
+ CLIENT_DIST_DIR,
99
+ '.vite',
100
+ 'manifest.json',
101
+ )
102
+
103
+ let viteManifest: ViteManifest
104
+ try {
105
+ viteManifest = JSON.parse(
106
+ readFileSync(clientViteManifestPath, 'utf-8'),
107
+ )
108
+ } catch (err) {
109
+ console.error(err)
110
+ throw new Error(
111
+ `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,
112
+ )
113
+ }
114
+
115
+ // This the manifest pulled from the generated route tree and later used by the Router.
116
+ // i.e what's located in `src/generatedRouteTree.gen.ts`
117
+ const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes
118
+
119
+ // This is where hydration will start, from when the SSR'd page reaches the browser.
120
+ // By default, this'd be the virtual entry of `/~start/default-client-entry.tsx`, unless a custom entry is provided.
121
+ let entryFile: ViteManifestChunk | undefined
122
+
123
+ const filesByRouteFilePath: ViteManifest = Object.fromEntries(
124
+ Object.entries(viteManifest).map(([k, v]) => {
125
+ if (v.isEntry) {
126
+ if (entryFile !== undefined) {
127
+ console.error(
128
+ `multiple entries detected`,
129
+ entryFile.file,
130
+ v.file,
131
+ )
132
+ }
133
+ entryFile = v
134
+ }
135
+
136
+ const rPath = k.split('?')[0]
137
+
138
+ return [rPath, v]
139
+ }, {}),
140
+ )
141
+
142
+ const routesDirectoryFromRoot = path.relative(
143
+ opts.root,
144
+ opts.tsr.routesDirectory,
145
+ )
146
+
147
+ // Add preloads to the routes from the vite manifest
148
+ Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {
149
+ const file =
150
+ filesByRouteFilePath[
151
+ path.posix.join(routesDirectoryFromRoot, v.filePath as string)
152
+ ]
153
+
154
+ if (file) {
155
+ // Map the relevant imports to their route paths,
156
+ // so that it can be imported in the browser.
157
+ const preloads = (file.imports ?? []).map((d) => {
158
+ const assetPath = joinURL(APP_BASE, viteManifest[d]!.file)
159
+ return assetPath
160
+ })
161
+
162
+ // Since this is the most important JS entry for the route,
163
+ // it should be moved to the front of the preloads so that
164
+ // it has the best chance of being loaded first.
165
+ if (file.file) {
166
+ preloads.unshift(path.join(APP_BASE, file.file))
167
+ }
168
+
169
+ const cssAssetsList = getCSSRecursively(
170
+ file,
171
+ filesByRouteFilePath,
172
+ APP_BASE,
173
+ )
174
+
175
+ routeTreeRoutes[routeId] = {
176
+ ...v,
177
+ assets: [...(v.assets || []), ...cssAssetsList],
178
+ preloads,
179
+ }
180
+ }
181
+ })
182
+
183
+ if (entryFile) {
184
+ routeTreeRoutes[rootRouteId]!.preloads = [
185
+ joinURL(APP_BASE, entryFile.file),
186
+ ...(entryFile.imports?.map((d) =>
187
+ joinURL(APP_BASE, viteManifest[d]!.file),
188
+ ) || []),
189
+ ]
190
+
191
+ // Gather all the CSS files from the entry file in
192
+ // the `css` key and add them to the root route
193
+ const entryCssAssetsList = getCSSRecursively(
194
+ entryFile,
195
+ filesByRouteFilePath,
196
+ APP_BASE,
197
+ )
198
+
199
+ routeTreeRoutes[rootRouteId]!.assets = [
200
+ ...(routeTreeRoutes[rootRouteId]!.assets || []),
201
+ ...entryCssAssetsList,
202
+ {
203
+ tag: 'script',
204
+ attrs: {
205
+ src: joinURL(APP_BASE, entryFile.file),
206
+ type: 'module',
207
+ },
208
+ },
209
+ ]
210
+ }
211
+
212
+ const recurseRoute = (
213
+ route: {
214
+ preloads?: Array<string>
215
+ children?: Array<any>
216
+ },
217
+ seenPreloads = {} as Record<string, true>,
218
+ ) => {
219
+ route.preloads = route.preloads?.filter((preload) => {
220
+ if (seenPreloads[preload]) {
221
+ return false
222
+ }
223
+ seenPreloads[preload] = true
224
+ return true
225
+ })
226
+
227
+ if (route.children) {
228
+ route.children.forEach((child) => {
229
+ const childRoute = routeTreeRoutes[child]!
230
+ recurseRoute(childRoute, { ...seenPreloads })
231
+ })
232
+ }
233
+ }
234
+
235
+ // @ts-expect-error
236
+ recurseRoute(routeTreeRoutes[rootRouteId])
237
+
238
+ const routesManifest = {
239
+ routes: routeTreeRoutes,
240
+ }
241
+
242
+ return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`
243
+ }
244
+
245
+ return undefined
246
+ },
247
+ },
248
+ }
249
+ }