@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.
- package/dist/cjs/compilers.cjs +24 -10
- package/dist/cjs/compilers.cjs.map +1 -1
- package/dist/cjs/constants.cjs +10 -0
- package/dist/cjs/constants.cjs.map +1 -1
- package/dist/cjs/constants.d.cts +2 -0
- 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/{extractHtmlScripts.cjs → dev-server-plugin/extract-html-scripts.cjs} +1 -1
- package/dist/cjs/dev-server-plugin/extract-html-scripts.cjs.map +1 -0
- package/dist/cjs/{nitro/dev-server-plugin.cjs → dev-server-plugin/plugin.cjs} +2 -2
- package/dist/cjs/dev-server-plugin/plugin.cjs.map +1 -0
- package/dist/cjs/load-env-plugin/plugin.cjs +34 -0
- package/dist/cjs/load-env-plugin/plugin.cjs.map +1 -0
- package/dist/cjs/load-env-plugin/plugin.d.cts +3 -0
- package/dist/cjs/{build-sitemap.cjs → nitro-plugin/build-sitemap.cjs} +12 -10
- package/dist/cjs/nitro-plugin/build-sitemap.cjs.map +1 -0
- package/dist/cjs/{build-sitemap.d.cts → nitro-plugin/build-sitemap.d.cts} +2 -2
- package/dist/cjs/{nitro/nitro-plugin.cjs → nitro-plugin/plugin.cjs} +79 -65
- package/dist/cjs/nitro-plugin/plugin.cjs.map +1 -0
- package/dist/cjs/{prerender.cjs → nitro-plugin/prerender.cjs} +18 -14
- package/dist/cjs/nitro-plugin/prerender.cjs.map +1 -0
- package/dist/cjs/{prerender.d.cts → nitro-plugin/prerender.d.cts} +1 -1
- package/dist/cjs/nitro-plugin/queue.cjs.map +1 -0
- package/dist/cjs/plugin.cjs +50 -38
- package/dist/cjs/plugin.cjs.map +1 -1
- package/dist/cjs/plugin.d.cts +14 -2657
- package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs +66 -0
- package/dist/cjs/resolve-virtual-entries-plugin/plugin.cjs.map +1 -0
- package/dist/cjs/resolve-virtual-entries-plugin/plugin.d.cts +3 -0
- 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 +21 -19
- package/dist/cjs/start-compiler-plugin.cjs.map +1 -1
- package/dist/cjs/start-compiler-plugin.d.cts +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/{esm/routesManifestPlugin.d.ts → cjs/start-manifest-plugin/plugin.d.cts} +1 -1
- 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/cjs/utils.cjs +11 -0
- package/dist/cjs/utils.cjs.map +1 -1
- package/dist/cjs/utils.d.cts +7 -0
- package/dist/esm/compilers.js +24 -10
- package/dist/esm/compilers.js.map +1 -1
- package/dist/esm/constants.d.ts +2 -0
- package/dist/esm/constants.js +10 -0
- 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/{extractHtmlScripts.js → dev-server-plugin/extract-html-scripts.js} +1 -1
- package/dist/esm/dev-server-plugin/extract-html-scripts.js.map +1 -0
- package/dist/esm/{nitro/dev-server-plugin.js → dev-server-plugin/plugin.js} +2 -2
- package/dist/esm/dev-server-plugin/plugin.js.map +1 -0
- package/dist/esm/load-env-plugin/plugin.d.ts +3 -0
- package/dist/esm/load-env-plugin/plugin.js +17 -0
- package/dist/esm/load-env-plugin/plugin.js.map +1 -0
- package/dist/esm/{build-sitemap.d.ts → nitro-plugin/build-sitemap.d.ts} +2 -2
- package/dist/esm/{build-sitemap.js → nitro-plugin/build-sitemap.js} +9 -7
- package/dist/esm/nitro-plugin/build-sitemap.js.map +1 -0
- package/dist/esm/nitro-plugin/plugin.js +181 -0
- package/dist/esm/nitro-plugin/plugin.js.map +1 -0
- package/dist/esm/{prerender.d.ts → nitro-plugin/prerender.d.ts} +1 -1
- package/dist/esm/{prerender.js → nitro-plugin/prerender.js} +15 -11
- package/dist/esm/nitro-plugin/prerender.js.map +1 -0
- package/dist/esm/nitro-plugin/queue.js.map +1 -0
- package/dist/esm/plugin.d.ts +14 -2657
- package/dist/esm/plugin.js +51 -39
- package/dist/esm/plugin.js.map +1 -1
- package/dist/esm/resolve-virtual-entries-plugin/plugin.d.ts +3 -0
- package/dist/esm/resolve-virtual-entries-plugin/plugin.js +49 -0
- package/dist/esm/resolve-virtual-entries-plugin/plugin.js.map +1 -0
- package/dist/esm/schema.d.ts +32 -16
- package/dist/esm/start-compiler-plugin.d.ts +1 -1
- package/dist/esm/start-compiler-plugin.js +21 -19
- package/dist/esm/start-compiler-plugin.js.map +1 -1
- package/dist/{cjs/routesManifestPlugin.d.cts → esm/start-manifest-plugin/plugin.d.ts} +1 -1
- 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/dist/esm/utils.d.ts +7 -0
- package/dist/esm/utils.js +11 -0
- package/dist/esm/utils.js.map +1 -1
- package/package.json +8 -7
- package/src/compilers.ts +31 -131
- package/src/constants.ts +10 -0
- package/src/debug.ts +3 -0
- package/src/{nitro/dev-server-plugin.ts → dev-server-plugin/plugin.ts} +11 -1
- package/src/global.d.ts +8 -0
- package/src/load-env-plugin/plugin.ts +17 -0
- package/src/{build-sitemap.ts → nitro-plugin/build-sitemap.ts} +11 -8
- package/src/nitro-plugin/plugin.ts +244 -0
- package/src/{prerender.ts → nitro-plugin/prerender.ts} +17 -13
- package/src/plugin.ts +63 -41
- package/src/resolve-virtual-entries-plugin/plugin.ts +63 -0
- package/src/start-compiler-plugin.ts +25 -25
- 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/src/utils.ts +11 -0
- package/dist/cjs/build-sitemap.cjs.map +0 -1
- package/dist/cjs/extractHtmlScripts.cjs.map +0 -1
- package/dist/cjs/nitro/build-nitro.cjs +0 -18
- package/dist/cjs/nitro/build-nitro.cjs.map +0 -1
- package/dist/cjs/nitro/build-nitro.d.cts +0 -2
- package/dist/cjs/nitro/dev-server-plugin.cjs.map +0 -1
- package/dist/cjs/nitro/nitro-plugin.cjs.map +0 -1
- package/dist/cjs/prerender.cjs.map +0 -1
- package/dist/cjs/queue.cjs.map +0 -1
- package/dist/cjs/routesManifestPlugin.cjs +0 -168
- package/dist/cjs/routesManifestPlugin.cjs.map +0 -1
- package/dist/cjs/start-server-routes-plugin/config.d.cts +0 -49
- package/dist/cjs/start-server-routes-plugin/plugin.cjs +0 -613
- 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/build-sitemap.js.map +0 -1
- package/dist/esm/extractHtmlScripts.js.map +0 -1
- package/dist/esm/nitro/build-nitro.d.ts +0 -2
- package/dist/esm/nitro/build-nitro.js +0 -18
- package/dist/esm/nitro/build-nitro.js.map +0 -1
- package/dist/esm/nitro/dev-server-plugin.js.map +0 -1
- package/dist/esm/nitro/nitro-plugin.js +0 -167
- package/dist/esm/nitro/nitro-plugin.js.map +0 -1
- package/dist/esm/prerender.js.map +0 -1
- package/dist/esm/queue.js.map +0 -1
- package/dist/esm/routesManifestPlugin.js +0 -168
- package/dist/esm/routesManifestPlugin.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 -613
- 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/nitro/build-nitro.ts +0 -27
- package/src/nitro/nitro-plugin.ts +0 -195
- package/src/routesManifestPlugin.ts +0 -220
- package/src/start-server-routes-plugin/config.ts +0 -8
- package/src/start-server-routes-plugin/plugin.ts +0 -899
- package/src/start-server-routes-plugin/template.ts +0 -164
- /package/dist/cjs/{extractHtmlScripts.d.cts → dev-server-plugin/extract-html-scripts.d.cts} +0 -0
- /package/dist/cjs/{nitro/dev-server-plugin.d.cts → dev-server-plugin/plugin.d.cts} +0 -0
- /package/dist/cjs/{nitro/nitro-plugin.d.cts → nitro-plugin/plugin.d.cts} +0 -0
- /package/dist/cjs/{queue.cjs → nitro-plugin/queue.cjs} +0 -0
- /package/dist/cjs/{queue.d.cts → nitro-plugin/queue.d.cts} +0 -0
- /package/dist/esm/{extractHtmlScripts.d.ts → dev-server-plugin/extract-html-scripts.d.ts} +0 -0
- /package/dist/esm/{nitro/dev-server-plugin.d.ts → dev-server-plugin/plugin.d.ts} +0 -0
- /package/dist/esm/{nitro/nitro-plugin.d.ts → nitro-plugin/plugin.d.ts} +0 -0
- /package/dist/esm/{queue.d.ts → nitro-plugin/queue.d.ts} +0 -0
- /package/dist/esm/{queue.js → nitro-plugin/queue.js} +0 -0
- /package/src/{extractHtmlScripts.ts → dev-server-plugin/extract-html-scripts.ts} +0 -0
- /package/src/{queue.ts → nitro-plugin/queue.ts} +0 -0
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import * as t from '@babel/types'
|
|
3
|
+
import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'
|
|
4
|
+
import { normalizePath } from 'vite'
|
|
5
|
+
import { deadCodeElimination } from 'babel-dead-code-elimination'
|
|
6
|
+
import { debug } from '../debug'
|
|
7
|
+
import type { Plugin } from 'vite'
|
|
8
|
+
import type { Config } from '@tanstack/router-generator'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* This removes the server part from the generated route tree so that it can be used on the client.
|
|
12
|
+
*/
|
|
13
|
+
export function routeTreeClientPlugin(config: Config): Plugin {
|
|
14
|
+
const generatedRouteTreePath = normalizePath(
|
|
15
|
+
path.resolve(config.generatedRouteTree),
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
name: 'tanstack-start:route-tree-client-plugin',
|
|
20
|
+
enforce: 'pre',
|
|
21
|
+
// only run this plugin in the client environment
|
|
22
|
+
applyToEnvironment: (env) => env.config.consumer === 'client',
|
|
23
|
+
transform: {
|
|
24
|
+
filter: { id: generatedRouteTreePath },
|
|
25
|
+
handler(code, id) {
|
|
26
|
+
if (id !== generatedRouteTreePath) {
|
|
27
|
+
return null
|
|
28
|
+
}
|
|
29
|
+
if (debug) console.info(`Compiling route tree for the client`, id)
|
|
30
|
+
const ast = parseAst({ code, sourceFilename: id })
|
|
31
|
+
|
|
32
|
+
// only keep `export const routeTree = ... `
|
|
33
|
+
const filteredBody = ast.program.body.filter((node) => {
|
|
34
|
+
if (t.isExportNamedDeclaration(node)) {
|
|
35
|
+
if (
|
|
36
|
+
node.declaration &&
|
|
37
|
+
t.isVariableDeclaration(node.declaration) &&
|
|
38
|
+
node.declaration.declarations.length === 1 &&
|
|
39
|
+
node.declaration.declarations[0] &&
|
|
40
|
+
t.isVariableDeclarator(node.declaration.declarations[0]) &&
|
|
41
|
+
t.isIdentifier(node.declaration.declarations[0].id) &&
|
|
42
|
+
node.declaration.declarations[0].id.name === 'routeTree'
|
|
43
|
+
) {
|
|
44
|
+
return true
|
|
45
|
+
}
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
// strip off the typescript interface & module declarations since they also reference the server routes
|
|
49
|
+
if (
|
|
50
|
+
t.isTSInterfaceDeclaration(node) ||
|
|
51
|
+
t.isTSModuleDeclaration(node)
|
|
52
|
+
) {
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
return true
|
|
56
|
+
})
|
|
57
|
+
|
|
58
|
+
ast.program.body = filteredBody
|
|
59
|
+
|
|
60
|
+
deadCodeElimination(ast)
|
|
61
|
+
|
|
62
|
+
const compiled = generateFromAst(ast, {
|
|
63
|
+
sourceMaps: true,
|
|
64
|
+
sourceFileName: id,
|
|
65
|
+
filename: id,
|
|
66
|
+
})
|
|
67
|
+
if (debug) {
|
|
68
|
+
logDiff(code, compiled.code)
|
|
69
|
+
console.log('Output:\n', compiled.code, '\n\n')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return compiled
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
}
|
|
76
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import path from 'node:path'
|
|
2
|
+
import { normalizePath } from 'vite'
|
|
3
|
+
import { debug } from '../debug'
|
|
4
|
+
import type { Config } from '@tanstack/router-generator'
|
|
5
|
+
import type { Plugin } from 'vite'
|
|
6
|
+
|
|
7
|
+
export const moduleId = 'tanstack-start-route-tree:v'
|
|
8
|
+
|
|
9
|
+
export function virtualRouteTreePlugin(config: Config): Plugin {
|
|
10
|
+
const generatedRouteTreePath = normalizePath(
|
|
11
|
+
path.resolve(config.generatedRouteTree),
|
|
12
|
+
)
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
name: 'tanstack-start:virtual-route-tree',
|
|
16
|
+
enforce: 'pre',
|
|
17
|
+
sharedDuringBuild: true,
|
|
18
|
+
resolveId: {
|
|
19
|
+
filter: { id: new RegExp(moduleId) },
|
|
20
|
+
handler(id) {
|
|
21
|
+
let resolvedId: string | null = null
|
|
22
|
+
if (id === moduleId) {
|
|
23
|
+
if (debug) console.info('resolving id', id, generatedRouteTreePath)
|
|
24
|
+
resolvedId = generatedRouteTreePath
|
|
25
|
+
}
|
|
26
|
+
return resolvedId
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
}
|
|
30
|
+
}
|
package/src/utils.ts
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
1
|
export function resolveViteId(id: string) {
|
|
2
2
|
return `\0${id}`
|
|
3
3
|
}
|
|
4
|
+
|
|
5
|
+
export function createLogger(prefix: string) {
|
|
6
|
+
const label = `[${prefix}]`
|
|
7
|
+
return {
|
|
8
|
+
log: (...args: any) => console.log(label, ...args),
|
|
9
|
+
debug: (...args: any) => console.debug(label, ...args),
|
|
10
|
+
info: (...args: any) => console.info(label, ...args),
|
|
11
|
+
warn: (...args: any) => console.warn(label, ...args),
|
|
12
|
+
error: (...args: any) => console.error(label, ...args),
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-sitemap.cjs","sources":["../../src/build-sitemap.ts"],"sourcesContent":["import { writeFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { create } from 'xmlbuilder2'\nimport type { TanStackStartOutputConfig } from './plugin'\nimport type { XMLBuilder } from 'xmlbuilder2/lib/interfaces'\n\nexport type SitemapUrl = {\n loc: string\n lastmod: string\n priority?: number\n changefreq?:\n | 'always'\n | 'hourly'\n | 'daily'\n | 'weekly'\n | 'monthly'\n | 'yearly'\n | 'never'\n alternateRefs?: Array<{\n href: string\n hreflang?: string\n }>\n images?: Array<{\n loc: string\n title?: string\n caption?: string\n }>\n news?: {\n publication: {\n name: string\n language: string\n }\n publicationDate: string | Date\n title: string\n }\n}\n\nexport type SitemapData = {\n urls: Array<SitemapUrl>\n}\n\nfunction buildSitemapJson(\n pages: TanStackStartOutputConfig['pages'],\n host: string,\n): SitemapData {\n const slash = checkSlash(host)\n\n const urls: Array<SitemapUrl> = pages\n .filter((page) => {\n return page.sitemap?.exclude !== true\n })\n .map((page) => ({\n loc: `${host}${slash}${page.path.replace(/^\\/+/g, '')}`,\n lastmod: page.sitemap?.lastmod\n ? new Date(page.sitemap.lastmod).toISOString().split('T')[0]!\n : new Date().toISOString().split('T')[0]!,\n priority: page.sitemap?.priority,\n changefreq: page.sitemap?.changefreq,\n alternateRefs: page.sitemap?.alternateRefs,\n images: page.sitemap?.images,\n news: page.sitemap?.news,\n }))\n\n return { urls }\n}\n\nfunction jsonToXml(sitemapData: SitemapData): string {\n const sitemap = createXml('urlset')\n\n for (const item of sitemapData.urls) {\n const page = sitemap.ele('url')\n page.ele('loc').txt(item.loc)\n page.ele('lastmod').txt(item.lastmod)\n\n if (item.priority !== undefined) {\n page.ele('priority').txt(item.priority.toString())\n }\n if (item.changefreq) {\n page.ele('changefreq').txt(item.changefreq)\n }\n\n // Add alternate references\n if (item.alternateRefs?.length) {\n for (const ref of item.alternateRefs) {\n const alternateRef = page.ele('xhtml:link')\n alternateRef.att('rel', 'alternate')\n alternateRef.att('href', ref.href)\n if (ref.hreflang) {\n alternateRef.att('hreflang', ref.hreflang)\n }\n }\n }\n\n // Add images\n if (item.images?.length) {\n for (const image of item.images) {\n const imageElement = page.ele('image:image')\n imageElement.ele('image:loc').txt(image.loc)\n if (image.title) {\n imageElement.ele('image:title').txt(image.title)\n }\n if (image.caption) {\n imageElement.ele('image:caption').txt(image.caption)\n }\n }\n }\n\n // Add news\n if (item.news) {\n const newsElement = page.ele('news:news')\n const publication = newsElement.ele('news:publication')\n publication.ele('news:name').txt(item.news.publication.name)\n publication.ele('news:language').txt(item.news.publication.language)\n newsElement\n .ele('news:publication_date')\n .txt(new Date(item.news.publicationDate).toISOString().split('T')[0]!)\n newsElement.ele('news:title').txt(item.news.title)\n }\n }\n\n return sitemap.end({ prettyPrint: true })\n}\n\nexport async function buildSitemap({\n options,\n publicDir,\n}: {\n options: TanStackStartOutputConfig\n publicDir: string\n}) {\n let sitemapOptions = options.sitemap\n\n if (!sitemapOptions && options.pages.length) {\n sitemapOptions = { enabled: true, outputPath: 'sitemap.xml' }\n }\n\n if (!sitemapOptions?.enabled) {\n throw new Error('Sitemap is not enabled')\n }\n\n const { host, outputPath } = sitemapOptions\n\n if (!host) {\n if (!options.sitemap) {\n console.info(\n 'Hint: Pages found, but no sitemap host has been set. To enable sitemap generation, set the `sitemap.host` option.',\n )\n return\n }\n throw new Error(\n 'Sitemap host is not set and required to build the sitemap.',\n )\n }\n\n if (!outputPath) {\n throw new Error('Sitemap output path is not set')\n }\n\n const { pages } = options\n\n if (!pages.length) {\n console.log('No pages were found to build the sitemap. Skipping...')\n return\n }\n\n console.log('Building Sitemap...')\n\n // Build the sitemap data\n const sitemapData = buildSitemapJson(pages, host)\n\n // Generate output paths\n const xmlOutputPath = path.join(publicDir, outputPath)\n const pagesOutputPath = path.join(publicDir, 'pages.json')\n\n try {\n // Write XML sitemap\n console.log(`Writing sitemap XML at ${xmlOutputPath}`)\n writeFileSync(xmlOutputPath, jsonToXml(sitemapData))\n\n // Write pages data for runtime use\n console.log(`Writing pages data at ${pagesOutputPath}`)\n writeFileSync(\n pagesOutputPath,\n JSON.stringify(\n {\n pages,\n host,\n lastBuilt: new Date().toISOString(),\n },\n null,\n 2,\n ),\n )\n } catch (e) {\n console.error(`Unable to write sitemap files`, e)\n }\n}\n\nfunction createXml(elementName: 'urlset' | 'sitemapindex'): XMLBuilder {\n return create({ version: '1.0', encoding: 'UTF-8' })\n .ele(elementName, {\n xmlns: 'https://www.sitemaps.org/schemas/sitemap/0.9',\n })\n .com(`This file was automatically generated by TanStack Start.`)\n}\n\nfunction checkSlash(host: string): string {\n const finalChar = host.slice(-1)\n return finalChar === '/' ? '' : '/'\n}\n"],"names":["writeFileSync","create"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"extractHtmlScripts.cjs","sources":["../../src/extractHtmlScripts.ts"],"sourcesContent":["import * as cheerio from 'cheerio'\n\nexport function extractHtmlScripts(\n html: string,\n): Array<{ content?: string; src?: string }> {\n const $ = cheerio.load(html)\n const scripts: Array<{ content?: string; src?: string }> = []\n\n $('script').each((_, element) => {\n const src = $(element).attr('src')\n const content = $(element).html() ?? undefined\n scripts.push({\n src,\n content,\n })\n })\n\n return scripts\n}\n"],"names":["cheerio"],"mappings":";;;;;;;;;;;;;;;;;;;;AAEO,SAAS,mBACd,MAC2C;AACrC,QAAA,IAAIA,mBAAQ,KAAK,IAAI;AAC3B,QAAM,UAAqD,CAAC;AAE5D,IAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,YAAY;AAC/B,UAAM,MAAM,EAAE,OAAO,EAAE,KAAK,KAAK;AACjC,UAAM,UAAU,EAAE,OAAO,EAAE,KAAU,KAAA;AACrC,YAAQ,KAAK;AAAA,MACX;AAAA,MACA;AAAA,IAAA,CACD;AAAA,EAAA,CACF;AAEM,SAAA;AACT;;"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const fs = require("node:fs");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
const nitropack = require("nitropack");
|
|
6
|
-
async function buildNitroEnvironment(nitro, build) {
|
|
7
|
-
await nitropack.prepare(nitro);
|
|
8
|
-
await nitropack.copyPublicAssets(nitro);
|
|
9
|
-
await build();
|
|
10
|
-
const publicDir = nitro.options.output.publicDir;
|
|
11
|
-
const viteDir = path.resolve(publicDir, ".vite");
|
|
12
|
-
if (await fs.promises.stat(viteDir).catch(() => false)) {
|
|
13
|
-
await fs.promises.rm(viteDir, { recursive: true, force: true });
|
|
14
|
-
}
|
|
15
|
-
await nitro.close();
|
|
16
|
-
}
|
|
17
|
-
exports.buildNitroEnvironment = buildNitroEnvironment;
|
|
18
|
-
//# sourceMappingURL=build-nitro.cjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"build-nitro.cjs","sources":["../../../src/nitro/build-nitro.ts"],"sourcesContent":["import { promises as fsp } from 'node:fs'\nimport path from 'node:path'\nimport { copyPublicAssets, prepare } from 'nitropack'\nimport type { Nitro } from 'nitropack'\n\nexport async function buildNitroEnvironment(\n nitro: Nitro,\n build: () => Promise<any>,\n) {\n await prepare(nitro)\n await copyPublicAssets(nitro)\n await build()\n\n const publicDir = nitro.options.output.publicDir\n\n // As a part of the build process, the `.vite/` directory\n // is copied over from `.tanstack-start/build/client-dist/`\n // to the `publicDir` (e.g. `.output/public/`).\n // This directory (containing the vite manifest) should not be\n // included in the final build, so we remove it here.\n const viteDir = path.resolve(publicDir, '.vite')\n if (await fsp.stat(viteDir).catch(() => false)) {\n await fsp.rm(viteDir, { recursive: true, force: true })\n }\n\n await nitro.close()\n}\n"],"names":["prepare","copyPublicAssets","fsp"],"mappings":";;;;;AAKsB,eAAA,sBACpB,OACA,OACA;AACA,QAAMA,UAAAA,QAAQ,KAAK;AACnB,QAAMC,UAAAA,iBAAiB,KAAK;AAC5B,QAAM,MAAM;AAEN,QAAA,YAAY,MAAM,QAAQ,OAAO;AAOvC,QAAM,UAAU,KAAK,QAAQ,WAAW,OAAO;AAC3C,MAAA,MAAMC,YAAI,KAAK,OAAO,EAAE,MAAM,MAAM,KAAK,GAAG;AACxC,UAAAA,GAAA,SAAI,GAAG,SAAS,EAAE,WAAW,MAAM,OAAO,MAAM;AAAA,EAAA;AAGxD,QAAM,MAAM,MAAM;AACpB;;"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dev-server-plugin.cjs","sources":["../../../src/nitro/dev-server-plugin.ts"],"sourcesContent":["import { createEvent, getHeader, sendWebResponse } from 'h3'\nimport { isRunnableDevEnvironment } from 'vite'\nimport { extractHtmlScripts } from '../extractHtmlScripts'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport type { Connect, DevEnvironment, Plugin, ViteDevServer } from 'vite'\n\ndeclare global {\n // eslint-disable-next-line no-var\n var TSS_INJECTED_HEAD_SCRIPTS: string | undefined\n}\n\nexport function devServerPlugin(): Plugin {\n // let config: UserConfig\n let isTest = false\n\n return {\n name: 'start-dev-ssr-plugin',\n config(userConfig, { mode }) {\n // config = userConfig\n isTest = isTest ? isTest : mode === 'test'\n },\n configureServer(viteDevServer) {\n if (isTest) {\n return\n }\n\n ;(globalThis as any).viteDevServer = viteDevServer\n\n return () => {\n remove_html_middlewares(viteDevServer.middlewares)\n let cachedScripts: string | undefined\n viteDevServer.middlewares.use(async (req, res) => {\n const event = createEvent(req, res)\n const serverEnv = viteDevServer.environments[\n VITE_ENVIRONMENT_NAMES.server\n ] as DevEnvironment | undefined\n\n try {\n if (!serverEnv) {\n throw new Error(\n `Server environment ${VITE_ENVIRONMENT_NAMES.server} not found`,\n )\n }\n if (!isRunnableDevEnvironment(serverEnv)) {\n throw new Error(\n `Expected server environment ${VITE_ENVIRONMENT_NAMES.server} to be a RunnableDevEnvironment. This can be caused by multiple vite versions being installed in the project.`,\n )\n }\n if (cachedScripts === undefined) {\n const templateHtml = `<html><head></head><body></body></html>`\n const transformedHtml = await viteDevServer.transformIndexHtml(\n req.url || '/',\n templateHtml,\n )\n const scripts = extractHtmlScripts(transformedHtml)\n globalThis.TSS_INJECTED_HEAD_SCRIPTS = scripts\n .map((script) => script.content ?? '')\n .join(';')\n }\n const serverEntry = await serverEnv.runner.import(\n '/~start/server-entry',\n )\n const response = await serverEntry['default'](event)\n\n return sendWebResponse(event, response)\n } catch (e) {\n console.error(e)\n viteDevServer.ssrFixStacktrace(e as Error)\n\n if (\n getHeader(event, 'content-type')?.includes('application/json')\n ) {\n return sendWebResponse(\n event,\n new Response(\n JSON.stringify(\n {\n status: 500,\n error: 'Internal Server Error',\n message:\n 'An unexpected error occurred. Please try again later.',\n timestamp: new Date().toISOString(),\n },\n null,\n 2,\n ),\n {\n status: 500,\n headers: {\n 'Content-Type': 'application/json',\n },\n },\n ),\n )\n }\n\n return sendWebResponse(\n event,\n new Response(\n `\n <!DOCTYPE html>\n <html lang=\"en\">\n <head>\n <meta charset=\"UTF-8\" />\n <title>Error</title>\n <script type=\"module\">\n import { ErrorOverlay } from '/@vite/client'\n document.body.appendChild(new ErrorOverlay(${JSON.stringify(\n prepareError(req, e),\n ).replace(/</g, '\\\\u003c')}))\n </script>\n </head>\n <body>\n </body>\n </html>\n `,\n {\n status: 500,\n headers: {\n 'Content-Type': 'text/html',\n },\n },\n ),\n )\n }\n })\n }\n },\n }\n}\n\n/**\n * Removes Vite internal middleware\n *\n * @param server\n */\nfunction remove_html_middlewares(server: ViteDevServer['middlewares']) {\n const html_middlewares = [\n 'viteIndexHtmlMiddleware',\n 'vite404Middleware',\n 'viteSpaFallbackMiddleware',\n ]\n for (let i = server.stack.length - 1; i > 0; i--) {\n if (\n html_middlewares.includes(\n // @ts-expect-error\n server.stack[i].handle.name,\n )\n ) {\n server.stack.splice(i, 1)\n }\n }\n}\n\n/**\n * Formats error for SSR message in error overlay\n * @param req\n * @param error\n * @returns\n */\nfunction prepareError(req: Connect.IncomingMessage, error: unknown) {\n const e = error as Error\n return {\n message: `An error occured while server rendering ${req.url}:\\n\\n\\t${\n typeof e === 'string' ? e : e.message\n } `,\n stack: typeof e === 'string' ? '' : e.stack,\n }\n}\n"],"names":["createEvent","VITE_ENVIRONMENT_NAMES","isRunnableDevEnvironment","extractHtmlScripts","sendWebResponse","getHeader"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nitro-plugin.cjs","sources":["../../../src/nitro/nitro-plugin.ts"],"sourcesContent":["import path from 'node:path'\nimport { rmSync } from 'node:fs'\nimport { build, createNitro } from 'nitropack'\nimport { dirname, resolve } from 'pathe'\nimport { clientDistDir, ssrEntryFile } from '../plugin'\nimport { prerender } from '../prerender'\nimport { VITE_ENVIRONMENT_NAMES } from '../constants'\nimport { buildSitemap } from '../build-sitemap'\nimport { devServerPlugin } from './dev-server-plugin'\nimport { buildNitroEnvironment } from './build-nitro'\nimport type { EnvironmentOptions, PluginOption, Rollup } from 'vite'\nimport type { NitroConfig } from 'nitropack'\nimport type { TanStackStartOutputConfig } from '../plugin'\n\nexport function nitroPlugin(\n options: TanStackStartOutputConfig,\n getSsrBundle: () => Rollup.OutputBundle,\n): Array<PluginOption> {\n const buildPreset =\n process.env['START_TARGET'] ?? (options.target as string | undefined)\n\n return [\n devServerPlugin(),\n {\n name: 'tanstack-vite-plugin-nitro',\n configEnvironment(name) {\n if (name === VITE_ENVIRONMENT_NAMES.server) {\n return {\n build: {\n commonjsOptions: {\n include: [],\n },\n ssr: true,\n sourcemap: true,\n rollupOptions: {\n input: '/~start/server-entry',\n },\n },\n } satisfies EnvironmentOptions\n }\n\n return null\n },\n config() {\n return {\n builder: {\n sharedPlugins: true,\n async buildApp(builder) {\n const clientEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.client]\n const serverEnv =\n builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!clientEnv) {\n throw new Error('Client environment not found')\n }\n\n if (!serverEnv) {\n throw new Error('SSR environment not found')\n }\n\n const clientOutputDir = resolve(options.root, clientDistDir)\n rmSync(clientOutputDir, { recursive: true, force: true })\n await builder.build(clientEnv)\n\n await builder.build(serverEnv)\n\n const nitroConfig: NitroConfig = {\n dev: false,\n // TODO do we need this? should this be made configurable?\n compatibilityDate: '2024-11-19',\n logLevel: 3,\n preset: buildPreset,\n publicAssets: [\n {\n dir: path.resolve(options.root, clientDistDir),\n },\n ],\n typescript: {\n generateTsConfig: false,\n },\n prerender: undefined,\n renderer: ssrEntryFile,\n rollupConfig: {\n plugins: [virtualBundlePlugin(getSsrBundle())],\n },\n }\n\n const nitro = await createNitro(nitroConfig)\n\n await buildNitroEnvironment(nitro, () => build(nitro))\n\n // If the user has not set a prerender option, we need to set it to true\n // if the pages array is not empty and has sub options requiring for prerendering\n if (options.prerender?.enabled !== false) {\n options.prerender = {\n ...options.prerender,\n enabled: options.pages.some((d) =>\n typeof d === 'string' ? false : !!d.prerender?.enabled,\n ),\n }\n }\n\n // Setup the options for prerendering the SPA shell (i.e `src/routes/__root.tsx`)\n if (options.spa?.enabled) {\n options.prerender = {\n ...options.prerender,\n enabled: true,\n }\n\n const maskUrl = new URL(\n options.spa.maskPath,\n 'http://localhost',\n )\n\n maskUrl.searchParams.set('__TSS_SHELL', 'true')\n\n options.pages.push({\n path: maskUrl.toString().replace('http://localhost', ''),\n prerender: options.spa.prerender,\n sitemap: {\n exclude: true,\n },\n })\n }\n\n // Start prerendering!!!\n if (options.prerender.enabled) {\n await prerender({\n options,\n nitro,\n builder,\n })\n }\n\n if (options.pages.length) {\n await buildSitemap({\n options,\n publicDir: nitro.options.output.publicDir,\n })\n }\n\n console.log(`\\n✅ Client and server bundles successfully built.`)\n },\n },\n }\n },\n },\n ]\n}\n\nfunction virtualBundlePlugin(ssrBundle: Rollup.OutputBundle): Rollup.Plugin {\n type VirtualModule = { code: string; map: string | null }\n const _modules = new Map<string, VirtualModule>()\n\n // group chunks and source maps\n for (const [fileName, content] of Object.entries(ssrBundle)) {\n if (content.type === 'chunk') {\n const virtualModule: VirtualModule = {\n code: content.code,\n map: null,\n }\n const maybeMap = ssrBundle[`${fileName}.map`]\n if (maybeMap && maybeMap.type === 'asset') {\n virtualModule.map = maybeMap.source as string\n }\n _modules.set(fileName, virtualModule)\n _modules.set(resolve(fileName), virtualModule)\n }\n }\n\n return {\n name: 'virtual-bundle',\n resolveId(id, importer) {\n if (_modules.has(id)) {\n return resolve(id)\n }\n\n if (importer) {\n const resolved = resolve(dirname(importer), id)\n if (_modules.has(resolved)) {\n return resolved\n }\n }\n return null\n },\n load(id) {\n const m = _modules.get(id)\n if (!m) {\n return null\n }\n return m\n },\n }\n}\n"],"names":["devServerPlugin","VITE_ENVIRONMENT_NAMES","resolve","clientDistDir","rmSync","ssrEntryFile","createNitro","buildNitroEnvironment","build","_a","prerender","buildSitemap","dirname"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prerender.cjs","sources":["../../src/prerender.ts"],"sourcesContent":["import { promises as fsp } from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\nimport { getRollupConfig } from 'nitropack/rollup'\nimport { build as buildNitro, createNitro } from 'nitropack'\nimport { joinURL, withBase, withoutBase } from 'ufo'\nimport { Queue } from './queue'\nimport { buildNitroEnvironment } from './nitro/build-nitro'\nimport { VITE_ENVIRONMENT_NAMES } from './constants'\nimport type { ViteBuilder } from 'vite'\nimport type { $Fetch, Nitro } from 'nitropack'\nimport type { TanStackStartOutputConfig } from './plugin'\nimport type { Page } from './schema'\n\nexport async function prerender({\n options,\n nitro,\n builder,\n}: {\n options: TanStackStartOutputConfig\n nitro: Nitro\n builder: ViteBuilder\n}) {\n console.info('Prendering pages...')\n\n // If prerender is enabled but no pages are provided, default to prerendering the root page\n if (options.prerender?.enabled && !options.pages.length) {\n options.pages = [\n {\n path: '/',\n },\n ]\n }\n\n const serverEnv = builder.environments[VITE_ENVIRONMENT_NAMES.server]\n\n if (!serverEnv) {\n throw new Error(\n `Vite's \"${VITE_ENVIRONMENT_NAMES.server}\" environment not found`,\n )\n }\n\n const prerenderOutputDir = path.resolve(\n options.root,\n '.tanstack-start/build/prerenderer',\n )\n\n const nodeNitro = await createNitro({\n ...nitro.options._config,\n preset: 'nitro-prerender',\n logLevel: 0,\n output: {\n dir: prerenderOutputDir,\n serverDir: path.resolve(prerenderOutputDir, 'server'),\n publicDir: path.resolve(prerenderOutputDir, 'public'),\n },\n })\n\n const nodeNitroRollupOptions = getRollupConfig(nodeNitro)\n\n const build = serverEnv.config.build\n\n build.outDir = prerenderOutputDir\n\n build.rollupOptions = {\n ...build.rollupOptions,\n ...nodeNitroRollupOptions,\n output: {\n ...build.rollupOptions.output,\n ...nodeNitroRollupOptions.output,\n sourcemap: undefined,\n },\n }\n\n await buildNitroEnvironment(nodeNitro, () => buildNitro(nodeNitro))\n\n // Import renderer entry\n const serverFilename =\n typeof nodeNitroRollupOptions.output.entryFileNames === 'string'\n ? nodeNitroRollupOptions.output.entryFileNames\n : 'index.mjs'\n\n const serverEntrypoint = path.resolve(\n path.join(nodeNitro.options.output.serverDir, serverFilename),\n )\n\n const { closePrerenderer, localFetch } = (await import(serverEntrypoint)) as {\n closePrerenderer: () => void\n localFetch: $Fetch\n }\n\n try {\n // Crawl all pages\n const pages = await prerenderPages()\n\n console.info(`Prerendered ${pages.length} pages:`)\n pages.forEach((page) => {\n console.info(`- ${page}`)\n })\n\n // TODO: Write the prerendered pages to the output directory\n } catch (error) {\n console.error(error)\n } finally {\n // Ensure server is always closed\n // server.process.kill()\n closePrerenderer()\n }\n\n function extractLinks(html: string): Array<string> {\n const linkRegex = /<a[^>]+href=[\"']([^\"']+)[\"'][^>]*>/g\n const links: Array<string> = []\n let match\n\n while ((match = linkRegex.exec(html)) !== null) {\n const href = match[1]\n if (href && (href.startsWith('/') || href.startsWith('./'))) {\n links.push(href)\n }\n }\n\n return links\n }\n\n async function prerenderPages() {\n const seen = new Set<string>()\n const retriesByPath = new Map<string, number>()\n const concurrency = options.prerender?.concurrency ?? os.cpus().length\n console.info(`Concurrency: ${concurrency}`)\n const queue = new Queue({ concurrency })\n\n options.pages.forEach((page) => addCrawlPageTask(page))\n\n await queue.start()\n\n return Array.from(seen)\n\n function addCrawlPageTask(page: Page) {\n // Was the page already seen?\n if (seen.has(page.path)) return\n\n // Add the page to the seen set\n seen.add(page.path)\n\n if (page.fromCrawl) {\n options.pages.push(page)\n }\n\n // If not enabled, skip\n if (!(page.prerender?.enabled ?? true)) return\n\n // If there is a filter link, check if the page should be prerendered\n if (options.prerender?.filter && !options.prerender.filter(page)) return\n\n // Resolve the merged default and page-specific prerender options\n const prerenderOptions = {\n ...options.prerender,\n ...page.prerender,\n }\n\n // Add the task\n queue.add(async () => {\n console.info(`Crawling: ${page.path}`)\n const retries = retriesByPath.get(page.path) || 0\n try {\n // Fetch the route\n const encodedRoute = encodeURI(page.path)\n\n const res = await localFetch<Response>(\n withBase(encodedRoute, nodeNitro.options.baseURL),\n {\n headers: { 'x-nitro-prerender': encodedRoute },\n },\n )\n\n if (!res.ok) {\n throw new Error(`Failed to fetch ${page.path}: ${res.statusText}`, {\n cause: res,\n })\n }\n\n const cleanPagePath = (\n prerenderOptions.outputPath || page.path\n ).split(/[?#]/)[0]!\n\n // Guess route type and populate fileName\n const contentType = res.headers.get('content-type') || ''\n const isImplicitHTML =\n !cleanPagePath.endsWith('.html') && contentType.includes('html')\n // &&\n // !JsonSigRx.test(dataBuff.subarray(0, 32).toString('utf8'))\n const routeWithIndex = cleanPagePath.endsWith('/')\n ? cleanPagePath + 'index'\n : cleanPagePath\n\n const htmlPath =\n cleanPagePath.endsWith('/') || prerenderOptions.autoSubfolderIndex\n ? joinURL(cleanPagePath, 'index.html')\n : cleanPagePath + '.html'\n\n const filename = withoutBase(\n isImplicitHTML ? htmlPath : routeWithIndex,\n nitro.options.baseURL,\n )\n\n const html = await res.text()\n\n const filepath = path.join(nitro.options.output.publicDir, filename)\n\n await fsp.mkdir(path.dirname(filepath), {\n recursive: true,\n })\n\n await fsp.writeFile(filepath, html)\n\n const newPage = await prerenderOptions.onSuccess?.({ page, html })\n\n if (newPage) {\n Object.assign(page, newPage)\n }\n\n // Find new links\n if (prerenderOptions.crawlLinks ?? true) {\n const links = extractLinks(html)\n for (const link of links) {\n addCrawlPageTask({ path: link, fromCrawl: true })\n }\n }\n } catch (error) {\n if (retries < (prerenderOptions.retryCount ?? 0)) {\n console.warn(`Encountered error, retrying: ${page.path} in 500ms`)\n await new Promise((resolve) =>\n setTimeout(resolve, prerenderOptions.retryDelay),\n )\n retriesByPath.set(page.path, retries + 1)\n addCrawlPageTask(page)\n } else {\n throw error\n }\n }\n })\n }\n }\n}\n"],"names":["VITE_ENVIRONMENT_NAMES","createNitro","getRollupConfig","buildNitroEnvironment","buildNitro","_a","queue","Queue","withBase","joinURL","withoutBase","fsp"],"mappings":"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"}
|
package/dist/cjs/queue.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"queue.cjs","sources":["../../src/queue.ts"],"sourcesContent":["interface PoolConfig {\n concurrency?: number\n started?: boolean\n tasks?: Array<() => Promise<any>>\n}\n\nconst defaultConfig: PoolConfig = {\n concurrency: 5,\n started: false,\n tasks: [],\n}\n\nexport class Queue<T> {\n private onSettles: Array<(res: any, error: any) => void> = []\n private onErrors: Array<(error: any, task: () => Promise<any>) => void> = []\n private onSuccesses: Array<(result: any, task: () => Promise<any>) => void> =\n []\n private running: boolean\n private active: Array<() => Promise<any>> = []\n private pending: Array<() => Promise<any>>\n private currentConcurrency: number\n\n constructor(config: PoolConfig = defaultConfig) {\n const { concurrency, started, tasks } = {\n ...defaultConfig,\n ...config,\n }\n this.running = started!\n this.pending = tasks as Array<() => Promise<any>>\n this.currentConcurrency = concurrency!\n }\n\n private tick() {\n if (!this.running) {\n return\n }\n while (\n this.active.length < this.currentConcurrency &&\n this.pending.length\n ) {\n const nextFn = this.pending.shift()\n if (!nextFn) {\n throw new Error('Found task that is not a function')\n }\n this.active.push(nextFn)\n ;(async () => {\n let success = false\n let res!: T\n let error: any\n try {\n res = await nextFn()\n success = true\n } catch (e) {\n error = e\n }\n this.active = this.active.filter((d) => d !== nextFn)\n if (success) {\n this.onSuccesses.forEach((d) => d(res, nextFn))\n } else {\n this.onErrors.forEach((d) => d(error, nextFn))\n }\n this.onSettles.forEach((d) => d(res, error))\n this.tick()\n })()\n }\n }\n\n add(fn: () => Promise<T> | T, { priority }: { priority?: boolean } = {}) {\n return new Promise<any>((resolve, reject) => {\n const task = () =>\n Promise.resolve(fn())\n .then((res) => {\n resolve(res)\n return res\n })\n .catch((err) => {\n reject(err)\n throw err\n })\n if (priority) {\n this.pending.unshift(task)\n } else {\n this.pending.push(task)\n }\n this.tick()\n })\n }\n\n throttle(n: number) {\n this.currentConcurrency = n\n }\n\n onSettled(cb: () => void) {\n this.onSettles.push(cb)\n return () => {\n this.onSettles = this.onSettles.filter((d) => d !== cb)\n }\n }\n\n onError(cb: (error: any, task: () => Promise<any>) => void) {\n this.onErrors.push(cb)\n return () => {\n this.onErrors = this.onErrors.filter((d) => d !== cb)\n }\n }\n\n onSuccess(cb: (result: any, task: () => Promise<any>) => void) {\n this.onSuccesses.push(cb)\n return () => {\n this.onSuccesses = this.onSuccesses.filter((d) => d !== cb)\n }\n }\n\n stop() {\n this.running = false\n }\n\n start() {\n this.running = true\n this.tick()\n return new Promise<void>((resolve) => {\n this.onSettled(() => {\n if (this.isSettled()) {\n resolve()\n }\n })\n })\n }\n\n clear() {\n this.pending = []\n }\n\n getActive() {\n return this.active\n }\n\n getPending() {\n return this.pending\n }\n\n getAll() {\n return [...this.active, ...this.pending]\n }\n\n isRunning() {\n return this.running\n }\n\n isSettled() {\n return !this.active.length && !this.pending.length\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const fs = require("node:fs");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
const ufo = require("ufo");
|
|
6
|
-
const routerCore = require("@tanstack/router-core");
|
|
7
|
-
const utils = require("./utils.cjs");
|
|
8
|
-
function startManifestPlugin(opts) {
|
|
9
|
-
let config;
|
|
10
|
-
const moduleId = "tanstack-start-router-manifest:v";
|
|
11
|
-
const resolvedModuleId = utils.resolveViteId(moduleId);
|
|
12
|
-
return {
|
|
13
|
-
name: "tsr-routes-manifest",
|
|
14
|
-
enforce: "pre",
|
|
15
|
-
configResolved(resolvedConfig) {
|
|
16
|
-
config = resolvedConfig;
|
|
17
|
-
},
|
|
18
|
-
// configEnvironment(env, envConfig) {
|
|
19
|
-
// config = envConfig.
|
|
20
|
-
// },
|
|
21
|
-
resolveId(id) {
|
|
22
|
-
if (id === moduleId) {
|
|
23
|
-
return resolvedModuleId;
|
|
24
|
-
}
|
|
25
|
-
return;
|
|
26
|
-
},
|
|
27
|
-
load(id) {
|
|
28
|
-
var _a, _b;
|
|
29
|
-
if (id === resolvedModuleId) {
|
|
30
|
-
if (this.environment.config.consumer !== "server") {
|
|
31
|
-
return `export default {}`;
|
|
32
|
-
}
|
|
33
|
-
if (config.command === "serve") {
|
|
34
|
-
return `export const tsrStartManifest = () => ({
|
|
35
|
-
entry: "$${process.env.TSS_CLIENT_BASE}/",
|
|
36
|
-
routes: {}
|
|
37
|
-
})`;
|
|
38
|
-
}
|
|
39
|
-
const clientViteManifestPath = path.resolve(
|
|
40
|
-
opts.root,
|
|
41
|
-
".tanstack-start/build/client-dist/.vite/manifest.json"
|
|
42
|
-
);
|
|
43
|
-
let viteManifest;
|
|
44
|
-
try {
|
|
45
|
-
viteManifest = JSON.parse(
|
|
46
|
-
fs.readFileSync(clientViteManifestPath, "utf-8")
|
|
47
|
-
);
|
|
48
|
-
} catch (err) {
|
|
49
|
-
console.error(err);
|
|
50
|
-
throw new Error(
|
|
51
|
-
`Could not find the production client vite manifest at '${clientViteManifestPath}'!`
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
const routeTreePath = path.resolve(opts.tsr.generatedRouteTree);
|
|
55
|
-
let routeTreeContent;
|
|
56
|
-
try {
|
|
57
|
-
routeTreeContent = fs.readFileSync(routeTreePath, "utf-8");
|
|
58
|
-
} catch (err) {
|
|
59
|
-
console.error(err);
|
|
60
|
-
throw new Error(
|
|
61
|
-
`Could not find the generated route tree at '${routeTreePath}'!`
|
|
62
|
-
);
|
|
63
|
-
}
|
|
64
|
-
const routerManifest = JSON.parse(
|
|
65
|
-
((_a = routeTreeContent.match(
|
|
66
|
-
/\/\* ROUTE_MANIFEST_START([\s\S]*?)ROUTE_MANIFEST_END \*\//
|
|
67
|
-
)) == null ? void 0 : _a[1]) || "{ routes: {} }"
|
|
68
|
-
);
|
|
69
|
-
const routes = routerManifest.routes;
|
|
70
|
-
let entryFile;
|
|
71
|
-
const filesByRouteFilePath = Object.fromEntries(
|
|
72
|
-
Object.entries(viteManifest).map(([k, v]) => {
|
|
73
|
-
if (v.isEntry) {
|
|
74
|
-
entryFile = v;
|
|
75
|
-
}
|
|
76
|
-
const rPath = k.split("?")[0];
|
|
77
|
-
return [rPath, v];
|
|
78
|
-
}, {})
|
|
79
|
-
);
|
|
80
|
-
const routesDirectoryFromRoot = path.relative(
|
|
81
|
-
opts.root,
|
|
82
|
-
opts.tsr.routesDirectory
|
|
83
|
-
);
|
|
84
|
-
Object.entries(routes).forEach(([k, v]) => {
|
|
85
|
-
const file = filesByRouteFilePath[path.join(routesDirectoryFromRoot, v.filePath)];
|
|
86
|
-
if (file) {
|
|
87
|
-
const preloads = (file.imports ?? []).map(
|
|
88
|
-
(d) => path.join("/", viteManifest[d].file)
|
|
89
|
-
);
|
|
90
|
-
if (file.file) {
|
|
91
|
-
preloads.unshift(path.join("/", file.file));
|
|
92
|
-
}
|
|
93
|
-
const cssFiles = file.css ?? [];
|
|
94
|
-
const cssAssetsList = cssFiles.map(
|
|
95
|
-
(cssFile) => ({
|
|
96
|
-
tag: "link",
|
|
97
|
-
attrs: {
|
|
98
|
-
rel: "stylesheet",
|
|
99
|
-
href: ufo.joinURL("/", cssFile),
|
|
100
|
-
type: "text/css"
|
|
101
|
-
}
|
|
102
|
-
})
|
|
103
|
-
);
|
|
104
|
-
routes[k] = {
|
|
105
|
-
...v,
|
|
106
|
-
assets: [...v.assets || [], ...cssAssetsList],
|
|
107
|
-
preloads
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
});
|
|
111
|
-
if (entryFile) {
|
|
112
|
-
routes[routerCore.rootRouteId].preloads = [
|
|
113
|
-
path.join("/", entryFile.file),
|
|
114
|
-
...((_b = entryFile.imports) == null ? void 0 : _b.map(
|
|
115
|
-
(d) => path.join("/", viteManifest[d].file)
|
|
116
|
-
)) || []
|
|
117
|
-
];
|
|
118
|
-
const entryCssFiles = entryFile.css ?? [];
|
|
119
|
-
const entryCssAssetsList = entryCssFiles.map(
|
|
120
|
-
(cssFile) => ({
|
|
121
|
-
tag: "link",
|
|
122
|
-
attrs: {
|
|
123
|
-
rel: "stylesheet",
|
|
124
|
-
href: ufo.joinURL("/", cssFile),
|
|
125
|
-
type: "text/css"
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
-
);
|
|
129
|
-
routes[routerCore.rootRouteId].assets = [
|
|
130
|
-
...routes[routerCore.rootRouteId].assets || [],
|
|
131
|
-
...entryCssAssetsList,
|
|
132
|
-
{
|
|
133
|
-
tag: "script",
|
|
134
|
-
attrs: {
|
|
135
|
-
src: ufo.joinURL("/", entryFile.file),
|
|
136
|
-
type: "module"
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
];
|
|
140
|
-
}
|
|
141
|
-
const recurseRoute = (route, seenPreloads = {}) => {
|
|
142
|
-
var _a2;
|
|
143
|
-
route.preloads = (_a2 = route.preloads) == null ? void 0 : _a2.filter((preload) => {
|
|
144
|
-
if (seenPreloads[preload]) {
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
seenPreloads[preload] = true;
|
|
148
|
-
return true;
|
|
149
|
-
});
|
|
150
|
-
if (route.children) {
|
|
151
|
-
route.children.forEach((child) => {
|
|
152
|
-
const childRoute = routes[child];
|
|
153
|
-
recurseRoute(childRoute, { ...seenPreloads });
|
|
154
|
-
});
|
|
155
|
-
}
|
|
156
|
-
};
|
|
157
|
-
recurseRoute(routes[routerCore.rootRouteId]);
|
|
158
|
-
const routesManifest = {
|
|
159
|
-
routes
|
|
160
|
-
};
|
|
161
|
-
return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`;
|
|
162
|
-
}
|
|
163
|
-
return;
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
exports.startManifestPlugin = startManifestPlugin;
|
|
168
|
-
//# sourceMappingURL=routesManifestPlugin.cjs.map
|