@tanstack/router-plugin 1.120.5 → 1.121.0-alpha.2

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.
Files changed (88) hide show
  1. package/dist/cjs/core/code-splitter/compilers.cjs +195 -194
  2. package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
  3. package/dist/cjs/core/code-splitter/compilers.d.cts +3 -0
  4. package/dist/cjs/core/code-splitter/framework-options.cjs +4 -8
  5. package/dist/cjs/core/code-splitter/framework-options.cjs.map +1 -1
  6. package/dist/cjs/core/code-splitter/framework-options.d.cts +0 -2
  7. package/dist/cjs/core/config.d.cts +31 -40
  8. package/dist/cjs/core/route-autoimport-plugin.cjs +98 -0
  9. package/dist/cjs/core/route-autoimport-plugin.cjs.map +1 -0
  10. package/dist/cjs/core/route-autoimport-plugin.d.cts +6 -0
  11. package/dist/cjs/core/route-hmr-statement.cjs +33 -0
  12. package/dist/cjs/core/route-hmr-statement.cjs.map +1 -0
  13. package/dist/cjs/core/route-hmr-statement.d.cts +1 -0
  14. package/dist/cjs/core/router-code-splitter-plugin.cjs +11 -20
  15. package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
  16. package/dist/cjs/core/router-composed-plugin.cjs +19 -5
  17. package/dist/cjs/core/router-composed-plugin.cjs.map +1 -1
  18. package/dist/cjs/core/router-generator-plugin.cjs +8 -2
  19. package/dist/cjs/core/router-generator-plugin.cjs.map +1 -1
  20. package/dist/cjs/core/router-hmr-plugin.cjs +51 -0
  21. package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -0
  22. package/dist/cjs/core/router-hmr-plugin.d.cts +8 -0
  23. package/dist/cjs/core/utils.cjs +12 -0
  24. package/dist/cjs/core/utils.cjs.map +1 -0
  25. package/dist/cjs/core/utils.d.cts +2 -0
  26. package/dist/cjs/esbuild.cjs +2 -0
  27. package/dist/cjs/esbuild.cjs.map +1 -1
  28. package/dist/cjs/esbuild.d.cts +53 -27
  29. package/dist/cjs/rspack.cjs +2 -0
  30. package/dist/cjs/rspack.cjs.map +1 -1
  31. package/dist/cjs/rspack.d.cts +53 -27
  32. package/dist/cjs/vite.cjs +2 -0
  33. package/dist/cjs/vite.cjs.map +1 -1
  34. package/dist/cjs/vite.d.cts +52 -26
  35. package/dist/cjs/webpack.cjs +2 -0
  36. package/dist/cjs/webpack.cjs.map +1 -1
  37. package/dist/cjs/webpack.d.cts +53 -27
  38. package/dist/esm/core/code-splitter/compilers.d.ts +3 -0
  39. package/dist/esm/core/code-splitter/compilers.js +195 -194
  40. package/dist/esm/core/code-splitter/compilers.js.map +1 -1
  41. package/dist/esm/core/code-splitter/framework-options.d.ts +0 -2
  42. package/dist/esm/core/code-splitter/framework-options.js +4 -8
  43. package/dist/esm/core/code-splitter/framework-options.js.map +1 -1
  44. package/dist/esm/core/config.d.ts +31 -40
  45. package/dist/esm/core/route-autoimport-plugin.d.ts +6 -0
  46. package/dist/esm/core/route-autoimport-plugin.js +81 -0
  47. package/dist/esm/core/route-autoimport-plugin.js.map +1 -0
  48. package/dist/esm/core/route-hmr-statement.d.ts +1 -0
  49. package/dist/esm/core/route-hmr-statement.js +16 -0
  50. package/dist/esm/core/route-hmr-statement.js.map +1 -0
  51. package/dist/esm/core/router-code-splitter-plugin.js +5 -14
  52. package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
  53. package/dist/esm/core/router-composed-plugin.js +19 -5
  54. package/dist/esm/core/router-composed-plugin.js.map +1 -1
  55. package/dist/esm/core/router-generator-plugin.js +8 -2
  56. package/dist/esm/core/router-generator-plugin.js.map +1 -1
  57. package/dist/esm/core/router-hmr-plugin.d.ts +8 -0
  58. package/dist/esm/core/router-hmr-plugin.js +51 -0
  59. package/dist/esm/core/router-hmr-plugin.js.map +1 -0
  60. package/dist/esm/core/utils.d.ts +2 -0
  61. package/dist/esm/core/utils.js +12 -0
  62. package/dist/esm/core/utils.js.map +1 -0
  63. package/dist/esm/esbuild.d.ts +53 -27
  64. package/dist/esm/esbuild.js +3 -1
  65. package/dist/esm/esbuild.js.map +1 -1
  66. package/dist/esm/rspack.d.ts +53 -27
  67. package/dist/esm/rspack.js +3 -1
  68. package/dist/esm/rspack.js.map +1 -1
  69. package/dist/esm/vite.d.ts +52 -26
  70. package/dist/esm/vite.js +3 -1
  71. package/dist/esm/vite.js.map +1 -1
  72. package/dist/esm/webpack.d.ts +53 -27
  73. package/dist/esm/webpack.js +3 -1
  74. package/dist/esm/webpack.js.map +1 -1
  75. package/package.json +6 -6
  76. package/src/core/code-splitter/compilers.ts +265 -277
  77. package/src/core/code-splitter/framework-options.ts +0 -6
  78. package/src/core/route-autoimport-plugin.ts +102 -0
  79. package/src/core/route-hmr-statement.ts +13 -0
  80. package/src/core/router-code-splitter-plugin.ts +3 -23
  81. package/src/core/router-composed-plugin.ts +20 -10
  82. package/src/core/router-generator-plugin.ts +12 -1
  83. package/src/core/router-hmr-plugin.ts +65 -0
  84. package/src/core/utils.ts +18 -0
  85. package/src/esbuild.ts +3 -2
  86. package/src/rspack.ts +3 -2
  87. package/src/vite.ts +3 -0
  88. package/src/webpack.ts +3 -1
