@tanstack/start-plugin-core 1.136.8 → 1.136.9
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/esm/start-manifest-plugin/plugin.js +22 -15
- package/dist/esm/start-manifest-plugin/plugin.js.map +1 -1
- package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js +4 -4
- package/dist/esm/start-router-plugin/generator-plugins/routes-manifest-plugin.js.map +1 -1
- package/package.json +6 -6
- package/src/global.d.ts +7 -3
- package/src/start-manifest-plugin/plugin.ts +24 -16
- package/src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts +10 -4
|
@@ -71,7 +71,7 @@ function startManifestPlugin(opts) {
|
|
|
71
71
|
clientEntry: '${joinURL(resolvedStartConfig.viteAppBase, "@id", ENTRY_POINTS.client)}',
|
|
72
72
|
})`;
|
|
73
73
|
}
|
|
74
|
-
const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST
|
|
74
|
+
const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST;
|
|
75
75
|
const cssPerChunkCache = /* @__PURE__ */ new Map();
|
|
76
76
|
let entryFile;
|
|
77
77
|
const clientBundle = opts.getClientBundle();
|
|
@@ -118,6 +118,7 @@ function startManifestPlugin(opts) {
|
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
|
+
const manifest = { routes: {} };
|
|
121
122
|
Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {
|
|
122
123
|
if (!v.filePath) {
|
|
123
124
|
throw new Error(`expected filePath to be set for ${routeId}`);
|
|
@@ -126,30 +127,36 @@ function startManifestPlugin(opts) {
|
|
|
126
127
|
if (chunks) {
|
|
127
128
|
chunks.forEach((chunk) => {
|
|
128
129
|
const preloads = chunk.imports.map((d) => {
|
|
129
|
-
const
|
|
130
|
-
|
|
130
|
+
const preloadPath = joinURL(
|
|
131
|
+
resolvedStartConfig.viteAppBase,
|
|
132
|
+
d
|
|
133
|
+
);
|
|
134
|
+
return preloadPath;
|
|
131
135
|
});
|
|
132
136
|
preloads.unshift(
|
|
133
137
|
joinURL(resolvedStartConfig.viteAppBase, chunk.fileName)
|
|
134
138
|
);
|
|
135
|
-
const
|
|
139
|
+
const assets = getCSSRecursively(
|
|
136
140
|
chunk,
|
|
137
141
|
chunksByFileName,
|
|
138
142
|
resolvedStartConfig.viteAppBase,
|
|
139
143
|
cssPerChunkCache
|
|
140
144
|
);
|
|
141
|
-
|
|
145
|
+
manifest.routes[routeId] = {
|
|
142
146
|
...v,
|
|
143
|
-
assets
|
|
144
|
-
preloads
|
|
147
|
+
assets,
|
|
148
|
+
preloads
|
|
145
149
|
};
|
|
146
150
|
});
|
|
151
|
+
} else {
|
|
152
|
+
manifest.routes[routeId] = v;
|
|
147
153
|
}
|
|
148
154
|
});
|
|
149
155
|
if (!entryFile) {
|
|
150
156
|
throw new Error("No entry file found");
|
|
151
157
|
}
|
|
152
|
-
|
|
158
|
+
manifest.routes[rootRouteId] = manifest.routes[rootRouteId] || {};
|
|
159
|
+
manifest.routes[rootRouteId].preloads = [
|
|
153
160
|
joinURL(resolvedStartConfig.viteAppBase, entryFile.fileName),
|
|
154
161
|
...entryFile.imports.map(
|
|
155
162
|
(d) => joinURL(resolvedStartConfig.viteAppBase, d)
|
|
@@ -161,8 +168,8 @@ function startManifestPlugin(opts) {
|
|
|
161
168
|
resolvedStartConfig.viteAppBase,
|
|
162
169
|
cssPerChunkCache
|
|
163
170
|
);
|
|
164
|
-
|
|
165
|
-
...
|
|
171
|
+
manifest.routes[rootRouteId].assets = [
|
|
172
|
+
...manifest.routes[rootRouteId].assets || [],
|
|
166
173
|
...entryCssAssetsList
|
|
167
174
|
];
|
|
168
175
|
const recurseRoute = (route, seenPreloads = {}) => {
|
|
@@ -175,14 +182,14 @@ function startManifestPlugin(opts) {
|
|
|
175
182
|
});
|
|
176
183
|
if (route.children) {
|
|
177
184
|
route.children.forEach((child) => {
|
|
178
|
-
const childRoute =
|
|
185
|
+
const childRoute = manifest.routes[child];
|
|
179
186
|
recurseRoute(childRoute, { ...seenPreloads });
|
|
180
187
|
});
|
|
181
188
|
}
|
|
182
189
|
};
|
|
183
|
-
recurseRoute(
|
|
184
|
-
Object.keys(
|
|
185
|
-
const route =
|
|
190
|
+
recurseRoute(manifest.routes[rootRouteId]);
|
|
191
|
+
Object.keys(manifest.routes).forEach((routeId) => {
|
|
192
|
+
const route = manifest.routes[routeId];
|
|
186
193
|
const hasAssets = route.assets && route.assets.length > 0;
|
|
187
194
|
const hasPreloads = route.preloads && route.preloads.length > 0;
|
|
188
195
|
if (!hasAssets && !hasPreloads) {
|
|
@@ -190,7 +197,7 @@ function startManifestPlugin(opts) {
|
|
|
190
197
|
}
|
|
191
198
|
});
|
|
192
199
|
const startManifest = {
|
|
193
|
-
routes:
|
|
200
|
+
routes: manifest.routes,
|
|
194
201
|
clientEntry: joinURL(
|
|
195
202
|
resolvedStartConfig.viteAppBase,
|
|
196
203
|
entryFile.fileName
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.js","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport { ENTRY_POINTS } from '../constants'\nimport type { GetConfigFn } from '../plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { RouterManagedTag } from '@tanstack/router-core'\n\nconst getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n cache: Map<Rollup.OutputChunk, Array<RouterManagedTag>>,\n visited = new Set<Rollup.OutputChunk>(),\n) => {\n if (visited.has(chunk)) {\n return []\n }\n visited.add(chunk)\n const cachedResult = cache.get(chunk)\n if (cachedResult) {\n return cachedResult\n }\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(\n importedChunk,\n chunksByFileName,\n basePath,\n cache,\n visited,\n ),\n )\n }\n }\n\n cache.set(chunk, result)\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(opts: {\n getClientBundle: () => Rollup.OutputBundle\n getConfig: GetConfigFn\n}): PluginOption {\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n const { resolvedStartConfig } = opts.getConfig()\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (this.environment.config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(resolvedStartConfig.viteAppBase, '@id', ENTRY_POINTS.client)}',\n })`\n }\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST.routes\n\n const cssPerChunkCache = new Map<\n Rollup.OutputChunk,\n Array<RouterManagedTag>\n >()\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = opts.getClientBundle()\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const assetPath = joinURL(resolvedStartConfig.viteAppBase, d)\n return assetPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(\n joinURL(resolvedStartConfig.viteAppBase, chunk.fileName),\n )\n\n const cssAssetsList = getCSSRecursively(\n chunk,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n routeTreeRoutes[routeId] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads: [...(v.preloads || []), ...preloads],\n }\n })\n }\n })\n\n if (!entryFile) {\n throw new Error('No entry file found')\n }\n routeTreeRoutes[rootRouteId]!.preloads = [\n joinURL(resolvedStartConfig.viteAppBase, entryFile.fileName),\n ...entryFile.imports.map((d) =>\n joinURL(resolvedStartConfig.viteAppBase, d),\n ),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n routeTreeRoutes[rootRouteId]!.assets = [\n ...(routeTreeRoutes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n ]\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = routeTreeRoutes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(routeTreeRoutes[rootRouteId]!)\n\n // Filter out routes that have neither assets nor preloads\n Object.keys(routeTreeRoutes).forEach((routeId) => {\n const route = routeTreeRoutes[routeId]!\n const hasAssets = route.assets && route.assets.length > 0\n const hasPreloads = route.preloads && route.preloads.length > 0\n if (!hasAssets && !hasPreloads) {\n delete routeTreeRoutes[routeId]\n }\n })\n\n const startManifest = {\n routes: routeTreeRoutes,\n clientEntry: joinURL(\n resolvedStartConfig.viteAppBase,\n entryFile.fileName,\n ),\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(startManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["id"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["../../../src/start-manifest-plugin/plugin.ts"],"sourcesContent":["import { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { VIRTUAL_MODULES } from '@tanstack/start-server-core'\nimport { tsrSplit } from '@tanstack/router-plugin'\nimport { resolveViteId } from '../utils'\nimport { ENTRY_POINTS } from '../constants'\nimport type { GetConfigFn } from '../plugin'\nimport type { PluginOption, Rollup } from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\n\nconst getCSSRecursively = (\n chunk: Rollup.OutputChunk,\n chunksByFileName: Map<string, Rollup.OutputChunk>,\n basePath: string,\n cache: Map<Rollup.OutputChunk, Array<RouterManagedTag>>,\n visited = new Set<Rollup.OutputChunk>(),\n) => {\n if (visited.has(chunk)) {\n return []\n }\n visited.add(chunk)\n const cachedResult = cache.get(chunk)\n if (cachedResult) {\n return cachedResult\n }\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of chunk.viteMetadata?.importedCss ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL(basePath, cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const importedFileName of chunk.imports) {\n const importedChunk = chunksByFileName.get(importedFileName)\n if (importedChunk) {\n result.push(\n ...getCSSRecursively(\n importedChunk,\n chunksByFileName,\n basePath,\n cache,\n visited,\n ),\n )\n }\n }\n\n cache.set(chunk, result)\n return result\n}\n\nconst resolvedModuleId = resolveViteId(VIRTUAL_MODULES.startManifest)\nexport function startManifestPlugin(opts: {\n getClientBundle: () => Rollup.OutputBundle\n getConfig: GetConfigFn\n}): PluginOption {\n return {\n name: 'tanstack-start:start-manifest-plugin',\n enforce: 'pre',\n resolveId: {\n filter: { id: new RegExp(VIRTUAL_MODULES.startManifest) },\n handler(id) {\n if (id === VIRTUAL_MODULES.startManifest) {\n return resolvedModuleId\n }\n return undefined\n },\n },\n load: {\n filter: {\n id: new RegExp(resolvedModuleId),\n },\n handler(id) {\n const { resolvedStartConfig } = opts.getConfig()\n if (id === resolvedModuleId) {\n if (this.environment.config.consumer !== 'server') {\n // this will ultimately fail the build if the plugin is used outside the server environment\n // TODO: do we need special handling for `serve`?\n return `export default {}`\n }\n\n // If we're in development, return a dummy manifest\n if (this.environment.config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n routes: {},\n clientEntry: '${joinURL(resolvedStartConfig.viteAppBase, '@id', ENTRY_POINTS.client)}',\n })`\n }\n\n // This the manifest pulled from the generated route tree and later used by the Router.\n // i.e what's located in `src/routeTree.gen.ts`\n const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST\n\n const cssPerChunkCache = new Map<\n Rollup.OutputChunk,\n Array<RouterManagedTag>\n >()\n\n // This is where hydration will start, from when the SSR'd page reaches the browser.\n let entryFile: Rollup.OutputChunk | undefined\n\n const clientBundle = opts.getClientBundle()\n const chunksByFileName = new Map<string, Rollup.OutputChunk>()\n\n const routeChunks: Record<\n string /** fullPath of route file **/,\n Array<Rollup.OutputChunk>\n > = {}\n for (const bundleEntry of Object.values(clientBundle)) {\n if (bundleEntry.type === 'chunk') {\n chunksByFileName.set(bundleEntry.fileName, bundleEntry)\n if (bundleEntry.isEntry) {\n if (entryFile) {\n throw new Error(\n `multiple entries detected: ${entryFile.fileName} ${bundleEntry.fileName}`,\n )\n }\n entryFile = bundleEntry\n }\n const routePieces = bundleEntry.moduleIds.flatMap((m) => {\n const [id, query] = m.split('?')\n if (id === undefined) {\n throw new Error('expected id to be defined')\n }\n if (query === undefined) {\n return []\n }\n const searchParams = new URLSearchParams(query)\n const split = searchParams.get(tsrSplit)\n\n if (split !== null) {\n return {\n id,\n split,\n }\n }\n return []\n })\n if (routePieces.length > 0) {\n routePieces.forEach((r) => {\n let array = routeChunks[r.id]\n if (array === undefined) {\n array = []\n routeChunks[r.id] = array\n }\n array.push(bundleEntry)\n })\n }\n }\n }\n\n const manifest: Manifest = { routes: {} }\n // Add preloads to the routes from the vite manifest\n Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {\n if (!v.filePath) {\n throw new Error(`expected filePath to be set for ${routeId}`)\n }\n const chunks = routeChunks[v.filePath]\n if (chunks) {\n chunks.forEach((chunk) => {\n // Map the relevant imports to their route paths,\n // so that it can be imported in the browser.\n const preloads = chunk.imports.map((d) => {\n const preloadPath = joinURL(\n resolvedStartConfig.viteAppBase,\n d,\n )\n return preloadPath\n })\n\n // Since this is the most important JS entry for the route,\n // it should be moved to the front of the preloads so that\n // it has the best chance of being loaded first.\n preloads.unshift(\n joinURL(resolvedStartConfig.viteAppBase, chunk.fileName),\n )\n\n const assets = getCSSRecursively(\n chunk,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n manifest.routes[routeId] = {\n ...v,\n assets,\n preloads,\n }\n })\n } else {\n manifest.routes[routeId] = v\n }\n })\n\n if (!entryFile) {\n throw new Error('No entry file found')\n }\n\n manifest.routes[rootRouteId] = manifest.routes[rootRouteId] || {}\n manifest.routes[rootRouteId].preloads = [\n joinURL(resolvedStartConfig.viteAppBase, entryFile.fileName),\n ...entryFile.imports.map((d) =>\n joinURL(resolvedStartConfig.viteAppBase, d),\n ),\n ]\n\n // Gather all the CSS files from the entry file in\n // the `css` key and add them to the root route\n const entryCssAssetsList = getCSSRecursively(\n entryFile,\n chunksByFileName,\n resolvedStartConfig.viteAppBase,\n cssPerChunkCache,\n )\n\n manifest.routes[rootRouteId].assets = [\n ...(manifest.routes[rootRouteId].assets || []),\n ...entryCssAssetsList,\n ]\n\n const recurseRoute = (\n route: {\n preloads?: Array<string>\n children?: Array<any>\n },\n seenPreloads = {} as Record<string, true>,\n ) => {\n route.preloads = route.preloads?.filter((preload) => {\n if (seenPreloads[preload]) {\n return false\n }\n seenPreloads[preload] = true\n return true\n })\n\n if (route.children) {\n route.children.forEach((child) => {\n const childRoute = manifest.routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n recurseRoute(manifest.routes[rootRouteId])\n\n // Filter out routes that have neither assets nor preloads\n Object.keys(manifest.routes).forEach((routeId) => {\n const route = manifest.routes[routeId]!\n const hasAssets = route.assets && route.assets.length > 0\n const hasPreloads = route.preloads && route.preloads.length > 0\n if (!hasAssets && !hasPreloads) {\n delete routeTreeRoutes[routeId]\n }\n })\n\n const startManifest = {\n routes: manifest.routes,\n clientEntry: joinURL(\n resolvedStartConfig.viteAppBase,\n entryFile.fileName,\n ),\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(startManifest)})`\n }\n\n return undefined\n },\n },\n }\n}\n"],"names":["id"],"mappings":"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"}
|
|
@@ -3,10 +3,11 @@ function routesManifestPlugin() {
|
|
|
3
3
|
return {
|
|
4
4
|
name: "routes-manifest-plugin",
|
|
5
5
|
onRouteTreeChanged: ({ routeTree, rootRouteNode, routeNodes }) => {
|
|
6
|
-
const
|
|
6
|
+
const allChildren = routeTree.map((d) => d.routePath);
|
|
7
|
+
const routes = {
|
|
7
8
|
[rootRouteId]: {
|
|
8
9
|
filePath: rootRouteNode.fullPath,
|
|
9
|
-
children:
|
|
10
|
+
children: allChildren
|
|
10
11
|
},
|
|
11
12
|
...Object.fromEntries(
|
|
12
13
|
routeNodes.map((d) => {
|
|
@@ -15,14 +16,13 @@ function routesManifestPlugin() {
|
|
|
15
16
|
filePathId,
|
|
16
17
|
{
|
|
17
18
|
filePath: d.fullPath,
|
|
18
|
-
parent: d.parent?.routePath ? d.parent.routePath : void 0,
|
|
19
19
|
children: d.children?.map((childRoute) => childRoute.routePath)
|
|
20
20
|
}
|
|
21
21
|
];
|
|
22
22
|
})
|
|
23
23
|
)
|
|
24
24
|
};
|
|
25
|
-
globalThis.TSS_ROUTES_MANIFEST =
|
|
25
|
+
globalThis.TSS_ROUTES_MANIFEST = routes;
|
|
26
26
|
}
|
|
27
27
|
};
|
|
28
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routes-manifest-plugin.js","sources":["../../../../src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts"],"sourcesContent":["import { rootRouteId } from '@tanstack/router-core'\n\nimport type { GeneratorPlugin } from '@tanstack/router-generator'\n\n/**\n * this plugin builds the routes manifest and stores it on globalThis\n * so that it can be accessed later (e.g. from a vite plugin)\n */\nexport function routesManifestPlugin(): GeneratorPlugin {\n return {\n name: 'routes-manifest-plugin',\n onRouteTreeChanged: ({ routeTree, rootRouteNode, routeNodes }) => {\n const
|
|
1
|
+
{"version":3,"file":"routes-manifest-plugin.js","sources":["../../../../src/start-router-plugin/generator-plugins/routes-manifest-plugin.ts"],"sourcesContent":["import { rootRouteId } from '@tanstack/router-core'\n\nimport type { GeneratorPlugin } from '@tanstack/router-generator'\n\n/**\n * this plugin builds the routes manifest and stores it on globalThis\n * so that it can be accessed later (e.g. from a vite plugin)\n */\nexport function routesManifestPlugin(): GeneratorPlugin {\n return {\n name: 'routes-manifest-plugin',\n onRouteTreeChanged: ({ routeTree, rootRouteNode, routeNodes }) => {\n const allChildren = routeTree.map((d) => d.routePath)\n const routes: Record<\n string,\n {\n filePath: string\n children: Array<string>\n }\n > = {\n [rootRouteId]: {\n filePath: rootRouteNode.fullPath,\n children: allChildren,\n },\n ...Object.fromEntries(\n routeNodes.map((d) => {\n const filePathId = d.routePath\n\n return [\n filePathId,\n {\n filePath: d.fullPath,\n children: d.children?.map((childRoute) => childRoute.routePath),\n },\n ]\n }),\n ),\n }\n\n globalThis.TSS_ROUTES_MANIFEST = routes\n },\n }\n}\n"],"names":[],"mappings":";AAQO,SAAS,uBAAwC;AACtD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,oBAAoB,CAAC,EAAE,WAAW,eAAe,iBAAiB;AAChE,YAAM,cAAc,UAAU,IAAI,CAAC,MAAM,EAAE,SAAS;AACpD,YAAM,SAMF;AAAA,QACF,CAAC,WAAW,GAAG;AAAA,UACb,UAAU,cAAc;AAAA,UACxB,UAAU;AAAA,QAAA;AAAA,QAEZ,GAAG,OAAO;AAAA,UACR,WAAW,IAAI,CAAC,MAAM;AACpB,kBAAM,aAAa,EAAE;AAErB,mBAAO;AAAA,cACL;AAAA,cACA;AAAA,gBACE,UAAU,EAAE;AAAA,gBACZ,UAAU,EAAE,UAAU,IAAI,CAAC,eAAe,WAAW,SAAS;AAAA,cAAA;AAAA,YAChE;AAAA,UAEJ,CAAC;AAAA,QAAA;AAAA,MACH;AAGF,iBAAW,sBAAsB;AAAA,IACnC;AAAA,EAAA;AAEJ;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.136.
|
|
3
|
+
"version": "1.136.9",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
"vitefu": "^1.1.1",
|
|
60
60
|
"xmlbuilder2": "^3.1.1",
|
|
61
61
|
"zod": "^3.24.2",
|
|
62
|
-
"@tanstack/router-
|
|
63
|
-
"@tanstack/router-
|
|
64
|
-
"@tanstack/router-plugin": "1.136.
|
|
62
|
+
"@tanstack/router-core": "1.136.9",
|
|
63
|
+
"@tanstack/router-generator": "1.136.9",
|
|
64
|
+
"@tanstack/router-plugin": "1.136.9",
|
|
65
65
|
"@tanstack/router-utils": "1.133.19",
|
|
66
66
|
"@tanstack/server-functions-plugin": "1.134.5",
|
|
67
|
-
"@tanstack/start-client-core": "1.136.
|
|
68
|
-
"@tanstack/start-server-core": "1.136.
|
|
67
|
+
"@tanstack/start-client-core": "1.136.9",
|
|
68
|
+
"@tanstack/start-server-core": "1.136.9"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/babel__code-frame": "^7.0.6",
|
package/src/global.d.ts
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
|
-
import type { Manifest } from '@tanstack/router-core'
|
|
2
|
-
|
|
3
1
|
/* eslint-disable no-var */
|
|
4
2
|
declare global {
|
|
5
|
-
var TSS_ROUTES_MANIFEST:
|
|
3
|
+
var TSS_ROUTES_MANIFEST: Record<
|
|
4
|
+
string,
|
|
5
|
+
{
|
|
6
|
+
filePath: string
|
|
7
|
+
children?: Array<string>
|
|
8
|
+
}
|
|
9
|
+
>
|
|
6
10
|
var TSS_PRERENDABLE_PATHS: Array<{ path: string }> | undefined
|
|
7
11
|
}
|
|
8
12
|
export {}
|
|
@@ -6,7 +6,7 @@ import { resolveViteId } from '../utils'
|
|
|
6
6
|
import { ENTRY_POINTS } from '../constants'
|
|
7
7
|
import type { GetConfigFn } from '../plugin'
|
|
8
8
|
import type { PluginOption, Rollup } from 'vite'
|
|
9
|
-
import type { RouterManagedTag } from '@tanstack/router-core'
|
|
9
|
+
import type { Manifest, RouterManagedTag } from '@tanstack/router-core'
|
|
10
10
|
|
|
11
11
|
const getCSSRecursively = (
|
|
12
12
|
chunk: Rollup.OutputChunk,
|
|
@@ -97,7 +97,7 @@ export function startManifestPlugin(opts: {
|
|
|
97
97
|
|
|
98
98
|
// This the manifest pulled from the generated route tree and later used by the Router.
|
|
99
99
|
// i.e what's located in `src/routeTree.gen.ts`
|
|
100
|
-
const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST
|
|
100
|
+
const routeTreeRoutes = globalThis.TSS_ROUTES_MANIFEST
|
|
101
101
|
|
|
102
102
|
const cssPerChunkCache = new Map<
|
|
103
103
|
Rollup.OutputChunk,
|
|
@@ -157,6 +157,7 @@ export function startManifestPlugin(opts: {
|
|
|
157
157
|
}
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
const manifest: Manifest = { routes: {} }
|
|
160
161
|
// Add preloads to the routes from the vite manifest
|
|
161
162
|
Object.entries(routeTreeRoutes).forEach(([routeId, v]) => {
|
|
162
163
|
if (!v.filePath) {
|
|
@@ -168,8 +169,11 @@ export function startManifestPlugin(opts: {
|
|
|
168
169
|
// Map the relevant imports to their route paths,
|
|
169
170
|
// so that it can be imported in the browser.
|
|
170
171
|
const preloads = chunk.imports.map((d) => {
|
|
171
|
-
const
|
|
172
|
-
|
|
172
|
+
const preloadPath = joinURL(
|
|
173
|
+
resolvedStartConfig.viteAppBase,
|
|
174
|
+
d,
|
|
175
|
+
)
|
|
176
|
+
return preloadPath
|
|
173
177
|
})
|
|
174
178
|
|
|
175
179
|
// Since this is the most important JS entry for the route,
|
|
@@ -179,26 +183,30 @@ export function startManifestPlugin(opts: {
|
|
|
179
183
|
joinURL(resolvedStartConfig.viteAppBase, chunk.fileName),
|
|
180
184
|
)
|
|
181
185
|
|
|
182
|
-
const
|
|
186
|
+
const assets = getCSSRecursively(
|
|
183
187
|
chunk,
|
|
184
188
|
chunksByFileName,
|
|
185
189
|
resolvedStartConfig.viteAppBase,
|
|
186
190
|
cssPerChunkCache,
|
|
187
191
|
)
|
|
188
192
|
|
|
189
|
-
|
|
193
|
+
manifest.routes[routeId] = {
|
|
190
194
|
...v,
|
|
191
|
-
assets
|
|
192
|
-
preloads
|
|
195
|
+
assets,
|
|
196
|
+
preloads,
|
|
193
197
|
}
|
|
194
198
|
})
|
|
199
|
+
} else {
|
|
200
|
+
manifest.routes[routeId] = v
|
|
195
201
|
}
|
|
196
202
|
})
|
|
197
203
|
|
|
198
204
|
if (!entryFile) {
|
|
199
205
|
throw new Error('No entry file found')
|
|
200
206
|
}
|
|
201
|
-
|
|
207
|
+
|
|
208
|
+
manifest.routes[rootRouteId] = manifest.routes[rootRouteId] || {}
|
|
209
|
+
manifest.routes[rootRouteId].preloads = [
|
|
202
210
|
joinURL(resolvedStartConfig.viteAppBase, entryFile.fileName),
|
|
203
211
|
...entryFile.imports.map((d) =>
|
|
204
212
|
joinURL(resolvedStartConfig.viteAppBase, d),
|
|
@@ -214,8 +222,8 @@ export function startManifestPlugin(opts: {
|
|
|
214
222
|
cssPerChunkCache,
|
|
215
223
|
)
|
|
216
224
|
|
|
217
|
-
|
|
218
|
-
...(
|
|
225
|
+
manifest.routes[rootRouteId].assets = [
|
|
226
|
+
...(manifest.routes[rootRouteId].assets || []),
|
|
219
227
|
...entryCssAssetsList,
|
|
220
228
|
]
|
|
221
229
|
|
|
@@ -236,17 +244,17 @@ export function startManifestPlugin(opts: {
|
|
|
236
244
|
|
|
237
245
|
if (route.children) {
|
|
238
246
|
route.children.forEach((child) => {
|
|
239
|
-
const childRoute =
|
|
247
|
+
const childRoute = manifest.routes[child]!
|
|
240
248
|
recurseRoute(childRoute, { ...seenPreloads })
|
|
241
249
|
})
|
|
242
250
|
}
|
|
243
251
|
}
|
|
244
252
|
|
|
245
|
-
recurseRoute(
|
|
253
|
+
recurseRoute(manifest.routes[rootRouteId])
|
|
246
254
|
|
|
247
255
|
// Filter out routes that have neither assets nor preloads
|
|
248
|
-
Object.keys(
|
|
249
|
-
const route =
|
|
256
|
+
Object.keys(manifest.routes).forEach((routeId) => {
|
|
257
|
+
const route = manifest.routes[routeId]!
|
|
250
258
|
const hasAssets = route.assets && route.assets.length > 0
|
|
251
259
|
const hasPreloads = route.preloads && route.preloads.length > 0
|
|
252
260
|
if (!hasAssets && !hasPreloads) {
|
|
@@ -255,7 +263,7 @@ export function startManifestPlugin(opts: {
|
|
|
255
263
|
})
|
|
256
264
|
|
|
257
265
|
const startManifest = {
|
|
258
|
-
routes:
|
|
266
|
+
routes: manifest.routes,
|
|
259
267
|
clientEntry: joinURL(
|
|
260
268
|
resolvedStartConfig.viteAppBase,
|
|
261
269
|
entryFile.fileName,
|
|
@@ -10,10 +10,17 @@ export function routesManifestPlugin(): GeneratorPlugin {
|
|
|
10
10
|
return {
|
|
11
11
|
name: 'routes-manifest-plugin',
|
|
12
12
|
onRouteTreeChanged: ({ routeTree, rootRouteNode, routeNodes }) => {
|
|
13
|
-
const
|
|
13
|
+
const allChildren = routeTree.map((d) => d.routePath)
|
|
14
|
+
const routes: Record<
|
|
15
|
+
string,
|
|
16
|
+
{
|
|
17
|
+
filePath: string
|
|
18
|
+
children: Array<string>
|
|
19
|
+
}
|
|
20
|
+
> = {
|
|
14
21
|
[rootRouteId]: {
|
|
15
22
|
filePath: rootRouteNode.fullPath,
|
|
16
|
-
children:
|
|
23
|
+
children: allChildren,
|
|
17
24
|
},
|
|
18
25
|
...Object.fromEntries(
|
|
19
26
|
routeNodes.map((d) => {
|
|
@@ -23,7 +30,6 @@ export function routesManifestPlugin(): GeneratorPlugin {
|
|
|
23
30
|
filePathId,
|
|
24
31
|
{
|
|
25
32
|
filePath: d.fullPath,
|
|
26
|
-
parent: d.parent?.routePath ? d.parent.routePath : undefined,
|
|
27
33
|
children: d.children?.map((childRoute) => childRoute.routePath),
|
|
28
34
|
},
|
|
29
35
|
]
|
|
@@ -31,7 +37,7 @@ export function routesManifestPlugin(): GeneratorPlugin {
|
|
|
31
37
|
),
|
|
32
38
|
}
|
|
33
39
|
|
|
34
|
-
globalThis.TSS_ROUTES_MANIFEST =
|
|
40
|
+
globalThis.TSS_ROUTES_MANIFEST = routes
|
|
35
41
|
},
|
|
36
42
|
}
|
|
37
43
|
}
|