@tanstack/start-plugin-core 1.121.0-alpha.15 → 1.121.0-alpha.16
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.
|
@@ -5,6 +5,26 @@ const path = require("node:path");
|
|
|
5
5
|
const ufo = require("ufo");
|
|
6
6
|
const routerCore = require("@tanstack/router-core");
|
|
7
7
|
const utils = require("./utils.cjs");
|
|
8
|
+
const getCSSRecursively = (file, filesByRouteFilePath) => {
|
|
9
|
+
const result = [];
|
|
10
|
+
for (const cssFile of file.css ?? []) {
|
|
11
|
+
result.push({
|
|
12
|
+
tag: "link",
|
|
13
|
+
attrs: {
|
|
14
|
+
rel: "stylesheet",
|
|
15
|
+
href: ufo.joinURL("/", cssFile),
|
|
16
|
+
type: "text/css"
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
for (const imp of file.imports ?? []) {
|
|
21
|
+
const importInfo = filesByRouteFilePath[imp];
|
|
22
|
+
if (importInfo) {
|
|
23
|
+
result.push(...getCSSRecursively(importInfo, filesByRouteFilePath));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
8
28
|
function startManifestPlugin(opts) {
|
|
9
29
|
let config;
|
|
10
30
|
const moduleId = "tanstack-start-router-manifest:v";
|
|
@@ -90,17 +110,7 @@ function startManifestPlugin(opts) {
|
|
|
90
110
|
if (file.file) {
|
|
91
111
|
preloads.unshift(path.join("/", file.file));
|
|
92
112
|
}
|
|
93
|
-
const
|
|
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
|
-
);
|
|
113
|
+
const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath);
|
|
104
114
|
routes[k] = {
|
|
105
115
|
...v,
|
|
106
116
|
assets: [...v.assets || [], ...cssAssetsList],
|
|
@@ -115,16 +125,9 @@ function startManifestPlugin(opts) {
|
|
|
115
125
|
(d) => path.join("/", viteManifest[d].file)
|
|
116
126
|
)) || []
|
|
117
127
|
];
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
tag: "link",
|
|
122
|
-
attrs: {
|
|
123
|
-
rel: "stylesheet",
|
|
124
|
-
href: ufo.joinURL("/", cssFile),
|
|
125
|
-
type: "text/css"
|
|
126
|
-
}
|
|
127
|
-
})
|
|
128
|
+
const entryCssAssetsList = getCSSRecursively(
|
|
129
|
+
entryFile,
|
|
130
|
+
filesByRouteFilePath
|
|
128
131
|
);
|
|
129
132
|
routes[routerCore.rootRouteId].assets = [
|
|
130
133
|
...routes[routerCore.rootRouteId].assets || [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routesManifestPlugin.cjs","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n const routes = routerManifest.routes\n\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssFiles = file.css ?? []\n const cssAssetsList: Array<RouterManagedTag> = cssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', viteManifest[d]!.file),\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 entryCssFiles = entryFile.css ?? []\n const entryCssAssetsList: Array<RouterManagedTag> = entryCssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', entryFile.file),\n type: 'module',\n },\n },\n ]\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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["resolveViteId","readFileSync","joinURL","rootRouteId","_a"],"mappings":";;;;;;;AAcO,SAAS,oBACd,MACc;AACV,MAAA;AAEJ,QAAM,WAAW;AACX,QAAA,mBAAmBA,oBAAc,QAAQ;AAExC,SAAA;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IAET,eAAe,gBAAgB;AACpB,eAAA;AAAA,IACX;AAAA;AAAA;AAAA;AAAA,IAIA,UAAU,IAAI;AACZ,UAAI,OAAO,UAAU;AACZ,eAAA;AAAA,MAAA;AAET;AAAA,IACF;AAAA,IACA,KAAK,IAAI;;AACP,UAAI,OAAO,kBAAkB;AAC3B,YAAI,KAAK,YAAY,OAAO,aAAa,UAAU;AAG1C,iBAAA;AAAA,QAAA;AAIL,YAAA,OAAO,YAAY,SAAS;AACvB,iBAAA;AAAA,uBACM,QAAQ,IAAI,eAAe;AAAA;AAAA;AAAA,QAAA;AAK1C,cAAM,yBAAyB,KAAK;AAAA,UAClC,KAAK;AAAA,UACL;AAAA,QACF;AAEI,YAAA;AACA,YAAA;AACF,yBAAe,KAAK;AAAA,YAClBC,GAAA,aAAa,wBAAwB,OAAO;AAAA,UAC9C;AAAA,iBACO,KAAK;AACZ,kBAAQ,MAAM,GAAG;AACjB,gBAAM,IAAI;AAAA,YACR,0DAA0D,sBAAsB;AAAA,UAClF;AAAA,QAAA;AAGF,cAAM,gBAAgB,KAAK,QAAQ,KAAK,IAAI,kBAAkB;AAE1D,YAAA;AACA,YAAA;AACiB,6BAAAA,GAAAA,aAAa,eAAe,OAAO;AAAA,iBAC/C,KAAK;AACZ,kBAAQ,MAAM,GAAG;AACjB,gBAAM,IAAI;AAAA,YACR,+CAA+C,aAAa;AAAA,UAC9D;AAAA,QAAA;AAMF,cAAM,iBAAiB,KAAK;AAAA,YAC1B,sBAAiB;AAAA,YACf;AAAA,UACF,MAFA,mBAEI,OAAM;AAAA,QACZ;AAEA,cAAM,SAAS,eAAe;AAE1B,YAAA;AAEJ,cAAM,uBAAqC,OAAO;AAAA,UAChD,OAAO,QAAQ,YAAY,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM;AAC3C,gBAAI,EAAE,SAAS;AACD,0BAAA;AAAA,YAAA;AAGd,kBAAM,QAAQ,EAAE,MAAM,GAAG,EAAE,CAAC;AAErB,mBAAA,CAAC,OAAO,CAAC;AAAA,UAAA,GACf,CAAE,CAAA;AAAA,QACP;AAEA,cAAM,0BAA0B,KAAK;AAAA,UACnC,KAAK;AAAA,UACL,KAAK,IAAI;AAAA,QACX;AAGO,eAAA,QAAQ,MAAM,EAAE,QAAQ,CAAC,CAAC,GAAG,CAAC,MAAM;AACzC,gBAAM,OACJ,qBACE,KAAK,KAAK,yBAAyB,EAAE,QAAkB,CACzD;AAEF,cAAI,MAAM;AACR,kBAAM,YAAY,KAAK,WAAW,CAAI,GAAA;AAAA,cAAI,CAAC,MACzC,KAAK,KAAK,KAAK,aAAa,CAAC,EAAG,IAAI;AAAA,YACtC;AAEA,gBAAI,KAAK,MAAM;AACb,uBAAS,QAAQ,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AAAA,YAAA;AAGtC,kBAAA,WAAW,KAAK,OAAO,CAAC;AAC9B,kBAAM,gBAAyC,SAAS;AAAA,cACtD,CAAC,aAAa;AAAA,gBACZ,KAAK;AAAA,gBACL,OAAO;AAAA,kBACL,KAAK;AAAA,kBACL,MAAMC,IAAAA,QAAQ,KAAK,OAAO;AAAA,kBAC1B,MAAM;AAAA,gBAAA;AAAA,cAEV;AAAA,YACF;AAEA,mBAAO,CAAC,IAAI;AAAA,cACV,GAAG;AAAA,cACH,QAAQ,CAAC,GAAI,EAAE,UAAU,CAAC,GAAI,GAAG,aAAa;AAAA,cAC9C;AAAA,YACF;AAAA,UAAA;AAAA,QACF,CACD;AAED,YAAI,WAAW;AACN,iBAAAC,WAAAA,WAAW,EAAG,WAAW;AAAA,YAC9B,KAAK,KAAK,KAAK,UAAU,IAAI;AAAA,YAC7B,KAAI,eAAU,YAAV,mBAAmB;AAAA,cAAI,CAAC,MAC1B,KAAK,KAAK,KAAK,aAAa,CAAC,EAAG,IAAI;AAAA,kBACjC,CAAA;AAAA,UACP;AAIM,gBAAA,gBAAgB,UAAU,OAAO,CAAC;AACxC,gBAAM,qBAA8C,cAAc;AAAA,YAChE,CAAC,aAAa;AAAA,cACZ,KAAK;AAAA,cACL,OAAO;AAAA,gBACL,KAAK;AAAA,gBACL,MAAMD,IAAAA,QAAQ,KAAK,OAAO;AAAA,gBAC1B,MAAM;AAAA,cAAA;AAAA,YAEV;AAAA,UACF;AAEO,iBAAAC,WAAAA,WAAW,EAAG,SAAS;AAAA,YAC5B,GAAI,OAAOA,WAAAA,WAAW,EAAG,UAAU,CAAC;AAAA,YACpC,GAAG;AAAA,YACH;AAAA,cACE,KAAK;AAAA,cACL,OAAO;AAAA,gBACL,KAAKD,IAAA,QAAQ,KAAK,UAAU,IAAI;AAAA,gBAChC,MAAM;AAAA,cAAA;AAAA,YACR;AAAA,UAEJ;AAAA,QAAA;AAGF,cAAM,eAAe,CACnB,OAIA,eAAe,CAAA,MACZ;;AACH,gBAAM,YAAWE,MAAA,MAAM,aAAN,gBAAAA,IAAgB,OAAO,CAAC,YAAY;AAC/C,gBAAA,aAAa,OAAO,GAAG;AAClB,qBAAA;AAAA,YAAA;AAET,yBAAa,OAAO,IAAI;AACjB,mBAAA;AAAA,UAAA;AAGT,cAAI,MAAM,UAAU;AACZ,kBAAA,SAAS,QAAQ,CAAC,UAAU;AAC1B,oBAAA,aAAa,OAAO,KAAK;AAC/B,2BAAa,YAAY,EAAE,GAAG,cAAc;AAAA,YAAA,CAC7C;AAAA,UAAA;AAAA,QAEL;AAGa,qBAAA,OAAOD,WAAAA,WAAW,CAAC;AAEhC,cAAM,iBAAiB;AAAA,UACrB;AAAA,QACF;AAEA,eAAO,0CAA0C,KAAK,UAAU,cAAc,CAAC;AAAA,MAAA;AAEjF;AAAA,IAAA;AAAA,EAEJ;AACF;;"}
|
|
1
|
+
{"version":3,"file":"routesManifestPlugin.cjs","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nconst getCSSRecursively = (\n file: ViteManifestChunk,\n filesByRouteFilePath: ViteManifest,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of file.css ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const imp of file.imports ?? []) {\n const importInfo = filesByRouteFilePath[imp]\n if (importInfo) {\n result.push(...getCSSRecursively(importInfo, filesByRouteFilePath))\n }\n }\n\n return result\n}\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n const routes = routerManifest.routes\n\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath)\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', viteManifest[d]!.file),\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 filesByRouteFilePath,\n )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', entryFile.file),\n type: 'module',\n },\n },\n ]\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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["joinURL","resolveViteId","readFileSync","rootRouteId","_a"],"mappings":"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"}
|
|
@@ -3,6 +3,26 @@ import path from "node:path";
|
|
|
3
3
|
import { joinURL } from "ufo";
|
|
4
4
|
import { rootRouteId } from "@tanstack/router-core";
|
|
5
5
|
import { resolveViteId } from "./utils.js";
|
|
6
|
+
const getCSSRecursively = (file, filesByRouteFilePath) => {
|
|
7
|
+
const result = [];
|
|
8
|
+
for (const cssFile of file.css ?? []) {
|
|
9
|
+
result.push({
|
|
10
|
+
tag: "link",
|
|
11
|
+
attrs: {
|
|
12
|
+
rel: "stylesheet",
|
|
13
|
+
href: joinURL("/", cssFile),
|
|
14
|
+
type: "text/css"
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
for (const imp of file.imports ?? []) {
|
|
19
|
+
const importInfo = filesByRouteFilePath[imp];
|
|
20
|
+
if (importInfo) {
|
|
21
|
+
result.push(...getCSSRecursively(importInfo, filesByRouteFilePath));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return result;
|
|
25
|
+
};
|
|
6
26
|
function startManifestPlugin(opts) {
|
|
7
27
|
let config;
|
|
8
28
|
const moduleId = "tanstack-start-router-manifest:v";
|
|
@@ -88,17 +108,7 @@ function startManifestPlugin(opts) {
|
|
|
88
108
|
if (file.file) {
|
|
89
109
|
preloads.unshift(path.join("/", file.file));
|
|
90
110
|
}
|
|
91
|
-
const
|
|
92
|
-
const cssAssetsList = cssFiles.map(
|
|
93
|
-
(cssFile) => ({
|
|
94
|
-
tag: "link",
|
|
95
|
-
attrs: {
|
|
96
|
-
rel: "stylesheet",
|
|
97
|
-
href: joinURL("/", cssFile),
|
|
98
|
-
type: "text/css"
|
|
99
|
-
}
|
|
100
|
-
})
|
|
101
|
-
);
|
|
111
|
+
const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath);
|
|
102
112
|
routes[k] = {
|
|
103
113
|
...v,
|
|
104
114
|
assets: [...v.assets || [], ...cssAssetsList],
|
|
@@ -113,16 +123,9 @@ function startManifestPlugin(opts) {
|
|
|
113
123
|
(d) => path.join("/", viteManifest[d].file)
|
|
114
124
|
)) || []
|
|
115
125
|
];
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
tag: "link",
|
|
120
|
-
attrs: {
|
|
121
|
-
rel: "stylesheet",
|
|
122
|
-
href: joinURL("/", cssFile),
|
|
123
|
-
type: "text/css"
|
|
124
|
-
}
|
|
125
|
-
})
|
|
126
|
+
const entryCssAssetsList = getCSSRecursively(
|
|
127
|
+
entryFile,
|
|
128
|
+
filesByRouteFilePath
|
|
126
129
|
);
|
|
127
130
|
routes[rootRouteId].assets = [
|
|
128
131
|
...routes[rootRouteId].assets || [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"routesManifestPlugin.js","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n const routes = routerManifest.routes\n\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssFiles = file.css ?? []\n const cssAssetsList: Array<RouterManagedTag> = cssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', viteManifest[d]!.file),\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 entryCssFiles = entryFile.css ?? []\n const entryCssAssetsList: Array<RouterManagedTag> = entryCssFiles.map(\n (cssFile) => ({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n }),\n )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', entryFile.file),\n type: 'module',\n },\n },\n ]\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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"routesManifestPlugin.js","sources":["../../src/routesManifestPlugin.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport path from 'node:path'\nimport { joinURL } from 'ufo'\nimport { rootRouteId } from '@tanstack/router-core'\nimport { resolveViteId } from './utils'\nimport type {\n PluginOption,\n ResolvedConfig,\n Manifest as ViteManifest,\n ManifestChunk as ViteManifestChunk,\n} from 'vite'\nimport type { Manifest, RouterManagedTag } from '@tanstack/router-core'\nimport type { TanStackStartOutputConfig } from './plugin'\n\nconst getCSSRecursively = (\n file: ViteManifestChunk,\n filesByRouteFilePath: ViteManifest,\n) => {\n const result: Array<RouterManagedTag> = []\n\n // Get all css imports from the file\n for (const cssFile of file.css ?? []) {\n result.push({\n tag: 'link',\n attrs: {\n rel: 'stylesheet',\n href: joinURL('/', cssFile),\n type: 'text/css',\n },\n })\n }\n\n // Recursively get CSS from imports\n for (const imp of file.imports ?? []) {\n const importInfo = filesByRouteFilePath[imp]\n if (importInfo) {\n result.push(...getCSSRecursively(importInfo, filesByRouteFilePath))\n }\n }\n\n return result\n}\n\nexport function startManifestPlugin(\n opts: TanStackStartOutputConfig,\n): PluginOption {\n let config: ResolvedConfig\n\n const moduleId = 'tanstack-start-router-manifest:v'\n const resolvedModuleId = resolveViteId(moduleId)\n\n return {\n name: 'tsr-routes-manifest',\n enforce: 'pre',\n\n configResolved(resolvedConfig) {\n config = resolvedConfig\n },\n // configEnvironment(env, envConfig) {\n // config = envConfig.\n // },\n resolveId(id) {\n if (id === moduleId) {\n return resolvedModuleId\n }\n return\n },\n load(id) {\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 // If we're in development, return a dummy manifest\n\n if (config.command === 'serve') {\n return `export const tsrStartManifest = () => ({\n entry: \"$${process.env.TSS_CLIENT_BASE}/\",\n routes: {}\n })`\n }\n\n const clientViteManifestPath = path.resolve(\n opts.root,\n '.tanstack-start/build/client-dist/.vite/manifest.json',\n )\n\n let viteManifest: ViteManifest\n try {\n viteManifest = JSON.parse(\n readFileSync(clientViteManifestPath, 'utf-8'),\n )\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the production client vite manifest at '${clientViteManifestPath}'!`,\n )\n }\n\n const routeTreePath = path.resolve(opts.tsr.generatedRouteTree)\n\n let routeTreeContent: string\n try {\n routeTreeContent = readFileSync(routeTreePath, 'utf-8')\n } catch (err) {\n console.error(err)\n throw new Error(\n `Could not find the generated route tree at '${routeTreePath}'!`,\n )\n }\n\n // Extract the routesManifest JSON from the route tree file.\n // It's located between the /* ROUTE_MANIFEST_START and ROUTE_MANIFEST_END */ comment block.\n\n const routerManifest = JSON.parse(\n routeTreeContent.match(\n /\\/\\* ROUTE_MANIFEST_START([\\s\\S]*?)ROUTE_MANIFEST_END \\*\\//,\n )?.[1] || '{ routes: {} }',\n ) as Manifest\n\n const routes = routerManifest.routes\n\n let entryFile: ViteManifestChunk | undefined\n\n const filesByRouteFilePath: ViteManifest = Object.fromEntries(\n Object.entries(viteManifest).map(([k, v]) => {\n if (v.isEntry) {\n entryFile = v\n }\n\n const rPath = k.split('?')[0]\n\n return [rPath, v]\n }, {}),\n )\n\n const routesDirectoryFromRoot = path.relative(\n opts.root,\n opts.tsr.routesDirectory,\n )\n\n // Add preloads to the routes from the vite manifest\n Object.entries(routes).forEach(([k, v]) => {\n const file =\n filesByRouteFilePath[\n path.join(routesDirectoryFromRoot, v.filePath as string)\n ]\n\n if (file) {\n const preloads = (file.imports ?? []).map((d) =>\n path.join('/', viteManifest[d]!.file),\n )\n\n if (file.file) {\n preloads.unshift(path.join('/', file.file))\n }\n\n const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath)\n\n routes[k] = {\n ...v,\n assets: [...(v.assets || []), ...cssAssetsList],\n preloads,\n }\n }\n })\n\n if (entryFile) {\n routes[rootRouteId]!.preloads = [\n path.join('/', entryFile.file),\n ...(entryFile.imports?.map((d) =>\n path.join('/', viteManifest[d]!.file),\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 filesByRouteFilePath,\n )\n\n routes[rootRouteId]!.assets = [\n ...(routes[rootRouteId]!.assets || []),\n ...entryCssAssetsList,\n {\n tag: 'script',\n attrs: {\n src: joinURL('/', entryFile.file),\n type: 'module',\n },\n },\n ]\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 = routes[child]!\n recurseRoute(childRoute, { ...seenPreloads })\n })\n }\n }\n\n // @ts-expect-error\n recurseRoute(routes[rootRouteId])\n\n const routesManifest = {\n routes,\n }\n\n return `export const tsrStartManifest = () => (${JSON.stringify(routesManifest)})`\n }\n return\n },\n }\n}\n"],"names":["_a"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tanstack/start-plugin-core",
|
|
3
|
-
"version": "1.121.0-alpha.
|
|
3
|
+
"version": "1.121.0-alpha.16",
|
|
4
4
|
"description": "Modern and scalable routing for React applications",
|
|
5
5
|
"author": "Tanner Linsley",
|
|
6
6
|
"license": "MIT",
|
|
@@ -64,10 +64,10 @@
|
|
|
64
64
|
"xmlbuilder2": "^3.1.1",
|
|
65
65
|
"zod": "^3.24.2",
|
|
66
66
|
"@tanstack/router-generator": "^1.121.0-alpha.14",
|
|
67
|
-
"@tanstack/router-core": "^1.121.0-alpha.14",
|
|
68
|
-
"@tanstack/router-utils": "^1.121.0-alpha.2",
|
|
69
67
|
"@tanstack/router-plugin": "^1.121.0-alpha.14",
|
|
70
|
-
"@tanstack/
|
|
68
|
+
"@tanstack/router-core": "^1.121.0-alpha.14",
|
|
69
|
+
"@tanstack/server-functions-plugin": "^1.121.0-alpha.8",
|
|
70
|
+
"@tanstack/router-utils": "^1.121.0-alpha.2"
|
|
71
71
|
},
|
|
72
72
|
"devDependencies": {
|
|
73
73
|
"vite": "^6.0.0"
|
|
@@ -12,6 +12,35 @@ import type {
|
|
|
12
12
|
import type { Manifest, RouterManagedTag } from '@tanstack/router-core'
|
|
13
13
|
import type { TanStackStartOutputConfig } from './plugin'
|
|
14
14
|
|
|
15
|
+
const getCSSRecursively = (
|
|
16
|
+
file: ViteManifestChunk,
|
|
17
|
+
filesByRouteFilePath: ViteManifest,
|
|
18
|
+
) => {
|
|
19
|
+
const result: Array<RouterManagedTag> = []
|
|
20
|
+
|
|
21
|
+
// Get all css imports from the file
|
|
22
|
+
for (const cssFile of file.css ?? []) {
|
|
23
|
+
result.push({
|
|
24
|
+
tag: 'link',
|
|
25
|
+
attrs: {
|
|
26
|
+
rel: 'stylesheet',
|
|
27
|
+
href: joinURL('/', cssFile),
|
|
28
|
+
type: 'text/css',
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Recursively get CSS from imports
|
|
34
|
+
for (const imp of file.imports ?? []) {
|
|
35
|
+
const importInfo = filesByRouteFilePath[imp]
|
|
36
|
+
if (importInfo) {
|
|
37
|
+
result.push(...getCSSRecursively(importInfo, filesByRouteFilePath))
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return result
|
|
42
|
+
}
|
|
43
|
+
|
|
15
44
|
export function startManifestPlugin(
|
|
16
45
|
opts: TanStackStartOutputConfig,
|
|
17
46
|
): PluginOption {
|
|
@@ -127,17 +156,7 @@ export function startManifestPlugin(
|
|
|
127
156
|
preloads.unshift(path.join('/', file.file))
|
|
128
157
|
}
|
|
129
158
|
|
|
130
|
-
const
|
|
131
|
-
const cssAssetsList: Array<RouterManagedTag> = cssFiles.map(
|
|
132
|
-
(cssFile) => ({
|
|
133
|
-
tag: 'link',
|
|
134
|
-
attrs: {
|
|
135
|
-
rel: 'stylesheet',
|
|
136
|
-
href: joinURL('/', cssFile),
|
|
137
|
-
type: 'text/css',
|
|
138
|
-
},
|
|
139
|
-
}),
|
|
140
|
-
)
|
|
159
|
+
const cssAssetsList = getCSSRecursively(file, filesByRouteFilePath)
|
|
141
160
|
|
|
142
161
|
routes[k] = {
|
|
143
162
|
...v,
|
|
@@ -157,16 +176,9 @@ export function startManifestPlugin(
|
|
|
157
176
|
|
|
158
177
|
// Gather all the CSS files from the entry file in
|
|
159
178
|
// the `css` key and add them to the root route
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
tag: 'link',
|
|
164
|
-
attrs: {
|
|
165
|
-
rel: 'stylesheet',
|
|
166
|
-
href: joinURL('/', cssFile),
|
|
167
|
-
type: 'text/css',
|
|
168
|
-
},
|
|
169
|
-
}),
|
|
179
|
+
const entryCssAssetsList = getCSSRecursively(
|
|
180
|
+
entryFile,
|
|
181
|
+
filesByRouteFilePath,
|
|
170
182
|
)
|
|
171
183
|
|
|
172
184
|
routes[rootRouteId]!.assets = [
|