@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
@@ -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,102 @@
1
+ import { generateFromAst, logDiff, parseAst } from '@tanstack/router-utils'
2
+ import babel from '@babel/core'
3
+ import * as template from '@babel/template'
4
+ import { getConfig } from './config'
5
+ import { debug, fileIsInRoutesDirectory } from './utils'
6
+ import type { Config } from './config'
7
+ import type { UnpluginFactory } from 'unplugin'
8
+
9
+ /**
10
+ * This plugin adds imports for createFileRoute and createLazyFileRoute to the file route.
11
+ */
12
+ export const unpluginRouteAutoImportFactory: UnpluginFactory<
13
+ Partial<Config> | undefined
14
+ > = (options = {}) => {
15
+ let ROOT: string = process.cwd()
16
+ let userConfig = options as Config
17
+
18
+ return {
19
+ name: 'router-autoimport-plugin',
20
+ enforce: 'pre',
21
+
22
+ transform(code, id) {
23
+ let routeType: 'createFileRoute' | 'createLazyFileRoute'
24
+ if (code.includes('export const Route = createFileRoute(')) {
25
+ routeType = 'createFileRoute'
26
+ } else if (code.includes('export const Route = createLazyFileRoute(')) {
27
+ routeType = 'createLazyFileRoute'
28
+ } else {
29
+ return null
30
+ }
31
+
32
+ const routerImportPath = `@tanstack/${userConfig.target}-router`
33
+
34
+ const ast = parseAst({ code })
35
+
36
+ let isCreateRouteFunctionImported = false as boolean
37
+
38
+ babel.traverse(ast, {
39
+ Program: {
40
+ enter(programPath) {
41
+ programPath.traverse({
42
+ ImportDeclaration(path) {
43
+ const importedSpecifiers = path.node.specifiers.map(
44
+ (specifier) => specifier.local.name,
45
+ )
46
+ if (
47
+ importedSpecifiers.includes(routeType) &&
48
+ path.node.source.value === routerImportPath
49
+ ) {
50
+ isCreateRouteFunctionImported = true
51
+ }
52
+ },
53
+ })
54
+ },
55
+ },
56
+ })
57
+
58
+ if (!isCreateRouteFunctionImported) {
59
+ if (debug) console.info('Adding autoimports to route ', id)
60
+
61
+ const autoImportStatement = template.statement(
62
+ `import { ${routeType} } from '${routerImportPath}'`,
63
+ )()
64
+ ast.program.body.unshift(autoImportStatement)
65
+
66
+ const result = generateFromAst(ast, {
67
+ sourceMaps: true,
68
+ filename: id,
69
+ sourceFileName: id,
70
+ })
71
+ if (debug) {
72
+ logDiff(code, result.code)
73
+ console.log('Output:\n', result.code + '\n\n')
74
+ }
75
+ return result
76
+ }
77
+
78
+ return null
79
+ },
80
+
81
+ transformInclude(id) {
82
+ return fileIsInRoutesDirectory(id, userConfig.routesDirectory)
83
+ },
84
+
85
+ vite: {
86
+ configResolved(config) {
87
+ ROOT = config.root
88
+ userConfig = getConfig(options, ROOT)
89
+ },
90
+ },
91
+
92
+ rspack() {
93
+ ROOT = process.cwd()
94
+ userConfig = getConfig(options, ROOT)
95
+ },
96
+
97
+ webpack() {
98
+ ROOT = process.cwd()
99
+ userConfig = getConfig(options, ROOT)
100
+ },
101
+ }
102
+ }
@@ -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
@@ -104,8 +87,6 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
104
87
 
105
88
  const fromCode = detectCodeSplitGroupingsFromRoute({
106
89
  code,
107
- root: ROOT,
108
- filename: id,
109
90
  })
110
91
 
