@tanstack/router-plugin 1.120.7 → 1.120.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/cjs/core/code-splitter/compilers.cjs +3 -9
  2. package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
  3. package/dist/cjs/core/code-splitter/framework-options.cjs +4 -8
  4. package/dist/cjs/core/code-splitter/framework-options.cjs.map +1 -1
  5. package/dist/cjs/core/code-splitter/framework-options.d.cts +0 -2
  6. package/dist/cjs/core/route-hmr-statement.cjs +33 -0
  7. package/dist/cjs/core/route-hmr-statement.cjs.map +1 -0
  8. package/dist/cjs/core/route-hmr-statement.d.cts +1 -0
  9. package/dist/cjs/core/router-code-splitter-plugin.cjs +7 -13
  10. package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
  11. package/dist/cjs/core/router-composed-plugin.cjs +17 -5
  12. package/dist/cjs/core/router-composed-plugin.cjs.map +1 -1
  13. package/dist/cjs/core/router-hmr-plugin.cjs +52 -0
  14. package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -0
  15. package/dist/cjs/core/router-hmr-plugin.d.cts +8 -0
  16. package/dist/cjs/core/utils.cjs +12 -0
  17. package/dist/cjs/core/utils.cjs.map +1 -0
  18. package/dist/cjs/core/utils.d.cts +2 -0
  19. package/dist/esm/core/code-splitter/compilers.js +3 -9
  20. package/dist/esm/core/code-splitter/compilers.js.map +1 -1
  21. package/dist/esm/core/code-splitter/framework-options.d.ts +0 -2
  22. package/dist/esm/core/code-splitter/framework-options.js +4 -8
  23. package/dist/esm/core/code-splitter/framework-options.js.map +1 -1
  24. package/dist/esm/core/route-hmr-statement.d.ts +1 -0
  25. package/dist/esm/core/route-hmr-statement.js +16 -0
  26. package/dist/esm/core/route-hmr-statement.js.map +1 -0
  27. package/dist/esm/core/router-code-splitter-plugin.js +1 -7
  28. package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
  29. package/dist/esm/core/router-composed-plugin.js +17 -5
  30. package/dist/esm/core/router-composed-plugin.js.map +1 -1
  31. package/dist/esm/core/router-hmr-plugin.d.ts +8 -0
  32. package/dist/esm/core/router-hmr-plugin.js +52 -0
  33. package/dist/esm/core/router-hmr-plugin.js.map +1 -0
  34. package/dist/esm/core/utils.d.ts +2 -0
  35. package/dist/esm/core/utils.js +12 -0
  36. package/dist/esm/core/utils.js.map +1 -0
  37. package/package.json +4 -4
  38. package/src/core/code-splitter/compilers.ts +4 -12
  39. package/src/core/code-splitter/framework-options.ts +0 -6
  40. package/src/core/route-hmr-statement.ts +13 -0
  41. package/src/core/router-code-splitter-plugin.ts +1 -18
  42. package/src/core/router-composed-plugin.ts +18 -10
  43. package/src/core/router-hmr-plugin.ts +67 -0
  44. package/src/core/utils.ts +18 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/router-plugin",
3
- "version": "1.120.7",
3
+ "version": "1.120.9",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -100,9 +100,9 @@
100
100
  "chokidar": "^3.6.0",
101
101
  "unplugin": "^2.1.2",
102
102
  "zod": "^3.24.2",
103
- "@tanstack/router-core": "^1.120.7",
104
- "@tanstack/router-generator": "^1.120.7",
103
+ "@tanstack/router-core": "^1.120.9",
105
104
  "@tanstack/virtual-file-routes": "^1.115.0",
105
+ "@tanstack/router-generator": "^1.120.9",
106
106
  "@tanstack/router-utils": "^1.115.0"
107
107
  },
108
108
  "peerDependencies": {
@@ -110,7 +110,7 @@
110
110
  "vite": ">=5.0.0 || >=6.0.0",
111
111
  "vite-plugin-solid": "^2.11.2",
112
112
  "webpack": ">=5.92.0",
113
- "@tanstack/react-router": "^1.120.7"
113
+ "@tanstack/react-router": "^1.120.9"
114
114
  },
115
115
  "peerDependenciesMeta": {
116
116
  "@rsbuild/core": {
@@ -7,6 +7,7 @@ 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'
@@ -288,18 +289,9 @@ export function compileCodeSplitReferenceRoute(
288
289
  )()
289
290
  }
290
291
 
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
- ])
292
+ // add HMR handling
293
+ if (opts.runtimeEnv !== 'prod') {
294
+ programPath.pushContainer('body', routeHmrStatement)
303
295
  }
