@tanstack/start-plugin-core 1.121.0-alpha.25 → 1.121.0-alpha.27
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.
- package/dist/cjs/compilers.cjs +24 -10
- package/dist/cjs/compilers.cjs.map +1 -1
- package/dist/cjs/constants.cjs +7 -1
- package/dist/cjs/constants.cjs.map +1 -1
- package/dist/cjs/constants.d.cts +1 -1
- package/dist/cjs/debug.cjs +5 -0
- package/dist/cjs/debug.cjs.map +1 -0
- package/dist/cjs/debug.d.cts +1 -0
- package/dist/cjs/nitro-plugin/build-sitemap.cjs +3 -3
- package/dist/cjs/nitro-plugin/build-sitemap.cjs.map +1 -1
- package/dist/cjs/nitro-plugin/plugin.cjs +2 -2
- package/dist/cjs/nitro-plugin/plugin.cjs.map +1 -1
- package/dist/cjs/nitro-plugin/prerender.cjs +7 -4
- package/dist/cjs/nitro-plugin/prerender.cjs.map +1 -1
- package/dist/cjs/plugin.cjs +26 -31
- package/dist/cjs/plugin.cjs.map +1 -1
- package/dist/cjs/plugin.d.cts +2 -4
- package/dist/cjs/schema.cjs +5 -5
- package/dist/cjs/schema.cjs.map +1 -1
- package/dist/cjs/schema.d.cts +32 -16
- package/dist/cjs/start-compiler-plugin.cjs +19 -17
- package/dist/cjs/start-compiler-plugin.cjs.map +1 -1
- package/dist/cjs/start-manifest-plugin/plugin.cjs +182 -0
- package/dist/cjs/start-manifest-plugin/plugin.cjs.map +1 -0
- package/dist/cjs/start-manifest-plugin/plugin.d.cts +3 -0
- package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs +39 -0
- package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.cjs.map +1 -0
- package/dist/cjs/start-router-plugin/generator-plugins/routes-manifest-plugin.d.cts +6 -0
- package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs +121 -0
- package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.cjs.map +1 -0
- package/dist/cjs/start-router-plugin/generator-plugins/server-routes-plugin.d.cts +2 -0
- package/dist/cjs/start-router-plugin/plugin.cjs +21 -0
- package/dist/cjs/start-router-plugin/plugin.cjs.map +1 -0
- package/dist/cjs/start-router-plugin/plugin.d.cts +3 -0
- package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs +72 -0
- package/dist/cjs/start-router-plugin/route-tree-client-plugin.cjs.map +1 -0
- package/dist/cjs/start-router-plugin/route-tree-client-plugin.d.cts +6 -0
- package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs +30 -0
- package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.cjs.map +1 -0
- package/dist/cjs/start-router-plugin/virtual-route-tree-plugin.d.cts +4 -0
- package/dist/esm/compilers.js +24 -10
- package/dist/esm/compilers.js.map +1 -1
- package/dist/esm/constants.d.ts +1 -1
- package/dist/esm/constants.js +7 -1
- package/dist/esm/constants.js.map +1 -1
- package/dist/esm/debug.d.ts +1 -0
- package/dist/esm/debug.js +5 -0
- package/dist/esm/debug.js.map +1 -0
- package/dist/esm/nitro-plugin/prerender.js +4 -1
- package/dist/esm/nitro-plugin/prerender.js.map +1 -1
- package/dist/esm/plugin.d.ts +2 -4
- package/dist/esm/plugin.js +17 -22
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/schema.d.ts +32 -16
- package/dist/esm/start-compiler-plugin.js +19 -17
- package/dist/esm/start-compiler-plugin.js.map +1 -1
- package/dist/esm/start-manifest-plugin/plugin.d.ts +3 -0
- package/dist/esm/start-manifest-plugin/plugin.js +182 -0
- package/dist/esm/start-manifest-plugin/plugin.js.map +1 -0
- package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.d.ts +6 -0
- package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +39 -0
- package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -0
- package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.d.ts +2 -0
- package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js +121 -0
- package/dist/esm/start-router-plugin/generator-plugins/server-routes-plugin.js.map +1 -0
- package/dist/esm/start-router-plugin/plugin.d.ts +3 -0
- package/dist/esm/start-router-plugin/plugin.js +21 -0
- package/dist/esm/start-router-plugin/plugin.js.map +1 -0
- package/dist/esm/start-router-plugin/route-tree-client-plugin.d.ts +6 -0
- package/dist/esm/start-router-plugin/route-tree-client-plugin.js +55 -0
- package/dist/esm/start-router-plugin/route-tree-client-plugin.js.map +1 -0
- package/dist/esm/start-router-plugin/virtual-route-tree-plugin.d.ts +4 -0
- package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js +30 -0
- package/dist/esm/start-router-plugin/virtual-route-tree-plugin.js.map +1 -0
- package/package.json +7 -6
- package/src/compilers.ts +31 -131
- package/src/constants.ts +8 -1
- package/src/debug.ts +3 -0
- package/src/global.d.ts +8 -0
- package/src/nitro-plugin/prerender.ts +4 -1
- package/src/plugin.ts +15 -26
- package/src/start-compiler-plugin.ts +24 -24
- package/src/start-manifest-plugin/plugin.ts +249 -0
- package/src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts +43 -0
- package/src/start-router-plugin/generator-plugins/server-routes-plugin.ts +138 -0
- package/src/start-router-plugin/plugin.ts +35 -0
- package/src/start-router-plugin/route-tree-client-plugin.ts +76 -0
- package/src/start-router-plugin/virtual-route-tree-plugin.ts +30 -0
- package/dist/cjs/start-routes-manifest-plugin/plugin.cjs +0 -207
- package/dist/cjs/start-routes-manifest-plugin/plugin.cjs.map +0 -1
- package/dist/cjs/start-routes-manifest-plugin/plugin.d.cts +0 -3
- package/dist/cjs/start-server-routes-plugin/config.d.cts +0 -49
- package/dist/cjs/start-server-routes-plugin/plugin.cjs +0 -614
- package/dist/cjs/start-server-routes-plugin/plugin.cjs.map +0 -1
- package/dist/cjs/start-server-routes-plugin/plugin.d.cts +0 -3
- package/dist/cjs/start-server-routes-plugin/template.cjs +0 -111
- package/dist/cjs/start-server-routes-plugin/template.cjs.map +0 -1
- package/dist/cjs/start-server-routes-plugin/template.d.cts +0 -34
- package/dist/esm/start-routes-manifest-plugin/plugin.d.ts +0 -3
- package/dist/esm/start-routes-manifest-plugin/plugin.js +0 -207
- package/dist/esm/start-routes-manifest-plugin/plugin.js.map +0 -1
- package/dist/esm/start-server-routes-plugin/config.d.ts +0 -49
- package/dist/esm/start-server-routes-plugin/plugin.d.ts +0 -3
- package/dist/esm/start-server-routes-plugin/plugin.js +0 -614
- package/dist/esm/start-server-routes-plugin/plugin.js.map +0 -1
- package/dist/esm/start-server-routes-plugin/template.d.ts +0 -34
- package/dist/esm/start-server-routes-plugin/template.js +0 -111
- package/dist/esm/start-server-routes-plugin/template.js.map +0 -1
- package/src/start-routes-manifest-plugin/plugin.ts +0 -282
- package/src/start-server-routes-plugin/config.ts +0 -8
- package/src/start-server-routes-plugin/plugin.ts +0 -900
- package/src/start-server-routes-plugin/template.ts +0 -164
package/src/plugin.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import path from 'node:path'
|
|
2
2
|
import { createNitro } from 'nitropack'
|
|
3
3
|
import { trimPathRight } from '@tanstack/router-core'
|
|
4
|
-
import {
|
|
4
|
+
import { VIRTUAL_MODULES } from '@tanstack/start-server-core'
|
|
5
5
|
import { TanStackServerFnPluginEnv } from '@tanstack/server-functions-plugin'
|
|
6
6
|
import * as vite from 'vite'
|
|
7
7
|
import { createTanStackConfig } from './schema'
|
|
8
8
|
import { nitroPlugin } from './nitro-plugin/plugin'
|
|
9
|
-
import {
|
|
9
|
+
import { startManifestPlugin } from './start-manifest-plugin/plugin'
|
|
10
10
|
import { startCompilerPlugin } from './start-compiler-plugin'
|
|
11
11
|
import {
|
|
12
12
|
CLIENT_DIST_DIR,
|
|
13
13
|
SSR_ENTRY_FILE,
|
|
14
14
|
VITE_ENVIRONMENT_NAMES,
|
|
15
15
|
} from './constants'
|
|
16
|
-
import {
|
|
16
|
+
import { tanStackStartRouter } from './start-router-plugin/plugin'
|
|
17
17
|
import { loadEnvPlugin } from './load-env-plugin/plugin'
|
|
18
18
|
import { devServerPlugin } from './dev-server-plugin/plugin'
|
|
19
19
|
import { resolveVirtualEntriesPlugin } from './resolve-virtual-entries-plugin/plugin'
|
|
@@ -35,11 +35,6 @@ export type TanStackStartOutputConfig = ReturnType<
|
|
|
35
35
|
typeof getTanStackStartOptions
|
|
36
36
|
>
|
|
37
37
|
|
|
38
|
-
declare global {
|
|
39
|
-
// eslint-disable-next-line no-var
|
|
40
|
-
var TSS_APP_BASE: string
|
|
41
|
-
}
|
|
42
|
-
|
|
43
38
|
export interface TanStackStartVitePluginCoreOptions {
|
|
44
39
|
framework: CompileStartFrameworkOptions
|
|
45
40
|
getVirtualServerRootHandler: (ctx: {
|
|
@@ -57,11 +52,9 @@ export function TanStackStartVitePluginCore(
|
|
|
57
52
|
startConfig: TanStackStartOutputConfig,
|
|
58
53
|
): Array<PluginOption> {
|
|
59
54
|
return [
|
|
60
|
-
|
|
61
|
-
verboseFileRoutes: false,
|
|
55
|
+
tanStackStartRouter({
|
|
62
56
|
...startConfig.tsr,
|
|
63
57
|
target: opts.framework,
|
|
64
|
-
enableRouteGeneration: true,
|
|
65
58
|
autoCodeSplitting: true,
|
|
66
59
|
}),
|
|
67
60
|
resolveVirtualEntriesPlugin(opts, startConfig),
|
|
@@ -162,18 +155,13 @@ export function TanStackStartVitePluginCore(
|
|
|
162
155
|
'@tanstack/start-router-manifest',
|
|
163
156
|
'@tanstack/start-config',
|
|
164
157
|
'@tanstack/server-functions-plugin',
|
|
165
|
-
'tanstack-start-router-manifest:v',
|
|
166
|
-
'tanstack-start-server-fn-manifest:v',
|
|
167
158
|
'nitropack',
|
|
168
159
|
'@tanstack/**start**',
|
|
160
|
+
...Object.values(VIRTUAL_MODULES),
|
|
169
161
|
],
|
|
170
162
|
},
|
|
171
163
|
optimizeDeps: {
|
|
172
|
-
exclude: [
|
|
173
|
-
'tanstack-start-server-fn-manifest:v',
|
|
174
|
-
'tanstack-start-router-manifest:v',
|
|
175
|
-
'tanstack-start-server-routes-manifest:v',
|
|
176
|
-
],
|
|
164
|
+
exclude: [...Object.values(VIRTUAL_MODULES)],
|
|
177
165
|
},
|
|
178
166
|
/* prettier-ignore */
|
|
179
167
|
define: {
|
|
@@ -197,9 +185,14 @@ export function TanStackStartVitePluginCore(
|
|
|
197
185
|
TanStackServerFnPluginEnv({
|
|
198
186
|
// This is the ID that will be available to look up and import
|
|
199
187
|
// our server function manifest and resolve its module
|
|
200
|
-
manifestVirtualImportId:
|
|
201
|
-
manifestOutputFilename:
|
|
202
|
-
'.tanstack
|
|
188
|
+
manifestVirtualImportId: VIRTUAL_MODULES.serverFnManifest,
|
|
189
|
+
manifestOutputFilename: path.join(
|
|
190
|
+
'.tanstack',
|
|
191
|
+
'start',
|
|
192
|
+
'build',
|
|
193
|
+
'server',
|
|
194
|
+
'server-functions-manifest.json',
|
|
195
|
+
),
|
|
203
196
|
client: {
|
|
204
197
|
getRuntimeCode: () =>
|
|
205
198
|
`import { createClientRpc } from '@tanstack/${opts.framework}-start/server-functions-client'`,
|
|
@@ -225,13 +218,9 @@ export function TanStackStartVitePluginCore(
|
|
|
225
218
|
},
|
|
226
219
|
}),
|
|
227
220
|
loadEnvPlugin(startConfig),
|
|
228
|
-
|
|
221
|
+
startManifestPlugin(startConfig),
|
|
229
222
|
devServerPlugin(),
|
|
230
223
|
nitroPlugin(startConfig, () => ssrBundle),
|
|
231
|
-
TanStackStartServerRoutesVite({
|
|
232
|
-
...startConfig.tsr,
|
|
233
|
-
target: opts.framework,
|
|
234
|
-
}),
|
|
235
224
|
]
|
|
236
225
|
}
|
|
237
226
|
|
|
@@ -20,6 +20,7 @@ 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('|'))
|
|
@@ -52,24 +53,29 @@ export function startCompilerPlugin(
|
|
|
52
53
|
applyToEnvironment(env) {
|
|
53
54
|
return [opts.client.envName, opts.server.envName].includes(env.name)
|
|
54
55
|
},
|
|
55
|
-
transform
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
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
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { rootRouteId } from '@tanstack/router-core'
|
|
2
|
+
|
|
3
|
+
import type { GeneratorPlugin } from '@tanstack/router-generator'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* this plugin builds the routes manifest and stores it on globalThis
|
|
7
|
+
* so that it can be accessed later (e.g. from a vite plugin)
|
|
8
|
+
*/
|
|
9
|
+
export function routesManifestPlugin(): GeneratorPlugin {
|
|
10
|
+
return {
|
|
11
|
+
name: 'routes-manifest-plugin',
|
|
12
|
+
onRouteTreesChanged: ({ routeTrees, rootRouteNode }) => {
|
|
13
|
+
const routeTree = routeTrees.find((tree) => tree.exportName === 'Route')
|
|
14
|
+
if (!routeTree) {
|
|
15
|
+
throw new Error(
|
|
16
|
+
'No route tree found with export name "Route". Please ensure your routes are correctly defined.',
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
const routesManifest = {
|
|
20
|
+
[rootRouteId]: {
|
|
21
|
+
filePath: rootRouteNode.filePath,
|
|
22
|
+
children: routeTree.acc.routeTree.map((d) => d.routePath),
|
|
23
|
+
},
|
|
24
|
+
...Object.fromEntries(
|
|
25
|
+
routeTree.acc.routeNodes.map((d) => {
|
|
26
|
+
const filePathId = d.routePath
|
|
27
|
+
|
|
28
|
+
return [
|
|
29
|
+
filePathId,
|
|
30
|
+
{
|
|
31
|
+
filePath: d.filePath,
|
|
32
|
+
parent: d.parent?.routePath ? d.parent.routePath : undefined,
|
|
33
|
+
children: d.children?.map((childRoute) => childRoute.routePath),
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
}),
|
|
37
|
+
),
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
globalThis.TSS_ROUTES_MANIFEST = { routes: routesManifest }
|
|
41
|
+
},
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import {
|
|
2
|
+
checkRouteFullPathUniqueness,
|
|
3
|
+
ensureStringArgument,
|
|
4
|
+
hasChildWithExport,
|
|
5
|
+
} from '@tanstack/router-generator'
|
|
6
|
+
|
|
7
|
+
import type {
|
|
8
|
+
GeneratorPluginWithTransform,
|
|
9
|
+
ImportDeclaration,
|
|
10
|
+
TransformImportsConfig,
|
|
11
|
+
} from '@tanstack/router-generator'
|
|
12
|
+
|
|
13
|
+
const EXPORT_NAME = 'ServerRoute'
|
|
14
|
+
export function serverRoutesPlugin(): GeneratorPluginWithTransform {
|
|
15
|
+
return {
|
|
16
|
+
name: 'server-routes-plugin',
|
|
17
|
+
transformPlugin: {
|
|
18
|
+
name: 'server-routes-transform',
|
|
19
|
+
exportName: EXPORT_NAME,
|
|
20
|
+
imports: (ctx) => {
|
|
21
|
+
const targetModule = `@tanstack/${ctx.target}-start/server`
|
|
22
|
+
const imports: TransformImportsConfig = {}
|
|
23
|
+
if (ctx.verboseFileRoutes === false) {
|
|
24
|
+
imports.banned = [
|
|
25
|
+
{
|
|
26
|
+
source: targetModule,
|
|
27
|
+
specifiers: [{ imported: 'createServerFileRoute' }],
|
|
28
|
+
},
|
|
29
|
+
]
|
|
30
|
+
} else {
|
|
31
|
+
imports.required = [
|
|
32
|
+
{
|
|
33
|
+
source: targetModule,
|
|
34
|
+
specifiers: [{ imported: 'createServerFileRoute' }],
|
|
35
|
+
},
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
return imports
|
|
39
|
+
},
|
|
40
|
+
onExportFound: ({ ctx, decl }) => {
|
|
41
|
+
let appliedChanges = false
|
|
42
|
+
if (decl.init?.type === 'CallExpression') {
|
|
43
|
+
let call = decl.init
|
|
44
|
+
let callee = call.callee
|
|
45
|
+
|
|
46
|
+
while (
|
|
47
|
+
callee.type === 'MemberExpression' &&
|
|
48
|
+
callee.object.type === 'CallExpression'
|
|
49
|
+
) {
|
|
50
|
+
call = callee.object
|
|
51
|
+
callee = call.callee
|
|
52
|
+
}
|
|
53
|
+
if (
|
|
54
|
+
call.callee.type === 'Identifier' &&
|
|
55
|
+
call.callee.name === 'createServerFileRoute'
|
|
56
|
+
) {
|
|
57
|
+
if (!ctx.verboseFileRoutes) {
|
|
58
|
+
if (call.arguments.length) {
|
|
59
|
+
call.arguments = []
|
|
60
|
+
appliedChanges = true
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
appliedChanges = ensureStringArgument(
|
|
64
|
+
call,
|
|
65
|
+
ctx.routeId,
|
|
66
|
+
ctx.preferredQuote,
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Expected "createServerFileRoute" call, but got "${call.callee.type}"`,
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return appliedChanges
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
moduleAugmentation: ({ generator }) => ({
|
|
79
|
+
module: `@tanstack/${generator.config.target}-start/server`,
|
|
80
|
+
interfaceName: 'ServerFileRoutesByPath',
|
|
81
|
+
}),
|
|
82
|
+
onRouteTreesChanged: ({ routeTrees, generator }) => {
|
|
83
|
+
const tree = routeTrees.find((tree) => tree.exportName === EXPORT_NAME)
|
|
84
|
+
if (tree) {
|
|
85
|
+
checkRouteFullPathUniqueness(tree.sortedRouteNodes, generator.config)
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
imports: (ctx) => {
|
|
89
|
+
const imports: Array<ImportDeclaration> = []
|
|
90
|
+
|
|
91
|
+
const targetModule = `@tanstack/${ctx.generator.config.target}-start/server`
|
|
92
|
+
if (ctx.generator.config.verboseFileRoutes === false) {
|
|
93
|
+
imports.push({
|
|
94
|
+
specifiers: [
|
|
95
|
+
{ imported: 'CreateServerFileRoute' },
|
|
96
|
+
{ imported: 'ServerFileRoutesByPath' },
|
|
97
|
+
],
|
|
98
|
+
source: targetModule,
|
|
99
|
+
importKind: 'type',
|
|
100
|
+
})
|
|
101
|
+
}
|
|
102
|
+
// don't add the import if there are no server routes defined
|
|
103
|
+
const hasMatchingRouteFiles = ctx.acc.routeNodes.length > 0
|
|
104
|
+
if (hasMatchingRouteFiles) {
|
|
105
|
+
// needs a virtual root route
|
|
106
|
+
if (!ctx.rootRouteNode.exports?.includes(EXPORT_NAME)) {
|
|
107
|
+
imports.push({
|
|
108
|
+
specifiers: [{ imported: 'createServerRootRoute' }],
|
|
109
|
+
source: targetModule,
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return imports
|
|
114
|
+
},
|
|
115
|
+
routeModuleAugmentation: ({ routeNode }) => {
|
|
116
|
+
// server routes don't support lazy routes
|
|
117
|
+
if (routeNode._fsRouteType === 'lazy') {
|
|
118
|
+
return undefined
|
|
119
|
+
}
|
|
120
|
+
return `const createServerFileRoute: CreateServerFileRoute<
|
|
121
|
+
ServerFileRoutesByPath['${routeNode.routePath}']['parentRoute'],
|
|
122
|
+
ServerFileRoutesByPath['${routeNode.routePath}']['id'],
|
|
123
|
+
ServerFileRoutesByPath['${routeNode.routePath}']['path'],
|
|
124
|
+
ServerFileRoutesByPath['${routeNode.routePath}']['fullPath'],
|
|
125
|
+
${hasChildWithExport(routeNode, 'ServerRoute') ? `${routeNode.variableName}ServerRouteChildren` : 'unknown'}
|
|
126
|
+
>`
|
|
127
|
+
},
|
|
128
|
+
createRootRouteCode: () => `createServerRootRoute()`,
|
|
129
|
+
createVirtualRouteCode: ({ node }) =>
|
|
130
|
+
`createServerFileRoute('${node.routePath}')`,
|
|
131
|
+
config: ({ sortedRouteNodes }) => {
|
|
132
|
+
const hasMatchingRouteFiles = sortedRouteNodes.length > 0
|
|
133
|
+
return {
|
|
134
|
+
virtualRootRoute: hasMatchingRouteFiles,
|
|
135
|
+
}
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
what is this plugin doing, especially compared to one already existing in the @tanstack/router-plugin package?
|
|
3
|
+
|
|
4
|
+
it configures:
|
|
5
|
+
1. the generator to generate both the render-route-tree as well as the server-route-tree
|
|
6
|
+
2. the code-splitter plugin, so it could possibly be enabled per environment (e.g. disable on the server)
|
|
7
|
+
3. the auto import plugin for both environments
|
|
8
|
+
4. the route tree client plugin, which removes the server part from the generated route tree
|
|
9
|
+
5. the virtual route tree plugin, which provides the route tree to the server
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import {
|
|
13
|
+
tanStackRouterCodeSplitter,
|
|
14
|
+
tanstackRouterAutoImport,
|
|
15
|
+
tanstackRouterGenerator,
|
|
16
|
+
} from '@tanstack/router-plugin/vite'
|
|
17
|
+
import { routeTreeClientPlugin } from './route-tree-client-plugin'
|
|
18
|
+
import { virtualRouteTreePlugin } from './virtual-route-tree-plugin'
|
|
19
|
+
import { routesManifestPlugin } from './generator-plugins/routes-manifest-plugin'
|
|
20
|
+
import { serverRoutesPlugin } from './generator-plugins/server-routes-plugin'
|
|
21
|
+
import type { PluginOption } from 'vite'
|
|
22
|
+
import type { Config } from '@tanstack/router-generator'
|
|
23
|
+
|
|
24
|
+
export function tanStackStartRouter(config: Config): Array<PluginOption> {
|
|
25
|
+
return [
|
|
26
|
+
tanstackRouterGenerator({
|
|
27
|
+
...config,
|
|
28
|
+
plugins: [serverRoutesPlugin(), routesManifestPlugin()],
|
|
29
|
+
}),
|
|
30
|
+
tanStackRouterCodeSplitter(config),
|
|
31
|
+
tanstackRouterAutoImport(config),
|
|
32
|
+
routeTreeClientPlugin(config),
|
|
33
|
+
virtualRouteTreePlugin(config),
|
|
34
|
+
]
|
|
35
|
+
}
|