111
92
  if (fromCode.groupings) {
@@ -139,11 +120,11 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
139
120
 
140
121
  const compiledReferenceRoute = compileCodeSplitReferenceRoute({
141
122
  code,
142
- root: ROOT,
143
- filename: id,
144
123
  runtimeEnv: isProduction ? 'prod' : 'dev',
145
124
  codeSplitGroupings: splitGroupings,
146
125
  targetFramework: userConfig.target,
126
+ filename: id,
127
+ id,
147
128
  })
148
129
 
149
130
  if (debug) {
@@ -178,7 +159,6 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
178
159
 
179
160
  const result = compileCodeSplitVirtualRoute({
180
161
  code,
181
- root: ROOT,
182
162
  filename: id,
183
163
  splitTargets: grouping,
184
164
  })
@@ -1,22 +1,32 @@
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
+ import { unpluginRouteAutoImportFactory } from './route-autoimport-plugin'
4
5
  import type { Config } from './config'
5
6
  import type { UnpluginFactory } from 'unplugin'
6
7
 
7
8
  export const unpluginRouterComposedFactory: UnpluginFactory<
8
9
  Partial<Config> | undefined
9
10
  > = (options = {}, meta) => {
10
- const routerGenerator = unpluginRouterGeneratorFactory(options, meta)
11
+ const getPlugin = (pluginFactory: UnpluginFactory<Partial<Config>>) => {
12
+ const plugin = pluginFactory(options, meta)
13
+ if (!Array.isArray(plugin)) {
14
+ return [plugin]
15
+ }
16
+ return plugin
17
+ }
18
+
19
+ const routerGenerator = getPlugin(unpluginRouterGeneratorFactory)
20
+ const routerCodeSplitter = getPlugin(unpluginRouterCodeSplitterFactory)
21
+ const routeAutoImport = getPlugin(unpluginRouteAutoImportFactory)
11
22
 
12
- const routerGeneratorOptions = Array.isArray(routerGenerator)
13
- ? routerGenerator
14
- : [routerGenerator]
23
+ const result = [...routerGenerator, ...routerCodeSplitter, ...routeAutoImport]
15
24
 
16
- const routerCodeSplitter = unpluginRouterCodeSplitterFactory(options, meta)
17
- const routerCodeSplitterOptions = Array.isArray(routerCodeSplitter)
18
- ? routerCodeSplitter
19
- : [routerCodeSplitter]
25
+ const isProduction = process.env.NODE_ENV === 'production'
20
26
 
21
- return [...routerGeneratorOptions, ...routerCodeSplitterOptions]
27
+ if (!isProduction && !options.autoCodeSplitting) {
28
+ const routerHmr = getPlugin(unpluginRouterHmrFactory)
29
+ result.push(...routerHmr)
30
+ }
31
+ return result
22
32
  }
@@ -82,12 +82,23 @@ export const unpluginRouterGeneratorFactory: UnpluginFactory<
82
82
  })
83
83
  },
