@tanstack/router-cli 1.1.5 → 1.1.7

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.
@@ -19,7 +19,10 @@ const configSchema = zod.z.object({
19
19
  routeFileIgnorePrefix: zod.z.string().optional(),
20
20
  routesDirectory: zod.z.string(),
21
21
  generatedRouteTree: zod.z.string(),
22
- quoteStyle: zod.z.enum(['single', 'double']).optional().default('single')
22
+ quoteStyle: zod.z.enum(['single', 'double']).optional().default('single'),
23
+ future: zod.z.object({
24
+ unstable_codeSplitting: zod.z.boolean().optional()
25
+ }).optional()
23
26
  });
24
27
  const configFilePathJson = path.resolve(process.cwd(), 'tsr.config.json');
25
28
  async function getConfig() {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport { z } from 'zod'\n\nconst configSchema = z.object({\n routeFilePrefix: z.string().optional(),\n routeFileIgnorePrefix: z.string().optional(),\n routesDirectory: z.string(),\n generatedRouteTree: z.string(),\n quoteStyle: z.enum(['single', 'double']).optional().default('single'),\n})\n\nexport type Config = z.infer<typeof configSchema>\n\nconst configFilePathJson = path.resolve(process.cwd(), 'tsr.config.json')\n\nexport async function getConfig(): Promise<Config> {\n const config = (await fs.readJson(configFilePathJson)) as unknown as Config\n\n return { routeFileIgnorePrefix: '-', ...configSchema.parse(config) }\n}\n"],"names":["configSchema","z","object","routeFilePrefix","string","optional","routeFileIgnorePrefix","routesDirectory","generatedRouteTree","quoteStyle","enum","default","configFilePathJson","path","resolve","process","cwd","getConfig","config","fs","readJson","parse"],"mappings":";;;;;;;;;;;;;;;;AAIA,MAAMA,YAAY,GAAGC,KAAC,CAACC,MAAM,CAAC;EAC5BC,eAAe,EAAEF,KAAC,CAACG,MAAM,EAAE,CAACC,QAAQ,EAAE;EACtCC,qBAAqB,EAAEL,KAAC,CAACG,MAAM,EAAE,CAACC,QAAQ,EAAE;AAC5CE,EAAAA,eAAe,EAAEN,KAAC,CAACG,MAAM,EAAE;AAC3BI,EAAAA,kBAAkB,EAAEP,KAAC,CAACG,MAAM,EAAE;AAC9BK,EAAAA,UAAU,EAAER,KAAC,CAACS,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAACL,QAAQ,EAAE,CAACM,OAAO,CAAC,QAAQ,CAAA;AACtE,CAAC,CAAC,CAAA;AAIF,MAAMC,kBAAkB,GAAGC,IAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAA;AAElE,eAAeC,SAASA,GAAoB;EACjD,MAAMC,MAAM,GAAI,MAAMC,EAAE,CAACC,QAAQ,CAACR,kBAAkB,CAAuB,CAAA;EAE3E,OAAO;AAAEN,IAAAA,qBAAqB,EAAE,GAAG;AAAE,IAAA,GAAGN,YAAY,CAACqB,KAAK,CAACH,MAAM,CAAA;GAAG,CAAA;AACtE;;;;"}
1
+ {"version":3,"file":"config.js","sources":["../../src/config.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport { z } from 'zod'\n\nconst configSchema = z.object({\n routeFilePrefix: z.string().optional(),\n routeFileIgnorePrefix: z.string().optional(),\n routesDirectory: z.string(),\n generatedRouteTree: z.string(),\n quoteStyle: z.enum(['single', 'double']).optional().default('single'),\n future: z\n .object({\n unstable_codeSplitting: z.boolean().optional(),\n })\n .optional(),\n})\n\nexport type Config = z.infer<typeof configSchema>\n\nconst configFilePathJson = path.resolve(process.cwd(), 'tsr.config.json')\n\nexport async function getConfig(): Promise<Config> {\n const config = (await fs.readJson(configFilePathJson)) as unknown as Config\n\n return { routeFileIgnorePrefix: '-', ...configSchema.parse(config) }\n}\n"],"names":["configSchema","z","object","routeFilePrefix","string","optional","routeFileIgnorePrefix","routesDirectory","generatedRouteTree","quoteStyle","enum","default","future","unstable_codeSplitting","boolean","configFilePathJson","path","resolve","process","cwd","getConfig","config","fs","readJson","parse"],"mappings":";;;;;;;;;;;;;;;;AAIA,MAAMA,YAAY,GAAGC,KAAC,CAACC,MAAM,CAAC;EAC5BC,eAAe,EAAEF,KAAC,CAACG,MAAM,EAAE,CAACC,QAAQ,EAAE;EACtCC,qBAAqB,EAAEL,KAAC,CAACG,MAAM,EAAE,CAACC,QAAQ,EAAE;AAC5CE,EAAAA,eAAe,EAAEN,KAAC,CAACG,MAAM,EAAE;AAC3BI,EAAAA,kBAAkB,EAAEP,KAAC,CAACG,MAAM,EAAE;AAC9BK,EAAAA,UAAU,EAAER,KAAC,CAACS,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAACL,QAAQ,EAAE,CAACM,OAAO,CAAC,QAAQ,CAAC;AACrEC,EAAAA,MAAM,EAAEX,KAAC,CACNC,MAAM,CAAC;IACNW,sBAAsB,EAAEZ,KAAC,CAACa,OAAO,EAAE,CAACT,QAAQ,EAAC;GAC9C,CAAC,CACDA,QAAQ,EAAC;AACd,CAAC,CAAC,CAAA;AAIF,MAAMU,kBAAkB,GAAGC,IAAI,CAACC,OAAO,CAACC,OAAO,CAACC,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAA;AAElE,eAAeC,SAASA,GAAoB;EACjD,MAAMC,MAAM,GAAI,MAAMC,EAAE,CAACC,QAAQ,CAACR,kBAAkB,CAAuB,CAAA;EAE3E,OAAO;AAAET,IAAAA,qBAAqB,EAAE,GAAG;AAAE,IAAA,GAAGN,YAAY,CAACwB,KAAK,CAACH,MAAM,CAAA;GAAG,CAAA;AACtE;;;;"}
@@ -113,18 +113,19 @@ async function generator(config) {
113
113
  let routeNodes = await getRouteNodes(config);
114
114
  routeNodes = multiSortBy(routeNodes, [d => d.routePath === '/' ? -1 : 1, d => d.routePath?.split('/').length, d => d.routePath?.endsWith('/') ? -1 : 1, d => d.routePath]).filter(d => d.routePath !== `/${routePathIdPrefix + rootPathId}`);
115
115
  const routeTree = [];
116
+ const routePiecesByPath = {};
116
117
 
117
118
  // Loop over the flat list of routeNodes and
118
119
  // build up a tree based on the routeNodes' routePath
119
- routeNodes.forEach(node => {
120
- // routeNodes.forEach((existingNode) => {
121
- // if (
122
- // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)
123
- // // node.routePath.length > existingNode.routePath!.length
124
- // ) {
125
- // node.parent = existingNode
126
- // }
127
- // })
120
+ routeNodes = routeNodes.filter(node => {
121
+ if (config.future?.unstable_codeSplitting) {
122
+ node.isRoute = node.routePath?.endsWith('/route');
123
+ node.isComponent = node.routePath?.endsWith('/component');
124
+ node.isLoader = node.routePath?.endsWith('/loader');
125
+ if (node.isComponent || node.isLoader || node.isRoute) {
126
+ node.routePath = node.routePath?.replace(/\/(component|loader|route)$/, '');
127
+ }
128
+ }
128
129
  const parentRoute = hasParentRoute(routeNodes, node.routePath);
129
130
  if (parentRoute) node.parent = parentRoute;
130
131
  node.path = node.parent ? node.routePath?.replace(node.parent.routePath, '') || '/' : node.routePath;
@@ -134,12 +135,20 @@ async function generator(config) {
134
135
  node.isNonPath = first.startsWith('_');
135
136
  node.isNonLayout = first.endsWith('_');
136
137
  node.cleanedPath = removeUnderscores(node.path) ?? '';
138
+ if (config.future?.unstable_codeSplitting) {
139
+ if (node.isLoader || node.isComponent) {
140
+ routePiecesByPath[node.routePath] = routePiecesByPath[node.routePath] || {};
141
+ routePiecesByPath[node.routePath][node.isLoader ? 'loader' : 'component'] = node;
142
+ return false;
143
+ }
144
+ }
137
145
  if (node.parent) {
138
146
  node.parent.children = node.parent.children ?? [];
139
147
  node.parent.children.push(node);
140
148
  } else {
141
149
  routeTree.push(node);
142
150
  }
151
+ return true;
143
152
  });
144
153
  async function buildRouteConfig(nodes, depth = 1) {
145
154
  const children = nodes.map(async node => {
@@ -171,39 +180,28 @@ async function generator(config) {
171
180
  return (await Promise.all(children)).filter(Boolean).join(`,`);
172
181
  }
173
182
  const routeConfigChildrenText = await buildRouteConfig(routeTree);
174
- const routeImports = [`import { Route as rootRoute } from './${sanitize(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, routePathIdPrefix + rootPathId)))}'`, ...multiSortBy(routeNodes, [d => d.routePath?.includes(`/${routePathIdPrefix + rootPathId}`) ? -1 : 1, d => d.routePath?.split('/').length, d => d.routePath?.endsWith("index'") ? -1 : 1, d => d]).map(node => {
175
- return `import { Route as ${node.variableName}Route } from './${sanitize(removeExt(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, node.filePath))))}'`;
176
- })].join('\n');
183
+ const sortedRouteNodes = multiSortBy(routeNodes, [d => d.routePath?.includes(`/${routePathIdPrefix + rootPathId}`) ? -1 : 1, d => d.routePath?.split('/').length, d => d.routePath?.endsWith("index'") ? -1 : 1, d => d]);
184
+ const routeImports = [`import { lazyFn, lazyRouteComponent } from '@tanstack/react-router'`, '\n', `import { Route as rootRoute } from './${sanitize(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, routePathIdPrefix + rootPathId)))}'`, ...sortedRouteNodes.map(node => {
185
+ return `import { Route as ${node.variableName}Import } from './${sanitize(removeExt(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, node.filePath))))}'`;
186
+ }), '\n', sortedRouteNodes.map(node => {
187
+ const loaderNode = routePiecesByPath[node.routePath]?.loader;
188
+ const componentNode = routePiecesByPath[node.routePath]?.component;
189
+ return [`const ${node.variableName}Route = ${node.variableName}Import.update({
190
+ ${[node.isNonPath ? `id: '${node.path}'` : `path: '${node.cleanedPath}'`, `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`].filter(Boolean).join(',')}
191
+ } as any)`, loaderNode ? `.updateLoader({ loader: lazyFn(() => import('./${sanitize(removeExt(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, loaderNode.filePath))))}'), 'loader') })` : '', componentNode ? `.update({ component: lazyRouteComponent(() => import('./${sanitize(removeExt(path.relative(path.dirname(config.generatedRouteTree), path.resolve(config.routesDirectory, componentNode.filePath))))}'), 'component') })` : ''].join('');
192
+ }).join('\n\n')].join('\n');
177
193
  const routeTypes = `declare module '@tanstack/react-router' {
178
194
  interface FileRoutesByPath {
179
195
  ${routeNodes.map(routeNode => {
180
196
  return `'${routeNode.routePath}': {
197
+ preLoaderRoute: typeof ${routeNode.variableName}Import
181
198
  parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route
182
199
  }`;
183
200
  }).join('\n')}
184
201
  }
185
202
  }`;
186
- const routeOptions = routeNodes.map(routeNode => {
187
- return `Object.assign(${routeNode.variableName ?? 'root'}Route.options, {
188
- ${[routeNode.isNonPath ? `id: '${routeNode.path}'` : `path: '${routeNode.cleanedPath}'`, `getParentRoute: () => ${routeNode.parent?.variableName ?? 'root'}Route`
189
- // `\n// ${JSON.stringify(
190
- // {
191
- // ...routeNode,
192
- // parent: undefined,
193
- // children: undefined,
194
- // fullPath: undefined,
195
- // variableName: undefined,
196
- // },
197
- // null,
198
- // 2,
199
- // )
200
- // .split('\n')
201
- // .join('\n// ')}`,
202
- ].filter(Boolean).join(',')}
203
- })`;
204
- }).join('\n\n');
205
203
  const routeConfig = `export const routeTree = rootRoute.addChildren([${routeConfigChildrenText}])`;
206
- const routeConfigFileContent = await prettier__namespace.format([routeImports, routeTypes, routeOptions, routeConfig].join('\n\n'), {
204
+ const routeConfigFileContent = await prettier__namespace.format([routeImports, routeTypes, routeConfig].join('\n\n'), {
207
205
  semi: false,
208
206
  parser: 'typescript'
209
207
  });
@@ -264,18 +262,18 @@ function removeUnderscores(s) {
264
262
  function replaceBackslash(s) {
265
263
  return s?.replace(/\\/gi, '/');
266
264
  }
267
- function hasParentRoute(routes, routeToCheck) {
268
- if (!routeToCheck || routeToCheck === '/') {
265
+ function hasParentRoute(routes, routePathToCheck) {
266
+ if (!routePathToCheck || routePathToCheck === '/') {
269
267
  return null;
270
268
  }
271
269
  const sortedNodes = multiSortBy(routes, [d => d.routePath.length * -1, d => d.variableName]).filter(d => d.routePath !== `/${rootPathId}`);
272
270
  for (const route of sortedNodes) {
273
271
  if (route.routePath === '/') continue;
274
- if (routeToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routeToCheck) {
272
+ if (routePathToCheck.startsWith(`${route.routePath}/`) && route.routePath !== routePathToCheck) {
275
273
  return route;
276
274
  }
277
275
  }
278
- const segments = routeToCheck.split('/');
276
+ const segments = routePathToCheck.split('/');
279
277
  segments.pop(); // Remove the last segment
280
278
  const parentRoute = segments.join('/');
281
279
  return hasParentRoute(routes, parentRoute);
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport * as prettier from 'prettier'\nimport { Config } from './config'\nimport { cleanPath, trimPathLeft } from '@tanstack/react-router'\n\nlet latestTask = 0\nexport const rootPathId = '__root'\nexport const fileRouteRegex = /new\\s+FileRoute\\(([^)]*)\\)/g\n\nexport type RouteNode = {\n filePath: string\n fullPath: string\n variableName: string\n routePath?: string\n cleanedPath?: string\n path?: string\n isNonPath?: boolean\n isNonLayout?: boolean\n isRoot?: boolean\n children?: RouteNode[]\n parent?: RouteNode\n}\n\nasync function getRouteNodes(config: Config) {\n const { routeFilePrefix, routeFileIgnorePrefix } = config\n\n let routeNodes: RouteNode[] = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fs.readdir(fullDir)\n\n dirList = dirList.filter((d) => {\n if (\n d.startsWith('.') ||\n (routeFileIgnorePrefix && d.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.startsWith(routeFilePrefix)\n }\n\n return true\n })\n\n await Promise.all(\n dirList.map(async (fileName) => {\n const fullPath = path.join(fullDir, fileName)\n const relativePath = path.join(dir, fileName)\n const stat = await fs.stat(fullPath)\n\n if (stat.isDirectory()) {\n await recurse(relativePath)\n } else {\n const filePath = path.join(dir, fileName)\n const filePathNoExt = removeExt(filePath)\n let routePath =\n replaceBackslash(\n cleanPath(`/${filePathNoExt.split('.').join('/')}`),\n ) ?? ''\n const variableName = fileToVariable(routePath)\n\n // Remove the index from the route path and\n // if the route path is empty, use `/'\n if (routePath === 'index') {\n routePath = '/'\n } else if (routePath.endsWith('/index')) {\n routePath = routePath.replace(/\\/index$/, '/')\n }\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n return routeNodes\n}\n\nlet first = false\nlet skipMessage = false\n\nexport async function generator(config: Config) {\n console.log()\n\n if (!first) {\n console.log('🔄 Generating routes...')\n first = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n console.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n const routePathIdPrefix = config.routeFilePrefix ?? ''\n\n let routeNodes = await getRouteNodes(config)\n\n routeNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => d.routePath !== `/${routePathIdPrefix + rootPathId}`)\n\n const routeTree: RouteNode[] = []\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n routeNodes.forEach((node) => {\n // routeNodes.forEach((existingNode) => {\n // if (\n // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)\n // // node.routePath.length > existingNode.routePath!.length\n // ) {\n // node.parent = existingNode\n // }\n // })\n const parentRoute = hasParentRoute(routeNodes, node.routePath)\n if (parentRoute) node.parent = parentRoute\n\n node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath!, '') || '/'\n : node.routePath\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath?.split('/') ?? []\n let first = split[0] ?? trimmedPath ?? ''\n\n node.isNonPath = first.startsWith('_')\n node.isNonLayout = first.endsWith('_')\n\n node.cleanedPath = removeUnderscores(node.path) ?? ''\n\n if (node.parent) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n } else {\n routeTree.push(node)\n }\n })\n\n async function buildRouteConfig(\n nodes: RouteNode[],\n depth = 1,\n ): Promise<string> {\n const children = nodes.map(async (node) => {\n const routeCode = await fs.readFile(node.fullPath, 'utf-8')\n\n // Ensure the boilerplate for the route exists\n if (node.isRoot) {\n return\n }\n\n // Ensure that new FileRoute(anything?) is replaced with FileRoute(${node.routePath})\n // routePath can contain $ characters, which have special meaning when used in replace\n // so we have to escape it by turning all $ into $$. But since we do it through a replace call\n // we have to double escape it into $$$$. For more information, see\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement\n const escapedRoutePath = node.routePath?.replaceAll('$', '$$$$') ?? ''\n const quote = config.quoteStyle === 'single' ? `'` : `\"`\n const replaced = routeCode.replace(\n fileRouteRegex,\n `new FileRoute(${quote}${escapedRoutePath}${quote})`,\n )\n\n if (replaced !== routeCode) {\n await fs.writeFile(node.fullPath, replaced)\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = await buildRouteConfig(node.children, depth + 1)\n return `${route}.addChildren([${spaces(depth * 4)}${childConfigs}])`\n }\n\n return route\n })\n\n return (await Promise.all(children)).filter(Boolean).join(`,`)\n }\n\n const routeConfigChildrenText = await buildRouteConfig(routeTree)\n\n const routeImports = [\n `import { Route as rootRoute } from './${sanitize(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, routePathIdPrefix + rootPathId),\n ),\n )}'`,\n ...multiSortBy(routeNodes, [\n (d) =>\n d.routePath?.includes(`/${routePathIdPrefix + rootPathId}`) ? -1 : 1,\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(\"index'\") ? -1 : 1),\n (d) => d,\n ]).map((node) => {\n return `import { Route as ${node.variableName}Route } from './${sanitize(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n ),\n )}'`\n }),\n ].join('\\n')\n\n const routeTypes = `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n return `'${routeNode.routePath}': {\n parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route\n }`\n })\n .join('\\n')}\n }\n}`\n\n const routeOptions = routeNodes\n .map((routeNode) => {\n return `Object.assign(${routeNode.variableName ?? 'root'}Route.options, {\n ${[\n routeNode.isNonPath\n ? `id: '${routeNode.path}'`\n : `path: '${routeNode.cleanedPath}'`,\n `getParentRoute: () => ${\n routeNode.parent?.variableName ?? 'root'\n }Route`,\n // `\\n// ${JSON.stringify(\n // {\n // ...routeNode,\n // parent: undefined,\n // children: undefined,\n // fullPath: undefined,\n // variableName: undefined,\n // },\n // null,\n // 2,\n // )\n // .split('\\n')\n // .join('\\n// ')}`,\n ]\n .filter(Boolean)\n .join(',')}\n })`\n })\n .join('\\n\\n')\n\n const routeConfig = `export const routeTree = rootRoute.addChildren([${routeConfigChildrenText}])`\n\n const routeConfigFileContent = await prettier.format(\n [routeImports, routeTypes, routeOptions, routeConfig].join('\\n\\n'),\n {\n semi: false,\n parser: 'typescript',\n },\n )\n\n const routeTreeContent = await fs\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err: any) => {\n if (err.code === 'ENOENT') {\n return undefined\n }\n throw err\n })\n\n if (!checkLatest()) return\n\n if (routeTreeContent !== routeConfigFileContent) {\n await fs.ensureDir(path.dirname(path.resolve(config.generatedRouteTree)))\n if (!checkLatest()) return\n await fs.writeFile(\n path.resolve(config.generatedRouteTree),\n routeConfigFileContent,\n )\n }\n\n console.log(\n `🌲 Processed ${routeNodes.length} routes in ${Date.now() - start}ms`,\n )\n}\n\nfunction fileToVariable(d: string): string {\n return (\n removeUnderscores(d)\n ?.replace(/\\$/g, '')\n ?.split(/[/-]/g)\n .map((d, i) => (i > 0 ? capitalize(d) : d))\n .join('')\n .replace(/([^a-zA-Z0-9]|[\\.])/gm, '') ?? ''\n )\n}\n\nexport function removeExt(d: string) {\n return d.substring(0, d.lastIndexOf('.')) || d\n}\n\nfunction spaces(d: number): string {\n return Array.from({ length: d })\n .map(() => ' ')\n .join('')\n}\n\nexport function multiSortBy<T>(\n arr: T[],\n accessors: ((item: T) => any)[] = [(d) => d],\n): T[] {\n return arr\n .map((d, i) => [d, i] as const)\n .sort(([a, ai], [b, bi]) => {\n for (const accessor of accessors) {\n const ao = accessor(a)\n const bo = accessor(b)\n\n if (typeof ao === 'undefined') {\n if (typeof bo === 'undefined') {\n continue\n }\n return 1\n }\n\n if (ao === bo) {\n continue\n }\n\n return ao > bo ? 1 : -1\n }\n\n return ai - bi\n })\n .map(([d]) => d)\n}\n\nfunction capitalize(s: string) {\n if (typeof s !== 'string') return ''\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction sanitize(s?: string) {\n return replaceBackslash(s?.replace(/\\\\index/gi, ''))\n}\n\nfunction removeUnderscores(s?: string) {\n return s?.replace(/(^_|_$)/, '').replace(/(\\/_|_\\/)/, '/')\n}\n\nfunction replaceBackslash(s?: string) {\n return s?.replace(/\\\\/gi, '/')\n}\n\nexport function hasParentRoute(\n routes: RouteNode[],\n routeToCheck: string | undefined,\n): RouteNode | null {\n if (!routeToCheck || routeToCheck === '/') {\n return null\n }\n\n const sortedNodes = multiSortBy(routes, [\n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue\n\n if (\n routeToCheck.startsWith(`${route.routePath}/`) &&\n route.routePath !== routeToCheck\n ) {\n return route\n }\n }\n const segments = routeToCheck.split('/')\n segments.pop() // Remove the last segment\n const parentRoute = segments.join('/')\n\n return hasParentRoute(routes, parentRoute)\n}\n"],"names":["latestTask","rootPathId","fileRouteRegex","getRouteNodes","config","routeFilePrefix","routeFileIgnorePrefix","routeNodes","recurse","dir","fullDir","path","resolve","routesDirectory","dirList","fs","readdir","filter","d","startsWith","Promise","all","map","fileName","fullPath","join","relativePath","stat","isDirectory","filePath","filePathNoExt","removeExt","routePath","replaceBackslash","cleanPath","split","variableName","fileToVariable","endsWith","replace","push","first","skipMessage","generator","console","log","taskId","checkLatest","start","Date","now","routePathIdPrefix","multiSortBy","length","routeTree","forEach","node","parentRoute","hasParentRoute","parent","trimmedPath","trimPathLeft","isNonPath","isNonLayout","cleanedPath","removeUnderscores","children","buildRouteConfig","nodes","depth","routeCode","readFile","isRoot","escapedRoutePath","replaceAll","quote","quoteStyle","replaced","writeFile","route","childConfigs","spaces","Boolean","routeConfigChildrenText","routeImports","sanitize","relative","dirname","generatedRouteTree","includes","routeTypes","routeNode","routeOptions","routeConfig","routeConfigFileContent","prettier","format","semi","parser","routeTreeContent","catch","err","code","undefined","ensureDir","i","capitalize","substring","lastIndexOf","Array","from","arr","accessors","sort","a","ai","b","bi","accessor","ao","bo","s","charAt","toUpperCase","slice","routes","routeToCheck","sortedNodes","segments","pop"],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sources":["../../src/generator.ts"],"sourcesContent":["import path from 'path'\nimport fs from 'fs-extra'\nimport * as prettier from 'prettier'\nimport { Config } from './config'\nimport { cleanPath, trimPathLeft } from '@tanstack/react-router'\n\nlet latestTask = 0\nexport const rootPathId = '__root'\nexport const fileRouteRegex = /new\\s+FileRoute\\(([^)]*)\\)/g\n\nexport type RouteNode = {\n filePath: string\n fullPath: string\n variableName: string\n routePath?: string\n cleanedPath?: string\n path?: string\n isNonPath?: boolean\n isNonLayout?: boolean\n isRoute?: boolean\n isLoader?: boolean\n isComponent?: boolean\n isRoot?: boolean\n children?: RouteNode[]\n parent?: RouteNode\n}\n\nasync function getRouteNodes(config: Config) {\n const { routeFilePrefix, routeFileIgnorePrefix } = config\n\n let routeNodes: RouteNode[] = []\n\n async function recurse(dir: string) {\n const fullDir = path.resolve(config.routesDirectory, dir)\n let dirList = await fs.readdir(fullDir)\n\n dirList = dirList.filter((d) => {\n if (\n d.startsWith('.') ||\n (routeFileIgnorePrefix && d.startsWith(routeFileIgnorePrefix))\n ) {\n return false\n }\n\n if (routeFilePrefix) {\n return d.startsWith(routeFilePrefix)\n }\n\n return true\n })\n\n await Promise.all(\n dirList.map(async (fileName) => {\n const fullPath = path.join(fullDir, fileName)\n const relativePath = path.join(dir, fileName)\n const stat = await fs.stat(fullPath)\n\n if (stat.isDirectory()) {\n await recurse(relativePath)\n } else {\n const filePath = path.join(dir, fileName)\n const filePathNoExt = removeExt(filePath)\n let routePath =\n replaceBackslash(\n cleanPath(`/${filePathNoExt.split('.').join('/')}`),\n ) ?? ''\n const variableName = fileToVariable(routePath)\n\n // Remove the index from the route path and\n // if the route path is empty, use `/'\n if (routePath === 'index') {\n routePath = '/'\n } else if (routePath.endsWith('/index')) {\n routePath = routePath.replace(/\\/index$/, '/')\n }\n\n routeNodes.push({\n filePath,\n fullPath,\n routePath,\n variableName,\n })\n }\n }),\n )\n\n return routeNodes\n }\n\n await recurse('./')\n\n return routeNodes\n}\n\nlet first = false\nlet skipMessage = false\n\ntype RouteSubNode = {\n component?: RouteNode\n loader?: RouteNode\n}\n\nexport async function generator(config: Config) {\n console.log()\n\n if (!first) {\n console.log('🔄 Generating routes...')\n first = true\n } else if (skipMessage) {\n skipMessage = false\n } else {\n console.log('♻️ Regenerating routes...')\n }\n\n const taskId = latestTask + 1\n latestTask = taskId\n\n const checkLatest = () => {\n if (latestTask !== taskId) {\n skipMessage = true\n return false\n }\n\n return true\n }\n\n const start = Date.now()\n const routePathIdPrefix = config.routeFilePrefix ?? ''\n\n let routeNodes = await getRouteNodes(config)\n\n routeNodes = multiSortBy(routeNodes, [\n (d) => (d.routePath === '/' ? -1 : 1),\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith('/') ? -1 : 1),\n (d) => d.routePath,\n ]).filter((d) => d.routePath !== `/${routePathIdPrefix + rootPathId}`)\n\n const routeTree: RouteNode[] = []\n const routePiecesByPath: Record<string, RouteSubNode> = {}\n\n // Loop over the flat list of routeNodes and\n // build up a tree based on the routeNodes' routePath\n routeNodes = routeNodes.filter((node) => {\n if (config.future?.unstable_codeSplitting) {\n node.isRoute = node.routePath?.endsWith('/route')\n node.isComponent = node.routePath?.endsWith('/component')\n node.isLoader = node.routePath?.endsWith('/loader')\n\n if (node.isComponent || node.isLoader || node.isRoute) {\n node.routePath = node.routePath?.replace(\n /\\/(component|loader|route)$/,\n '',\n )\n }\n }\n\n const parentRoute = hasParentRoute(routeNodes, node.routePath)\n if (parentRoute) node.parent = parentRoute\n\n node.path = node.parent\n ? node.routePath?.replace(node.parent.routePath!, '') || '/'\n : node.routePath\n\n const trimmedPath = trimPathLeft(node.path ?? '')\n\n const split = trimmedPath?.split('/') ?? []\n let first = split[0] ?? trimmedPath ?? ''\n\n node.isNonPath = first.startsWith('_')\n node.isNonLayout = first.endsWith('_')\n\n node.cleanedPath = removeUnderscores(node.path) ?? ''\n\n if (config.future?.unstable_codeSplitting) {\n if (node.isLoader || node.isComponent) {\n routePiecesByPath[node.routePath!] =\n routePiecesByPath[node.routePath!] || {}\n\n routePiecesByPath[node.routePath!]![\n node.isLoader ? 'loader' : 'component'\n ] = node\n return false\n }\n }\n\n if (node.parent) {\n node.parent.children = node.parent.children ?? []\n node.parent.children.push(node)\n } else {\n routeTree.push(node)\n }\n\n return true\n })\n\n async function buildRouteConfig(\n nodes: RouteNode[],\n depth = 1,\n ): Promise<string> {\n const children = nodes.map(async (node) => {\n const routeCode = await fs.readFile(node.fullPath, 'utf-8')\n\n // Ensure the boilerplate for the route exists\n if (node.isRoot) {\n return\n }\n\n // Ensure that new FileRoute(anything?) is replaced with FileRoute(${node.routePath})\n // routePath can contain $ characters, which have special meaning when used in replace\n // so we have to escape it by turning all $ into $$. But since we do it through a replace call\n // we have to double escape it into $$$$. For more information, see\n // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace#specifying_a_string_as_the_replacement\n const escapedRoutePath = node.routePath?.replaceAll('$', '$$$$') ?? ''\n const quote = config.quoteStyle === 'single' ? `'` : `\"`\n const replaced = routeCode.replace(\n fileRouteRegex,\n `new FileRoute(${quote}${escapedRoutePath}${quote})`,\n )\n\n if (replaced !== routeCode) {\n await fs.writeFile(node.fullPath, replaced)\n }\n\n const route = `${node.variableName}Route`\n\n if (node.children?.length) {\n const childConfigs = await buildRouteConfig(node.children, depth + 1)\n return `${route}.addChildren([${spaces(depth * 4)}${childConfigs}])`\n }\n\n return route\n })\n\n return (await Promise.all(children)).filter(Boolean).join(`,`)\n }\n\n const routeConfigChildrenText = await buildRouteConfig(routeTree)\n\n const sortedRouteNodes = multiSortBy(routeNodes, [\n (d) =>\n d.routePath?.includes(`/${routePathIdPrefix + rootPathId}`) ? -1 : 1,\n (d) => d.routePath?.split('/').length,\n (d) => (d.routePath?.endsWith(\"index'\") ? -1 : 1),\n (d) => d,\n ])\n\n const routeImports = [\n `import { lazyFn, lazyRouteComponent } from '@tanstack/react-router'`,\n '\\n',\n `import { Route as rootRoute } from './${sanitize(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, routePathIdPrefix + rootPathId),\n ),\n )}'`,\n ...sortedRouteNodes.map((node) => {\n return `import { Route as ${node.variableName}Import } from './${sanitize(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, node.filePath),\n ),\n ),\n )}'`\n }),\n '\\n',\n sortedRouteNodes\n .map((node) => {\n const loaderNode = routePiecesByPath[node.routePath!]?.loader\n const componentNode = routePiecesByPath[node.routePath!]?.component\n\n return [\n `const ${node.variableName}Route = ${node.variableName}Import.update({\n ${[\n node.isNonPath\n ? `id: '${node.path}'`\n : `path: '${node.cleanedPath}'`,\n `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,\n ]\n .filter(Boolean)\n .join(',')}\n } as any)`,\n loaderNode\n ? `.updateLoader({ loader: lazyFn(() => import('./${sanitize(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(config.routesDirectory, loaderNode.filePath),\n ),\n ),\n )}'), 'loader') })`\n : '',\n componentNode\n ? `.update({ component: lazyRouteComponent(() => import('./${sanitize(\n removeExt(\n path.relative(\n path.dirname(config.generatedRouteTree),\n path.resolve(\n config.routesDirectory,\n componentNode.filePath,\n ),\n ),\n ),\n )}'), 'component') })`\n : '',\n ].join('')\n })\n .join('\\n\\n'),\n ].join('\\n')\n\n const routeTypes = `declare module '@tanstack/react-router' {\n interface FileRoutesByPath {\n ${routeNodes\n .map((routeNode) => {\n return `'${routeNode.routePath}': {\n preLoaderRoute: typeof ${routeNode.variableName}Import\n parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route\n }`\n })\n .join('\\n')}\n }\n}`\n\n const routeConfig = `export const routeTree = rootRoute.addChildren([${routeConfigChildrenText}])`\n\n const routeConfigFileContent = await prettier.format(\n [routeImports, routeTypes, routeConfig].join('\\n\\n'),\n {\n semi: false,\n parser: 'typescript',\n },\n )\n\n const routeTreeContent = await fs\n .readFile(path.resolve(config.generatedRouteTree), 'utf-8')\n .catch((err: any) => {\n if (err.code === 'ENOENT') {\n return undefined\n }\n throw err\n })\n\n if (!checkLatest()) return\n\n if (routeTreeContent !== routeConfigFileContent) {\n await fs.ensureDir(path.dirname(path.resolve(config.generatedRouteTree)))\n if (!checkLatest()) return\n await fs.writeFile(\n path.resolve(config.generatedRouteTree),\n routeConfigFileContent,\n )\n }\n\n console.log(\n `🌲 Processed ${routeNodes.length} routes in ${Date.now() - start}ms`,\n )\n}\n\nfunction fileToVariable(d: string): string {\n return (\n removeUnderscores(d)\n ?.replace(/\\$/g, '')\n ?.split(/[/-]/g)\n .map((d, i) => (i > 0 ? capitalize(d) : d))\n .join('')\n .replace(/([^a-zA-Z0-9]|[\\.])/gm, '') ?? ''\n )\n}\n\nexport function removeExt(d: string) {\n return d.substring(0, d.lastIndexOf('.')) || d\n}\n\nfunction spaces(d: number): string {\n return Array.from({ length: d })\n .map(() => ' ')\n .join('')\n}\n\nexport function multiSortBy<T>(\n arr: T[],\n accessors: ((item: T) => any)[] = [(d) => d],\n): T[] {\n return arr\n .map((d, i) => [d, i] as const)\n .sort(([a, ai], [b, bi]) => {\n for (const accessor of accessors) {\n const ao = accessor(a)\n const bo = accessor(b)\n\n if (typeof ao === 'undefined') {\n if (typeof bo === 'undefined') {\n continue\n }\n return 1\n }\n\n if (ao === bo) {\n continue\n }\n\n return ao > bo ? 1 : -1\n }\n\n return ai - bi\n })\n .map(([d]) => d)\n}\n\nfunction capitalize(s: string) {\n if (typeof s !== 'string') return ''\n return s.charAt(0).toUpperCase() + s.slice(1)\n}\n\nfunction sanitize(s?: string) {\n return replaceBackslash(s?.replace(/\\\\index/gi, ''))\n}\n\nfunction removeUnderscores(s?: string) {\n return s?.replace(/(^_|_$)/, '').replace(/(\\/_|_\\/)/, '/')\n}\n\nfunction replaceBackslash(s?: string) {\n return s?.replace(/\\\\/gi, '/')\n}\n\nexport function hasParentRoute(\n routes: RouteNode[],\n routePathToCheck: string | undefined,\n): RouteNode | null {\n if (!routePathToCheck || routePathToCheck === '/') {\n return null\n }\n\n const sortedNodes = multiSortBy(routes, [\n (d) => d.routePath!.length * -1,\n (d) => d.variableName,\n ]).filter((d) => d.routePath !== `/${rootPathId}`)\n\n for (const route of sortedNodes) {\n if (route.routePath === '/') continue\n\n if (\n routePathToCheck.startsWith(`${route.routePath}/`) &&\n route.routePath !== routePathToCheck\n ) {\n return route\n }\n }\n const segments = routePathToCheck.split('/')\n segments.pop() // Remove the last segment\n const parentRoute = segments.join('/')\n\n return hasParentRoute(routes, parentRoute)\n}\n"],"names":["latestTask","rootPathId","fileRouteRegex","getRouteNodes","config","routeFilePrefix","routeFileIgnorePrefix","routeNodes","recurse","dir","fullDir","path","resolve","routesDirectory","dirList","fs","readdir","filter","d","startsWith","Promise","all","map","fileName","fullPath","join","relativePath","stat","isDirectory","filePath","filePathNoExt","removeExt","routePath","replaceBackslash","cleanPath","split","variableName","fileToVariable","endsWith","replace","push","first","skipMessage","generator","console","log","taskId","checkLatest","start","Date","now","routePathIdPrefix","multiSortBy","length","routeTree","routePiecesByPath","node","future","unstable_codeSplitting","isRoute","isComponent","isLoader","parentRoute","hasParentRoute","parent","trimmedPath","trimPathLeft","isNonPath","isNonLayout","cleanedPath","removeUnderscores","children","buildRouteConfig","nodes","depth","routeCode","readFile","isRoot","escapedRoutePath","replaceAll","quote","quoteStyle","replaced","writeFile","route","childConfigs","spaces","Boolean","routeConfigChildrenText","sortedRouteNodes","includes","routeImports","sanitize","relative","dirname","generatedRouteTree","loaderNode","loader","componentNode","component","routeTypes","routeNode","routeConfig","routeConfigFileContent","prettier","format","semi","parser","routeTreeContent","catch","err","code","undefined","ensureDir","i","capitalize","substring","lastIndexOf","Array","from","arr","accessors","sort","a","ai","b","bi","accessor","ao","bo","s","charAt","toUpperCase","slice","routes","routePathToCheck","sortedNodes","segments","pop"],"mappings":"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"}
@@ -5,18 +5,31 @@ declare const configSchema: z.ZodObject<{
5
5
  routesDirectory: z.ZodString;
6
6
  generatedRouteTree: z.ZodString;
7
7
  quoteStyle: z.ZodDefault<z.ZodOptional<z.ZodEnum<["single", "double"]>>>;
8
+ future: z.ZodOptional<z.ZodObject<{
9
+ unstable_codeSplitting: z.ZodOptional<z.ZodBoolean>;
10
+ }, "strip", z.ZodTypeAny, {
11
+ unstable_codeSplitting?: boolean | undefined;
12
+ }, {
13
+ unstable_codeSplitting?: boolean | undefined;
14
+ }>>;
8
15
  }, "strip", z.ZodTypeAny, {
9
16
  routesDirectory: string;
10
17
  generatedRouteTree: string;
11
18
  quoteStyle: "single" | "double";
12
19
  routeFilePrefix?: string | undefined;
13
20
  routeFileIgnorePrefix?: string | undefined;
21
+ future?: {
22
+ unstable_codeSplitting?: boolean | undefined;
23
+ } | undefined;
14
24
  }, {
15
25
  routesDirectory: string;
16
26
  generatedRouteTree: string;
17
27
  routeFilePrefix?: string | undefined;
18
28
  routeFileIgnorePrefix?: string | undefined;
19
29
  quoteStyle?: "single" | "double" | undefined;
30
+ future?: {
31
+ unstable_codeSplitting?: boolean | undefined;
32
+ } | undefined;
20
33
  }>;
21
34
  export type Config = z.infer<typeof configSchema>;
22
35
  export declare function getConfig(): Promise<Config>;
@@ -10,6 +10,9 @@ export type RouteNode = {
10
10
  path?: string;
11
11
  isNonPath?: boolean;
12
12
  isNonLayout?: boolean;
13
+ isRoute?: boolean;
14
+ isLoader?: boolean;
15
+ isComponent?: boolean;
13
16
  isRoot?: boolean;
14
17
  children?: RouteNode[];
15
18
  parent?: RouteNode;
@@ -17,4 +20,4 @@ export type RouteNode = {
17
20
  export declare function generator(config: Config): Promise<void>;
18
21
  export declare function removeExt(d: string): string;
19
22
  export declare function multiSortBy<T>(arr: T[], accessors?: ((item: T) => any)[]): T[];
20
- export declare function hasParentRoute(routes: RouteNode[], routeToCheck: string | undefined): RouteNode | null;
23
+ export declare function hasParentRoute(routes: RouteNode[], routePathToCheck: string | undefined): RouteNode | null;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/router-cli",
3
3
  "author": "Tanner Linsley",
4
- "version": "1.1.5",
4
+ "version": "1.1.7",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router",
@@ -59,7 +59,7 @@
59
59
  "through2": "^4.0.2",
60
60
  "yargs": "^17.6.2",
61
61
  "zod": "^3.19.1",
62
- "@tanstack/react-router": "1.1.5"
62
+ "@tanstack/react-router": "1.1.7"
63
63
  },
64
64
  "scripts": {
65
65
  "build": "rollup --config rollup.config.js"
package/src/config.ts CHANGED
@@ -8,6 +8,11 @@ const configSchema = z.object({
8
8
  routesDirectory: z.string(),
9
9
  generatedRouteTree: z.string(),
10
10
  quoteStyle: z.enum(['single', 'double']).optional().default('single'),
11
+ future: z
12
+ .object({
13
+ unstable_codeSplitting: z.boolean().optional(),
14
+ })
15
+ .optional(),
11
16
  })
12
17
 
13
18
  export type Config = z.infer<typeof configSchema>
package/src/generator.ts CHANGED
@@ -17,6 +17,9 @@ export type RouteNode = {
17
17
  path?: string
18
18
  isNonPath?: boolean
19
19
  isNonLayout?: boolean
20
+ isRoute?: boolean
21
+ isLoader?: boolean
22
+ isComponent?: boolean
20
23
  isRoot?: boolean
21
24
  children?: RouteNode[]
22
25
  parent?: RouteNode
@@ -92,6 +95,11 @@ async function getRouteNodes(config: Config) {
92
95
  let first = false
93
96
  let skipMessage = false
94
97
 
98
+ type RouteSubNode = {
99
+ component?: RouteNode
100
+ loader?: RouteNode
101
+ }
102
+
95
103
  export async function generator(config: Config) {
96
104
  console.log()
97
105
 
@@ -129,18 +137,24 @@ export async function generator(config: Config) {
129
137
  ]).filter((d) => d.routePath !== `/${routePathIdPrefix + rootPathId}`)
130
138
 
131
139
  const routeTree: RouteNode[] = []
140
+ const routePiecesByPath: Record<string, RouteSubNode> = {}
132
141
 
133
142
  // Loop over the flat list of routeNodes and
134
143
  // build up a tree based on the routeNodes' routePath
135
- routeNodes.forEach((node) => {
136
- // routeNodes.forEach((existingNode) => {
137
- // if (
138
- // node.routePath?.startsWith(`${existingNode?.routePath ?? ''}/`)
139
- // // node.routePath.length > existingNode.routePath!.length
140
- // ) {
141
- // node.parent = existingNode
142
- // }
143
- // })
144
+ routeNodes = routeNodes.filter((node) => {
145
+ if (config.future?.unstable_codeSplitting) {
146
+ node.isRoute = node.routePath?.endsWith('/route')
147
+ node.isComponent = node.routePath?.endsWith('/component')
148
+ node.isLoader = node.routePath?.endsWith('/loader')
149
+
150
+ if (node.isComponent || node.isLoader || node.isRoute) {
151
+ node.routePath = node.routePath?.replace(
152
+ /\/(component|loader|route)$/,
153
+ '',
154
+ )
155
+ }
156
+ }
157
+
144
158
  const parentRoute = hasParentRoute(routeNodes, node.routePath)
145
159
  if (parentRoute) node.parent = parentRoute
146
160
 
@@ -158,12 +172,26 @@ export async function generator(config: Config) {
158
172
 
159
173
  node.cleanedPath = removeUnderscores(node.path) ?? ''
160
174
 
175
+ if (config.future?.unstable_codeSplitting) {
176
+ if (node.isLoader || node.isComponent) {
177
+ routePiecesByPath[node.routePath!] =
178
+ routePiecesByPath[node.routePath!] || {}
179
+
180
+ routePiecesByPath[node.routePath!]![
181
+ node.isLoader ? 'loader' : 'component'
182
+ ] = node
183
+ return false
184
+ }
185
+ }
186
+
161
187
  if (node.parent) {
162
188
  node.parent.children = node.parent.children ?? []
163
189
  node.parent.children.push(node)
164
190
  } else {
165
191
  routeTree.push(node)
166
192
  }
193
+
194
+ return true
167
195
  })
168
196
 
169
197
  async function buildRouteConfig(
@@ -209,21 +237,25 @@ export async function generator(config: Config) {
209
237
 
210
238
  const routeConfigChildrenText = await buildRouteConfig(routeTree)
211
239
 
240
+ const sortedRouteNodes = multiSortBy(routeNodes, [
241
+ (d) =>
242
+ d.routePath?.includes(`/${routePathIdPrefix + rootPathId}`) ? -1 : 1,
243
+ (d) => d.routePath?.split('/').length,
244
+ (d) => (d.routePath?.endsWith("index'") ? -1 : 1),
245
+ (d) => d,
246
+ ])
247
+
212
248
  const routeImports = [
249
+ `import { lazyFn, lazyRouteComponent } from '@tanstack/react-router'`,
250
+ '\n',
213
251
  `import { Route as rootRoute } from './${sanitize(
214
252
  path.relative(
215
253
  path.dirname(config.generatedRouteTree),
216
254
  path.resolve(config.routesDirectory, routePathIdPrefix + rootPathId),
217
255
  ),
218
256
  )}'`,
219
- ...multiSortBy(routeNodes, [
220
- (d) =>
221
- d.routePath?.includes(`/${routePathIdPrefix + rootPathId}`) ? -1 : 1,
222
- (d) => d.routePath?.split('/').length,
223
- (d) => (d.routePath?.endsWith("index'") ? -1 : 1),
224
- (d) => d,
225
- ]).map((node) => {
226
- return `import { Route as ${node.variableName}Route } from './${sanitize(
257
+ ...sortedRouteNodes.map((node) => {
258
+ return `import { Route as ${node.variableName}Import } from './${sanitize(
227
259
  removeExt(
228
260
  path.relative(
229
261
  path.dirname(config.generatedRouteTree),
@@ -232,6 +264,49 @@ export async function generator(config: Config) {
232
264
  ),
233
265
  )}'`
234
266
  }),
267
+ '\n',
268
+ sortedRouteNodes
269
+ .map((node) => {
270
+ const loaderNode = routePiecesByPath[node.routePath!]?.loader
271
+ const componentNode = routePiecesByPath[node.routePath!]?.component
272
+
273
+ return [
274
+ `const ${node.variableName}Route = ${node.variableName}Import.update({
275
+ ${[
276
+ node.isNonPath
277
+ ? `id: '${node.path}'`
278
+ : `path: '${node.cleanedPath}'`,
279
+ `getParentRoute: () => ${node.parent?.variableName ?? 'root'}Route`,
280
+ ]
281
+ .filter(Boolean)
282
+ .join(',')}
283
+ } as any)`,
284
+ loaderNode
285
+ ? `.updateLoader({ loader: lazyFn(() => import('./${sanitize(
286
+ removeExt(
287
+ path.relative(
288
+ path.dirname(config.generatedRouteTree),
289
+ path.resolve(config.routesDirectory, loaderNode.filePath),
290
+ ),
291
+ ),
292
+ )}'), 'loader') })`
293
+ : '',
294
+ componentNode
295
+ ? `.update({ component: lazyRouteComponent(() => import('./${sanitize(
296
+ removeExt(
297
+ path.relative(
298
+ path.dirname(config.generatedRouteTree),
299
+ path.resolve(
300
+ config.routesDirectory,
301
+ componentNode.filePath,
302
+ ),
303
+ ),
304
+ ),
305
+ )}'), 'component') })`
306
+ : '',
307
+ ].join('')
308
+ })
309
+ .join('\n\n'),
235
310
  ].join('\n')
236
311
 
237
312
  const routeTypes = `declare module '@tanstack/react-router' {
@@ -239,6 +314,7 @@ export async function generator(config: Config) {
239
314
  ${routeNodes
240
315
  .map((routeNode) => {
241
316
  return `'${routeNode.routePath}': {
317
+ preLoaderRoute: typeof ${routeNode.variableName}Import
242
318
  parentRoute: typeof ${routeNode.parent?.variableName ?? 'root'}Route
243
319
  }`
244
320
  })
@@ -246,40 +322,10 @@ export async function generator(config: Config) {
246
322
  }
247
323
  }`
248
324
 
249
- const routeOptions = routeNodes
250
- .map((routeNode) => {
251
- return `Object.assign(${routeNode.variableName ?? 'root'}Route.options, {
252
- ${[
253
- routeNode.isNonPath
254
- ? `id: '${routeNode.path}'`
255
- : `path: '${routeNode.cleanedPath}'`,
256
- `getParentRoute: () => ${
257
- routeNode.parent?.variableName ?? 'root'
258
- }Route`,
259
- // `\n// ${JSON.stringify(
260
- // {
261
- // ...routeNode,
262
- // parent: undefined,
263
- // children: undefined,
264
- // fullPath: undefined,
265
- // variableName: undefined,
266
- // },
267
- // null,
268
- // 2,
269
- // )
270
- // .split('\n')
271
- // .join('\n// ')}`,
272
- ]
273
- .filter(Boolean)
274
- .join(',')}
275
- })`
276
- })
277
- .join('\n\n')
278
-
279
325
  const routeConfig = `export const routeTree = rootRoute.addChildren([${routeConfigChildrenText}])`
280
326
 
281
327
  const routeConfigFileContent = await prettier.format(
282
- [routeImports, routeTypes, routeOptions, routeConfig].join('\n\n'),
328
+ [routeImports, routeTypes, routeConfig].join('\n\n'),
283
329
  {
284
330
  semi: false,
285
331
  parser: 'typescript',
@@ -381,9 +427,9 @@ function replaceBackslash(s?: string) {
381
427
 
382
428
  export function hasParentRoute(
383
429
  routes: RouteNode[],
384
- routeToCheck: string | undefined,
430
+ routePathToCheck: string | undefined,
385
431
  ): RouteNode | null {
386
- if (!routeToCheck || routeToCheck === '/') {
432
+ if (!routePathToCheck || routePathToCheck === '/') {
387
433
  return null
388
434
  }
389
435
 
@@ -396,13 +442,13 @@ export function hasParentRoute(
396
442
  if (route.routePath === '/') continue
397
443
 
398
444
  if (
399
- routeToCheck.startsWith(`${route.routePath}/`) &&
400
- route.routePath !== routeToCheck
445
+ routePathToCheck.startsWith(`${route.routePath}/`) &&
446
+ route.routePath !== routePathToCheck
401
447
  ) {
402
448
  return route
403
449
  }
404
450
  }
405
- const segments = routeToCheck.split('/')
451
+ const segments = routePathToCheck.split('/')
406
452
  segments.pop() // Remove the last segment
407
453
  const parentRoute = segments.join('/')
408
454