@@ -7,33 +7,13 @@ import {
7
7
  } from 'babel-dead-code-elimination'
8
8
  import { generateFromAst, parseAst } from '@tanstack/router-utils'
9
9
  import { tsrSplit } from '../constants'
10
+ import { routeHmrStatement } from '../route-hmr-statement'
10
11
  import { createIdentifier } from './path-ids'
11
12
  import { getFrameworkOptions } from './framework-options'
12
13
  import type { GeneratorResult, ParseAstOptions } from '@tanstack/router-utils'
13
14
  import type { CodeSplitGroupings, SplitRouteIdentNodes } from '../constants'
14
15
  import type { Config } from '../config'
15
16
 
16
- // eslint-disable-next-line unused-imports/no-unused-vars
17
- const debug = process.env.TSR_VITE_DEBUG
18
-
19
- type SplitModulesById = Record<
20
- string,
21
- { id: string; node: t.FunctionExpression }
22
- >
23
-
24
- interface State {
25
- filename: string
26
- opts: {
27
- minify: boolean
28
- root: string
29
- }
30
- imported: Record<string, boolean>
31
- refs: Set<any>
32
- serverIndex: number
33
- splitIndex: number
34
- splitModulesById: SplitModulesById
35
- }
36
-
37
17
  type SplitNodeMeta = {
38
18
  routeIdent: SplitRouteIdentNodes
39
19
  splitStrategy: 'lazyFn' | 'lazyRouteComponent'
@@ -117,6 +97,8 @@ export function compileCodeSplitReferenceRoute(
117
97
  runtimeEnv: 'dev' | 'prod'
118
98
  codeSplitGroupings: CodeSplitGroupings
119
99
  targetFramework: Config['target']
100
+ filename: string
101
+ id: string
120
102
  },
121
103
  ): GeneratorResult {
122
104
  const ast = parseAst(opts)
@@ -136,9 +118,7 @@ export function compileCodeSplitReferenceRoute(
136
118
 
137
119
  babel.traverse(ast, {
138
120
  Program: {
139
- enter(programPath, programState) {
140
- const state = programState as unknown as State
141
-
121
+ enter(programPath) {
142
122
  /**
143
123
  * If the component for the route is being imported from
144
124
  * another file, this is to track the path to that file
@@ -150,229 +130,228 @@ export function compileCodeSplitReferenceRoute(
150
130
  */
151
131
  const removableImportPaths = new Set<string>([])
152
132
 
153
- programPath.traverse(
154
- {
155
- CallExpression: (path) => {
156
- if (!t.isIdentifier(path.node.callee)) {
157
- return
158
- }
159
-
160
- if (
161
- !(
162
- path.node.callee.name === 'createRoute' ||
163
- path.node.callee.name === 'createFileRoute'
164
- )
165
- ) {
166
- return
167
- }
133
+ programPath.traverse({
134
+ CallExpression: (path) => {
135
+ if (!t.isIdentifier(path.node.callee)) {
136
+ return
137
+ }
168
138
 
169
- if (t.isCallExpression(path.parentPath.node)) {
170
- const options = resolveIdentifier(
171
- path,
172
- path.parentPath.node.arguments[0],
173
- )
139
+ if (
140
+ !(
141
+ path.node.callee.name === 'createRoute' ||
142
+ path.node.callee.name === 'createFileRoute'
143
+ )
144
+ ) {
145
+ return
146
+ }
174
147
 
175
- const hasImportedOrDefinedIdentifier = (name: string) => {
176
- return programPath.scope.hasBinding(name)
177
- }
148
+ function babelHandleReference(routeOptions: t.Node | undefined) {
149
+ const hasImportedOrDefinedIdentifier = (name: string) => {
150
+ return programPath.scope.hasBinding(name)
151
+ }
178
152
 
179
- if (t.isObjectExpression(options)) {
180
- options.properties.forEach((prop) => {
181
- if (t.isObjectProperty(prop)) {
182
- if (t.isIdentifier(prop.key)) {
183
- // If the user has not specified a split grouping for this key
184
- // then we should not split it
185
- const codeSplitGroupingByKey = findIndexForSplitNode(
186
- prop.key.name,
187
- )
188
- if (codeSplitGroupingByKey === -1) {
189
- return
190
- }
191
- const codeSplitGroup = [
192
- ...new Set(
193
- opts.codeSplitGroupings[codeSplitGroupingByKey],
194
- ),
195
- ]
196
-
197
- const key = prop.key.name
198
- // find key in nodeSplitConfig
199
- const isNodeConfigAvailable = SPLIT_NODES_CONFIG.has(
200
- key as any,
201
- )
202
-
203
- if (!isNodeConfigAvailable) {
204
- return
205
- }
153
+ if (t.isObjectExpression(routeOptions)) {
154
+ routeOptions.properties.forEach((prop) => {
155
+ if (t.isObjectProperty(prop)) {
156
+ if (t.isIdentifier(prop.key)) {
157
+ // If the user has not specified a split grouping for this key
158
+ // then we should not split it
159
+ const codeSplitGroupingByKey = findIndexForSplitNode(
160
+ prop.key.name,
161
+ )
162
+ if (codeSplitGroupingByKey === -1) {
163
+ return
164
+ }
165
+ const codeSplitGroup = [
166
+ ...new Set(
167
+ opts.codeSplitGroupings[codeSplitGroupingByKey],
168
+ ),
169
+ ]
170
+
171
+ const key = prop.key.name
172
+ // find key in nodeSplitConfig
173
+ const isNodeConfigAvailable = SPLIT_NODES_CONFIG.has(
174
+ key as any,
175
+ )
176
+
177
+ if (!isNodeConfigAvailable) {
178
+ return
179
+ }
206
180
 
207
- const splitNodeMeta = SPLIT_NODES_CONFIG.get(
208
- key as any,
209
- )!
181
+ const splitNodeMeta = SPLIT_NODES_CONFIG.get(key as any)!
210
182
 
211
- // We need to extract the existing search params from the filename, if any
212
- // and add the relevant codesplitPrefix to them, then write them back to the filename
213
- const splitUrl = addSplitSearchParamToFilename(
214
- opts.filename,
215
- codeSplitGroup,
216
- )
183
+ // We need to extract the existing search params from the filename, if any
184
+ // and add the relevant codesplitPrefix to them, then write them back to the filename
185
+ const splitUrl = addSplitSearchParamToFilename(
186
+ opts.filename,
187
+ codeSplitGroup,
188
+ )
217
189
 
218
- if (
219
- splitNodeMeta.splitStrategy === 'lazyRouteComponent'
220
- ) {
221
- const value = prop.value
222
-
223
- let shouldSplit = true
224
-
225
- if (t.isIdentifier(value)) {
226
- const existingImportPath =
227
- getImportSpecifierAndPathFromLocalName(
228
- programPath,
229
- value.name,
230
- ).path
231
- if (existingImportPath) {
232
- removableImportPaths.add(existingImportPath)
233
- }
190
+ if (
191
+ splitNodeMeta.splitStrategy === 'lazyRouteComponent'
192
+ ) {
193
+ const value = prop.value
234
194
 
235
- // exported identifiers should not be split
236
- // since they are already being imported
237
- // and need to be retained in the compiled file
238
- const isExported = hasExport(ast, value)
239
- shouldSplit = !isExported
195
+ let shouldSplit = true
240
196
 
241
- if (shouldSplit) {
242
- removeIdentifierLiteral(path, value)
243
- }
244
- }
245
-
246
- if (!shouldSplit) {
247
- return
197
+ if (t.isIdentifier(value)) {
198
+ const existingImportPath =
199
+ getImportSpecifierAndPathFromLocalName(
200
+ programPath,
201
+ value.name,
202
+ ).path
203
+ if (existingImportPath) {
204
+ removableImportPaths.add(existingImportPath)
248
205
  }
249
206
 
250
- // Prepend the import statement to the program along with the importer function
251
- // Check to see if lazyRouteComponent is already imported before attempting
252
- // to import it again
207
+ // exported identifiers should not be split
208
+ // since they are already being imported
209
+ // and need to be retained in the compiled file
210
+ const isExported = hasExport(ast, value)
211
+ shouldSplit = !isExported
253
212
 
254
- if (
255
- !hasImportedOrDefinedIdentifier(
256
- LAZY_ROUTE_COMPONENT_IDENT,
257
- )
258
- ) {
259
- programPath.unshiftContainer('body', [
260
- template.statement(
261
- `import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`,
262
- )(),
263
- ])
213
+ if (shouldSplit) {
214
+ removeIdentifierLiteral(path, value)
264
215
  }
216
+ }
265
217
 
266
- // Check to see if the importer function is already defined
267
- // If not, define it with the dynamic import statement
268
- if (
269
- !hasImportedOrDefinedIdentifier(
270
- splitNodeMeta.localImporterIdent,
271
- )
272
- ) {
273
- programPath.unshiftContainer('body', [
274
- template.statement(
275
- `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
276
- )(),
277
- ])
278
- }
218
+ if (!shouldSplit) {
219
+ return
220
+ }
279
221
 
280
- // If it's a component, we need to pass the function to check the Route.ssr value
281
- if (key === 'component') {
282
- prop.value = template.expression(
283
- `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}', () => Route.ssr)`,
284
- )()
285
- } else {
286
- prop.value = template.expression(
287
- `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
288
- )()
289
- }
222
+ // Prepend the import statement to the program along with the importer function
223
+ // Check to see if lazyRouteComponent is already imported before attempting
224
+ // to import it again
290
225
 
291
- // If the TSRDummyComponent is not defined, define it
292
- if (
293
- opts.runtimeEnv !== 'prod' && // only in development
294
- !hasImportedOrDefinedIdentifier(
295
- frameworkOptions.idents.dummyHMRComponent,
296
- )
297
- ) {
298
- programPath.pushContainer('body', [
299
- template.statement(
300
- frameworkOptions.dummyHMRComponent,
301
- )(),
302
- ])
303
- }
226
+ if (
227
+ !hasImportedOrDefinedIdentifier(
228
+ LAZY_ROUTE_COMPONENT_IDENT,
229
+ )
230
+ ) {
231
+ programPath.unshiftContainer('body', [
232
+ template.statement(
233
+ `import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`,
234
+ )(),
235
+ ])
304
236
  }
305
237
 
306
- if (splitNodeMeta.splitStrategy === 'lazyFn') {
307
- const value = prop.value
238
+ // Check to see if the importer function is already defined
239
+ // If not, define it with the dynamic import statement
240
+ if (
241
+ !hasImportedOrDefinedIdentifier(
242
+ splitNodeMeta.localImporterIdent,
243
+ )
244
+ ) {
245
+ programPath.unshiftContainer('body', [
246
+ template.statement(
247
+ `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
248
+ )(),
249
+ ])
250
+ }
308
251
 
309
- let shouldSplit = true
252
+ // If it's a component, we need to pass the function to check the Route.ssr value
253
+ if (key === 'component') {
254
+ prop.value = template.expression(
255
+ `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}', () => Route.ssr)`,
256
+ )()
257
+ } else {
258
+ prop.value = template.expression(
259
+ `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
260
+ )()
261
+ }
310
262
 
311
- if (t.isIdentifier(value)) {
312
- const existingImportPath =
313
- getImportSpecifierAndPathFromLocalName(
314
- programPath,
315
- value.name,
316
- ).path
317
- if (existingImportPath) {
318
- removableImportPaths.add(existingImportPath)
319
- }
263
+ // add HMR handling
264
+ if (opts.runtimeEnv !== 'prod') {
265
+ programPath.pushContainer('body', routeHmrStatement)
266
+ }
267
+ }
320
268
 
321
- // exported identifiers should not be split
322
- // since they are already being imported
323
- // and need to be retained in the compiled file
324
- const isExported = hasExport(ast, value)
325
- shouldSplit = !isExported
269
+ if (splitNodeMeta.splitStrategy === 'lazyFn') {
270
+ const value = prop.value
326
271
 
327
- if (shouldSplit) {
328
- removeIdentifierLiteral(path, value)
329
- }
330
- }
272
+ let shouldSplit = true
331
273
 
332
- if (!shouldSplit) {
333
- return
274
+ if (t.isIdentifier(value)) {
275
+ const existingImportPath =
276
+ getImportSpecifierAndPathFromLocalName(
277
+ programPath,
278
+ value.name,
279
+ ).path
280
+ if (existingImportPath) {
281
+ removableImportPaths.add(existingImportPath)
334
282
  }
335
283
 
336
- // Prepend the import statement to the program along with the importer function
337
- if (!hasImportedOrDefinedIdentifier(LAZY_FN_IDENT)) {
338
- programPath.unshiftContainer(
339
- 'body',
340
- template.smart(
341
- `import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`,
342
- )(),
343
- )
344
- }
284
+ // exported identifiers should not be split
285
+ // since they are already being imported
286
+ // and need to be retained in the compiled file
287
+ const isExported = hasExport(ast, value)
288
+ shouldSplit = !isExported
345
289
 
346
- // Check to see if the importer function is already defined
347
- // If not, define it with the dynamic import statement
348
- if (
349
- !hasImportedOrDefinedIdentifier(
350
- splitNodeMeta.localImporterIdent,
351
- )
352
- ) {
353
- programPath.unshiftContainer('body', [
354
- template.statement(
355
- `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
356
- )(),
357
- ])
290
+ if (shouldSplit) {
291
+ removeIdentifierLiteral(path, value)
358
292
  }
293
+ }
359
294
 
360
- // Add the lazyFn call with the dynamic import to the prop value
361
- prop.value = template.expression(
362
- `${LAZY_FN_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
363
- )()
295
+ if (!shouldSplit) {
296
+ return
297
+ }
298
+
299
+ // Prepend the import statement to the program along with the importer function
300
+ if (!hasImportedOrDefinedIdentifier(LAZY_FN_IDENT)) {
301
+ programPath.unshiftContainer(
302
+ 'body',
303
+ template.smart(
304
+ `import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`,
305
+ )(),
306
+ )
307
+ }
308
+
309
+ // Check to see if the importer function is already defined
310
+ // If not, define it with the dynamic import statement
311
+ if (
312
+ !hasImportedOrDefinedIdentifier(
313
+ splitNodeMeta.localImporterIdent,
314
+ )
315
+ ) {
316
+ programPath.unshiftContainer('body', [
317
+ template.statement(
318
+ `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
319
+ )(),
320
+ ])
364
321
  }
322
+
323
+ // Add the lazyFn call with the dynamic import to the prop value
324
+ prop.value = template.expression(
325
+ `${LAZY_FN_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
326
+ )()
365
327
  }
366
328
  }
329
+ }
367
330
 
368
- programPath.scope.crawl()
369
- })
370
- }
331
+ programPath.scope.crawl()
332
+ })
371
333
  }
372
- },
334
+ }
335
+
336
+ if (t.isCallExpression(path.parentPath.node)) {
337
+ // createFileRoute('/')({ ... })
338
+ const options = resolveIdentifier(
339
+ path,
340
+ path.parentPath.node.arguments[0],
341
+ )
342
+
343
+ babelHandleReference(options)
344
+ } else if (t.isVariableDeclarator(path.parentPath.node)) {
345
+ // createFileRoute({ ... })
346
+ const caller = resolveIdentifier(path, path.parentPath.node.init)
347
+
348
+ if (t.isCallExpression(caller)) {
349
+ const options = resolveIdentifier(path, caller.arguments[0])
350
+ babelHandleReference(options)
351
+ }
352
+ }
373
353
  },
374
- state,
375
- )
354
+ })
376
355
 
377
356
  /**
378
357
  * If the component for the route is being imported,
@@ -406,6 +385,7 @@ export function compileCodeSplitReferenceRoute(
406
385
  export function compileCodeSplitVirtualRoute(
407
386
  opts: ParseAstOptions & {
408
387
  splitTargets: Array<SplitRouteIdentNodes>
388
+ filename: string
409
389
  },
410
390
  ): GeneratorResult {
411
391
  const ast = parseAst(opts)
@@ -417,9 +397,7 @@ export function compileCodeSplitVirtualRoute(
417
397
 
418
398
  babel.traverse(ast, {
419
399
  Program: {
420
- enter(programPath, programState) {
421
- const state = programState as unknown as State
422
-
400
+ enter(programPath) {
423
401
  const trackedNodesToSplitByType: Record<
424
402
  SplitRouteIdentNodes,
425
403
  { node: t.Node | undefined; meta: SplitNodeMeta } | undefined
@@ -432,75 +410,85 @@ export function compileCodeSplitVirtualRoute(
432
410
  }
433
411
 
434
412
  // Find and track all the known split-able nodes
435
- programPath.traverse(
436
- {
437
- CallExpression: (path) => {
438
- if (!t.isIdentifier(path.node.callee)) {
439
- return
440
- }
441
-
442
- if (
443
- !(
444
- path.node.callee.name === 'createRoute' ||
445
- path.node.callee.name === 'createFileRoute'
446
- )
447
- ) {
448
- return
449
- }
413
+ programPath.traverse({
414
+ CallExpression: (path) => {
415
+ if (!t.isIdentifier(path.node.callee)) {
416
+ return
417
+ }
450
418
 
451
- if (t.isCallExpression(path.parentPath.node)) {
452
- const options = resolveIdentifier(
453
- path,
454
- path.parentPath.node.arguments[0],
455
- )
419
+ if (
420
+ !(
421
+ path.node.callee.name === 'createRoute' ||
422
+ path.node.callee.name === 'createFileRoute'
423
+ )
424
+ ) {
425
+ return
426
+ }
456
427
 
457
- if (t.isObjectExpression(options)) {
458
- options.properties.forEach((prop) => {
459
- if (t.isObjectProperty(prop)) {
460
- // do not use `intendedSplitNodes` here
461
- // since we have special considerations that need
462
- // to be accounted for like (not splitting exported identifiers)
463
- KNOWN_SPLIT_ROUTE_IDENTS.forEach((splitType) => {
464
- if (
465
- !t.isIdentifier(prop.key) ||
466
- prop.key.name !== splitType
467
- ) {
468
- return
469
- }
428
+ function babelHandleVirtual(options: t.Node | undefined) {
429
+ if (t.isObjectExpression(options)) {
430
+ options.properties.forEach((prop) => {
431
+ if (t.isObjectProperty(prop)) {
432
+ // do not use `intendedSplitNodes` here
433
+ // since we have special considerations that need
434
+ // to be accounted for like (not splitting exported identifiers)
435
+ KNOWN_SPLIT_ROUTE_IDENTS.forEach((splitType) => {
436
+ if (
437
+ !t.isIdentifier(prop.key) ||
438
+ prop.key.name !== splitType
439
+ ) {
440
+ return
441
+ }
470
442
 
471
- const value = prop.value
443
+ const value = prop.value
472
444
 
473
- let isExported = false
474
- if (t.isIdentifier(value)) {
475
- isExported = hasExport(ast, value)
476
- if (isExported) {
477
- knownExportedIdents.add(value.name)
478
- }
445
+ let isExported = false
446
+ if (t.isIdentifier(value)) {
447
+ isExported = hasExport(ast, value)
448
+ if (isExported) {
449
+ knownExportedIdents.add(value.name)
479
450
  }
451
+ }
480
452
 
481
- // If the node is exported, we need to remove
482
- // the export from the split file
483
- if (isExported && t.isIdentifier(value)) {
484
- removeExports(ast, value)
485
- } else {
486
- const meta = SPLIT_NODES_CONFIG.get(splitType)!
487
- trackedNodesToSplitByType[splitType] = {
488
- node: prop.value,
489
- meta,
490
- }
453
+ // If the node is exported, we need to remove
454
+ // the export from the split file
455
+ if (isExported && t.isIdentifier(value)) {
456
+ removeExports(ast, value)
457
+ } else {
458
+ const meta = SPLIT_NODES_CONFIG.get(splitType)!
459
+ trackedNodesToSplitByType[splitType] = {
460
+ node: prop.value,
461
+ meta,
491
462
  }
492
- })
493
- }
494
- })
463
+ }
464
+ })
465
+ }
466
+ })
495
467
 
496
- // Remove all of the options
497
- options.properties = []
498
- }
468
+ // Remove all of the options
469
+ options.properties = []
499
470
  }
500
- },
471
+ }
472
+
473
+ if (t.isCallExpression(path.parentPath.node)) {
474
+ // createFileRoute('/')({ ... })
475
+ const options = resolveIdentifier(
476
+ path,
477
+ path.parentPath.node.arguments[0],
478
+ )
479
+
480
+ babelHandleVirtual(options)
481
+ } else if (t.isVariableDeclarator(path.parentPath.node)) {
482
+ // createFileRoute({ ... })
483
+ const caller = resolveIdentifier(path, path.parentPath.node.init)
484
+
485
+ if (t.isCallExpression(caller)) {
486
+ const options = resolveIdentifier(path, caller.arguments[0])
487
+ babelHandleVirtual(options)
488
+ }
489
+ }
501
490
  },
502
- state,
503
- )
491
+ })
504
492
 
505
493
  // Start the transformation to only exported the intended split nodes
506
494
  intendedSplitNodes.forEach((SPLIT_TYPE) => {
@@ -841,7 +829,7 @@ function getImportSpecifierAndPathFromLocalName(
841
829
  }
842
830
 
843
831
  // Reusable function to get literal value or resolve variable to literal
844
- function resolveIdentifier(path: any, node: any) {
832
+ function resolveIdentifier(path: any, node: any): t.Node | undefined {
845
833
  if (t.isIdentifier(node)) {
846
834
  const binding = path.scope.getBinding(node.name)
847
835
  if (