304
296
  }
305
297
 
@@ -4,9 +4,7 @@ type FrameworkOptions = {
4
4
  createFileRoute: string
5
5
  lazyFn: string
6
6
  lazyRouteComponent: string
7
- dummyHMRComponent: string
8
7
  }
9
- dummyHMRComponent: string
10
8
  }
11
9
 
12
10
  export function getFrameworkOptions(framework: string): FrameworkOptions {
@@ -20,9 +18,7 @@ export function getFrameworkOptions(framework: string): FrameworkOptions {
20
18
  createFileRoute: 'createFileRoute',
21
19
  lazyFn: 'lazyFn',
22
20
  lazyRouteComponent: 'lazyRouteComponent',
23
- dummyHMRComponent: 'TSRDummyComponent',
24
21
  },
25
- dummyHMRComponent: `export function TSRDummyComponent() { return null }`,
26
22
  }
27
23
  break
28
24
  case 'solid':
@@ -32,9 +28,7 @@ export function getFrameworkOptions(framework: string): FrameworkOptions {
32
28
  createFileRoute: 'createFileRoute',
33
29
  lazyFn: 'lazyFn',
34
30
  lazyRouteComponent: 'lazyRouteComponent',
35
- dummyHMRComponent: 'TSRDummyComponent',
36
31
  },
37
- dummyHMRComponent: `export function TSRDummyComponent() { return null }`,
38
32
  }
39
33
  break
40
34
  default:
@@ -0,0 +1,13 @@
1
+ import * as template from '@babel/template'
2
+
3
+ export const routeHmrStatement = template.statement(
4
+ `
5
+ if (import.meta.hot) {
6
+ import.meta.hot.accept((newModule) => {
7
+ if (newModule.Route && typeof newModule.Route.clone === 'function') {
8
+ newModule.Route.clone(Route)
9
+ }
10
+ })
11
+ }
12
+ `,
13
+ )()
@@ -3,7 +3,6 @@
3
3
  * https://github.com/TanStack/router/pull/3355
4
4
  */
5
5
 
6
- import { isAbsolute, join, normalize } from 'node:path'
7
6
  import { fileURLToPath, pathToFileURL } from 'node:url'
8
7
  import { logDiff } from '@tanstack/router-utils'
9
8
  import { getConfig, splitGroupingsSchema } from './config'
@@ -18,6 +17,7 @@ import {
18
17
  tsrSplit,
19
18
  } from './constants'
20
19
  import { decodeIdentifier } from './code-splitter/path-ids'
20
+ import { debug, fileIsInRoutesDirectory } from './utils'
21
21
  import type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'
22
22
 
23
23
  import type { Config } from './config'
@@ -27,27 +27,10 @@ import type {
27
27
  TransformResult as UnpluginTransformResult,
28
28
  } from 'unplugin'
29
29
 