84
84
  vite: {
85
- async configResolved(config) {
85
+ configResolved(config) {
86
86
  ROOT = config.root
87
87
  userConfig = getConfig(options, ROOT)
88
88
 
89
+ // if (config.command === 'serve') {
90
+ // await run(generate)
91
+ // }
92
+ },
93
+ async buildStart() {
94
+ if (this.environment.config.consumer === 'server') {
95
+ // When building in environment mode, we only need to generate routes
96
+ // for the client environment
97
+ return
98
+ }
89
99
  await run(generate)
90
100
  },
101
+ sharedDuringBuild: true,
91
102
  },
92
103
  rspack(compiler) {
93
104
  userConfig = getConfig(options, ROOT)
@@ -0,0 +1,65 @@
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 })
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
+ userConfig = getConfig(options, ROOT)
52
+ },
53
+ },
54
+
55
+ rspack() {
56
+ ROOT = process.cwd()
57
+ userConfig = getConfig(options, ROOT)
58
+ },
59
+
60
+ webpack() {
61
+ ROOT = process.cwd()
62
+ userConfig = getConfig(options, ROOT)
63
+ },
64
+ }
65
+ }
@@ -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
+ }
package/src/esbuild.ts CHANGED
@@ -37,13 +37,13 @@ const TanStackRouterCodeSplitterEsbuild = createEsbuildPlugin(
37
37
  * @example
38
38
  * ```ts
39
39
  * export default {
40
- * plugins: [TanStackRouterEsbuild()],
40
+ * plugins: [tanstackRouter()],
41
41
  * // ...
42
42
  * }
43
43
  * ```
44
44
  */
45
45
  const TanStackRouterEsbuild = createEsbuildPlugin(unpluginRouterComposedFactory)
46
-
46
+ const tanstackRouter = TanStackRouterEsbuild
47
47
  export default TanStackRouterEsbuild
48
48
 
49
49
  export {
@@ -51,6 +51,7 @@ export {
51
51
  TanStackRouterGeneratorEsbuild,
52
52
  TanStackRouterCodeSplitterEsbuild,
53
53
  TanStackRouterEsbuild,
54
+ tanstackRouter,
54
55
  }
55
56
 
56
57
  export type { Config }
package/src/rspack.ts CHANGED
@@ -47,7 +47,7 @@ const TanStackRouterCodeSplitterRspack = /* #__PURE__ */ createRspackPlugin(
47
47
  * // ...
48
48
  * tools: {
49
49
  * rspack: {
50
- * plugins: [TanStackRouterRspack()],
50
+ * plugins: [tanstackRouter()],
51
51
  * },
52
52
  * },
53
53
  * })
@@ -56,12 +56,13 @@ const TanStackRouterCodeSplitterRspack = /* #__PURE__ */ createRspackPlugin(
56
56
  const TanStackRouterRspack = /* #__PURE__ */ createRspackPlugin(
57
57
  unpluginRouterComposedFactory,
58
58
  )
59
-
59
+ const tanstackRouter = TanStackRouterRspack
60
60
  export default TanStackRouterRspack
61
61
  export {
62
62
  configSchema,
63
63
  TanStackRouterRspack,
64
64
  TanStackRouterGeneratorRspack,
65
65
  TanStackRouterCodeSplitterRspack,
66
+ tanstackRouter,
66
67
  }
67
68
  export type { Config }
package/src/vite.ts CHANGED
@@ -43,6 +43,7 @@ const TanStackRouterCodeSplitterVite = createVitePlugin(
43
43
  * ```
44
44
  */
45
45
  const TanStackRouterVite = createVitePlugin(unpluginRouterComposedFactory)
46
+ const tanstackRouter = TanStackRouterVite
46
47
 
47
48
  export default TanStackRouterVite
48
49
  export {
@@ -50,5 +51,7 @@ export {
50
51
  TanStackRouterGeneratorVite,
51
52
  TanStackRouterCodeSplitterVite,
52
53
  TanStackRouterVite,
54
+ tanstackRouter,
53
55
  }
56
+
54
57
  export type { Config }
package/src/webpack.ts CHANGED
@@ -37,7 +37,7 @@ const TanStackRouterCodeSplitterWebpack = /* #__PURE__ */ createWebpackPlugin(
37
37
  * ```ts
38
38
  * export default {
39
39
  * // ...
40
- * plugins: [TanStackRouterWebpack()],
40
+ * plugins: [tanstackRouter()],
41
41
  * }
42
42
  * ```
43
43
  */
@@ -45,11 +45,13 @@ const TanStackRouterWebpack = /* #__PURE__ */ createWebpackPlugin(
45
45
  unpluginRouterComposedFactory,
46
46
  )
47
47
 
48
+ const tanstackRouter = TanStackRouterWebpack
48
49
  export default TanStackRouterWebpack
49
50
  export {
50
51
  configSchema,
51
52
  TanStackRouterWebpack,
52
53
  TanStackRouterGeneratorWebpack,
53
54
  TanStackRouterCodeSplitterWebpack,
55
+ tanstackRouter,
54
56
  }
55
57
  export type { Config }