30
- const debug =
31
- process.env.TSR_VITE_DEBUG &&
32
- ['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)
33
-
34
30
  function capitalizeFirst(str: string): string {
35
31
  return str.charAt(0).toUpperCase() + str.slice(1)
36
32
  }
37
33
 
38
- function fileIsInRoutesDirectory(
39
- filePath: string,
40
- routesDirectory: string,
41
- ): boolean {
42
- const routesDirectoryPath = isAbsolute(routesDirectory)
43
- ? routesDirectory
44
- : join(process.cwd(), routesDirectory)
45
-
46
- const path = normalize(filePath)
47
-
48
- return path.startsWith(routesDirectoryPath)
49
- }
50
-
51
34
  type BannedBeforeExternalPlugin = {
52
35
  identifier: string
53
36
  pkg: string
@@ -1,22 +1,30 @@
1
1
  import { unpluginRouterGeneratorFactory } from './router-generator-plugin'
2
2
  import { unpluginRouterCodeSplitterFactory } from './router-code-splitter-plugin'
3
-
3
+ import { unpluginRouterHmrFactory } from './router-hmr-plugin'
4
4
  import type { Config } from './config'
5
5
  import type { UnpluginFactory } from 'unplugin'
6
6
 
7
7
  export const unpluginRouterComposedFactory: UnpluginFactory<
8
8
  Partial<Config> | undefined
9
9
  > = (options = {}, meta) => {
10
- const routerGenerator = unpluginRouterGeneratorFactory(options, meta)
10
+ const getPlugin = (pluginFactory: UnpluginFactory<Partial<Config>>) => {
11
+ const plugin = pluginFactory(options, meta)
12
+ if (!Array.isArray(plugin)) {
13
+ return [plugin]
14
+ }
15
+ return plugin
16
+ }
17
+
18
+ const routerGenerator = getPlugin(unpluginRouterGeneratorFactory)
19
+ const routerCodeSplitter = getPlugin(unpluginRouterCodeSplitterFactory)
11
20
 
12
- const routerGeneratorOptions = Array.isArray(routerGenerator)
13
- ? routerGenerator
14
- : [routerGenerator]
21
+ const result = [...routerGenerator, ...routerCodeSplitter]
15
22
 
16
- const routerCodeSplitter = unpluginRouterCodeSplitterFactory(options, meta)
17
- const routerCodeSplitterOptions = Array.isArray(routerCodeSplitter)
18
- ? routerCodeSplitter
19
- : [routerCodeSplitter]
23
+ const isProduction = process.env.NODE_ENV === 'production'
20
24
 
21
- return [...routerGeneratorOptions, ...routerCodeSplitterOptions]
25
+ if (!isProduction && !options.autoCodeSplitting) {
26
+ const routerHmr = getPlugin(unpluginRouterHmrFactory)
27
+ result.push(...routerHmr)
28
+ }
29
+ return result
22
30
  }
@@ -0,0 +1,67 @@
1
+ import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'
2
+ import { getConfig } from './config'
3
+ import { routeHmrStatement } from './route-hmr-statement'
4
+ import { debug, fileIsInRoutesDirectory } from './utils'
5
+ import type { Config } from './config'
6
+ import type { UnpluginFactory } from 'unplugin'
7
+
8
+ /**
9
+ * This plugin adds HMR support for file routes.
10
+ * It is only added to the composed plugin in dev when autoCodeSplitting is disabled, since the code splitting plugin
11
+ * handles HMR for code-split routes itself.
12
+ */
13
+ export const unpluginRouterHmrFactory: UnpluginFactory<
14
+ Partial<Config> | undefined
15
+ > = (options = {}) => {
16
+ let ROOT: string = process.cwd()
17
+ let userConfig = options as Config
18
+
19
+ return {
20
+ name: 'router-hmr-plugin',
21
+ enforce: 'pre',
22
+
23
+ transform(code, id) {
24
+ if (!code.includes('export const Route = createFileRoute(')) {
25
+ return null
26
+ }
27
+
28
+ if (debug) console.info('Adding HMR handling to route ', id)
29
+
30
+ const ast = parseAst({ code, filename: id, root: ROOT })
31
+ ast.program.body.push(routeHmrStatement)
32
+ const result = generateFromAst(ast, {
33
+ sourceMaps: true,
34
+ filename: id,
35
+ sourceFileName: id,
36
+ })
37
+ if (debug) {
38
+ logDiff(code, result.code)
39
+ console.log('Output:\n', result.code + '\n\n')
40
+ }
41
+ return result
42
+ },
43
+
44
+ transformInclude(id) {
45
+ return fileIsInRoutesDirectory(id, userConfig.routesDirectory)
46
+ },
47
+
48
+ vite: {
49
+ configResolved(config) {
50
+ ROOT = config.root
51
+ config.mode
52
+
53
+ userConfig = getConfig(options, ROOT)
54
+ },
55
+ },
56
+
57
+ rspack() {
58
+ ROOT = process.cwd()
59
+ userConfig = getConfig(options, ROOT)
60
+ },
61
+
62
+ webpack() {
63
+ ROOT = process.cwd()
64
+ userConfig = getConfig(options, ROOT)
65
+ },
66
+ }
67
+ }
@@ -0,0 +1,18 @@
1
+ import { isAbsolute, join, normalize } from 'node:path'
2
+
3
+ export const debug =
4
+ process.env.TSR_VITE_DEBUG &&
5
+ ['true', 'router-plugin'].includes(process.env.TSR_VITE_DEBUG)
6
+
7
+ export function fileIsInRoutesDirectory(
8
+ filePath: string,
9
+ routesDirectory: string,
10
+ ): boolean {
11
+ const routesDirectoryPath = isAbsolute(routesDirectory)
12
+ ? routesDirectory
13
+ : join(process.cwd(), routesDirectory)
14
+
15
+ const path = normalize(filePath)
16
+
17
+ return path.startsWith(routesDirectoryPath)
18
+ }