@tanstack/router-plugin 1.167.11 → 1.167.13

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 (86) hide show
  1. package/dist/cjs/core/code-splitter/compilers.cjs +5 -4
  2. package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
  3. package/dist/cjs/core/code-splitter/compilers.d.cts +2 -10
  4. package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs +2 -2
  5. package/dist/cjs/core/code-splitter/plugins/framework-plugins.cjs.map +1 -1
  6. package/dist/cjs/core/code-splitter/plugins/framework-plugins.d.cts +1 -0
  7. package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.cjs +12 -6
  8. package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.cjs.map +1 -1
  9. package/dist/cjs/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.cts +3 -1
  10. package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.cjs +12 -7
  11. package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.cjs.map +1 -1
  12. package/dist/cjs/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.cts +3 -1
  13. package/dist/cjs/core/code-splitter/plugins.d.cts +2 -0
  14. package/dist/cjs/core/config.cjs +4 -1
  15. package/dist/cjs/core/config.cjs.map +1 -1
  16. package/dist/cjs/core/config.d.cts +25 -0
  17. package/dist/cjs/core/hmr-hot-expression.cjs +27 -0
  18. package/dist/cjs/core/hmr-hot-expression.cjs.map +1 -0
  19. package/dist/cjs/core/hmr-hot-expression.d.cts +6 -0
  20. package/dist/cjs/core/route-autoimport-plugin.cjs +2 -2
  21. package/dist/cjs/core/route-hmr-statement.cjs +13 -10
  22. package/dist/cjs/core/route-hmr-statement.cjs.map +1 -1
  23. package/dist/cjs/core/route-hmr-statement.d.cts +3 -1
  24. package/dist/cjs/core/router-code-splitter-plugin.cjs +7 -10
  25. package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
  26. package/dist/cjs/core/router-hmr-plugin.cjs +6 -2
  27. package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -1
  28. package/dist/cjs/esbuild.d.cts +12 -0
  29. package/dist/cjs/index.d.cts +1 -1
  30. package/dist/cjs/rspack.cjs +3 -2
  31. package/dist/cjs/rspack.cjs.map +1 -1
  32. package/dist/cjs/rspack.d.cts +6 -135
  33. package/dist/cjs/vite.d.cts +15 -0
  34. package/dist/cjs/webpack.cjs +3 -2
  35. package/dist/cjs/webpack.cjs.map +1 -1
  36. package/dist/cjs/webpack.d.cts +6 -135
  37. package/dist/esm/core/code-splitter/compilers.d.ts +2 -10
  38. package/dist/esm/core/code-splitter/compilers.js +4 -3
  39. package/dist/esm/core/code-splitter/compilers.js.map +1 -1
  40. package/dist/esm/core/code-splitter/plugins/framework-plugins.d.ts +1 -0
  41. package/dist/esm/core/code-splitter/plugins/framework-plugins.js +2 -2
  42. package/dist/esm/core/code-splitter/plugins/framework-plugins.js.map +1 -1
  43. package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.d.ts +3 -1
  44. package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.js +11 -5
  45. package/dist/esm/core/code-splitter/plugins/react-refresh-ignored-route-exports.js.map +1 -1
  46. package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.d.ts +3 -1
  47. package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.js +11 -6
  48. package/dist/esm/core/code-splitter/plugins/react-stable-hmr-split-route-components.js.map +1 -1
  49. package/dist/esm/core/code-splitter/plugins.d.ts +2 -0
  50. package/dist/esm/core/config.d.ts +25 -0
  51. package/dist/esm/core/config.js +4 -1
  52. package/dist/esm/core/config.js.map +1 -1
  53. package/dist/esm/core/hmr-hot-expression.d.ts +6 -0
  54. package/dist/esm/core/hmr-hot-expression.js +23 -0
  55. package/dist/esm/core/hmr-hot-expression.js.map +1 -0
  56. package/dist/esm/core/route-autoimport-plugin.js +1 -1
  57. package/dist/esm/core/route-hmr-statement.d.ts +3 -1
  58. package/dist/esm/core/route-hmr-statement.js +13 -10
  59. package/dist/esm/core/route-hmr-statement.js.map +1 -1
  60. package/dist/esm/core/router-code-splitter-plugin.js +7 -10
  61. package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
  62. package/dist/esm/core/router-hmr-plugin.js +6 -2
  63. package/dist/esm/core/router-hmr-plugin.js.map +1 -1
  64. package/dist/esm/esbuild.d.ts +12 -0
  65. package/dist/esm/index.d.ts +1 -1
  66. package/dist/esm/rspack.d.ts +6 -135
  67. package/dist/esm/rspack.js +3 -2
  68. package/dist/esm/rspack.js.map +1 -1
  69. package/dist/esm/vite.d.ts +15 -0
  70. package/dist/esm/webpack.d.ts +6 -135
  71. package/dist/esm/webpack.js +3 -2
  72. package/dist/esm/webpack.js.map +1 -1
  73. package/package.json +4 -4
  74. package/src/core/code-splitter/compilers.ts +8 -12
  75. package/src/core/code-splitter/plugins/framework-plugins.ts +7 -2
  76. package/src/core/code-splitter/plugins/react-refresh-ignored-route-exports.ts +12 -4
  77. package/src/core/code-splitter/plugins/react-stable-hmr-split-route-components.ts +14 -5
  78. package/src/core/code-splitter/plugins.ts +2 -0
  79. package/src/core/config.ts +9 -0
  80. package/src/core/hmr-hot-expression.ts +31 -0
  81. package/src/core/route-hmr-statement.ts +31 -22
  82. package/src/core/router-code-splitter-plugin.ts +8 -14
  83. package/src/core/router-hmr-plugin.ts +10 -1
  84. package/src/index.ts +1 -0
  85. package/src/rspack.ts +17 -2
  86. package/src/webpack.ts +17 -2
@@ -72,6 +72,10 @@ export type CodeSplittingOptions = {
72
72
  addHmr?: boolean
73
73
  }
74
74
 
75
+ export type HmrOptions = {
76
+ hotExpression?: string
77
+ }
78
+
75
79
  const codeSplittingOptionsSchema = z.object({
76
80
  splitBehavior: z.function().optional(),
77
81
  defaultBehavior: splitGroupingsSchema.optional(),
@@ -93,6 +97,11 @@ export const configSchema = generatorConfigSchema.extend({
93
97
  .optional(),
94
98
  plugin: z
95
99
  .object({
100
+ hmr: z
101
+ .object({
102
+ hotExpression: z.string().optional(),
103
+ })
104
+ .optional(),
96
105
  vite: z
97
106
  .object({
98
107
  environmentName: z.string().optional(),
@@ -0,0 +1,31 @@
1
+ import * as template from '@babel/template'
2
+ import type * as t from '@babel/types'
3
+ import type { Config } from './config'
4
+
5
+ export const DEFAULT_HMR_HOT_EXPRESSION = 'import.meta.hot'
6
+
7
+ export function resolveHmrHotExpression(hotExpression?: string): string {
8
+ return hotExpression ?? DEFAULT_HMR_HOT_EXPRESSION
9
+ }
10
+
11
+ export function createHmrHotExpressionAst(
12
+ hotExpression?: string,
13
+ ): t.Expression {
14
+ return template.expression.ast(resolveHmrHotExpression(hotExpression))
15
+ }
16
+
17
+ export function withHmrHotExpression(
18
+ config: Partial<Config> | undefined,
19
+ hotExpression: string,
20
+ ): Partial<Config> {
21
+ return {
22
+ ...config,
23
+ plugin: {
24
+ ...config?.plugin,
25
+ hmr: {
26
+ ...config?.plugin?.hmr,
27
+ hotExpression: config?.plugin?.hmr?.hotExpression ?? hotExpression,
28
+ },
29
+ },
30
+ }
31
+ }
@@ -1,5 +1,11 @@
1
1
  import * as template from '@babel/template'
2
- import type { AnyRoute, AnyRouteMatch, AnyRouter } from '@tanstack/router-core'
2
+ import { createHmrHotExpressionAst } from './hmr-hot-expression'
3
+ import type {
4
+ AnyRoute,
5
+ AnyRouteMatch,
6
+ AnyRouter,
7
+ RouterWritableStore,
8
+ } from '@tanstack/router-core'
3
9
 
4
10
  type AnyRouteWithPrivateProps = AnyRoute & {
5
11
  options: Record<string, unknown>
@@ -18,21 +24,15 @@ type AnyRouterWithPrivateMaps = AnyRouter & {
18
24
  stores: AnyRouter['stores'] & {
19
25
  cachedMatchStoresById: Map<
20
26
  string,
21
- {
22
- setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void
23
- }
27
+ Pick<RouterWritableStore<AnyRouteMatch>, 'set'>
24
28
  >
25
29
  pendingMatchStoresById: Map<
26
30
  string,
27
- {
28
- setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void
29
- }
31
+ Pick<RouterWritableStore<AnyRouteMatch>, 'set'>
30
32
  >
31
33
  activeMatchStoresById: Map<
32
34
  string,
33
- {
34
- setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void
35
- }
35
+ Pick<RouterWritableStore<AnyRouteMatch>, 'set'>
36
36
  >
37
37
  }
38
38
  }
@@ -59,7 +59,7 @@ function handleRouteUpdate(
59
59
  // handles hot-updating the function bodies of these components — our job
60
60
  // is only to update non-component route options (loader, head, etc.).
61
61
  // For code-split (splittable) routes, the lazyRouteComponent wrapper is
62
- // already cached in import.meta.hot.data so its identity is stable.
62
+ // already cached in the bundler hot data so its identity is stable.
63
63
  // For unsplittable routes (e.g. root routes), the component is a plain
64
64
  // function reference that gets recreated on every module re-execution,
65
65
  // so we must explicitly preserve the old reference.
@@ -95,9 +95,9 @@ function handleRouteUpdate(
95
95
  walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree)
96
96
 
97
97
  const filter = (m: AnyRouteMatch) => m.routeId === oldRoute.id
98
- const activeMatch = router.stores.activeMatchesSnapshot.state.find(filter)
99
- const pendingMatch = router.stores.pendingMatchesSnapshot.state.find(filter)
100
- const cachedMatches = router.stores.cachedMatchesSnapshot.state.filter(filter)
98
+ const activeMatch = router.stores.activeMatchesSnapshot.get().find(filter)
99
+ const pendingMatch = router.stores.pendingMatchesSnapshot.get().find(filter)
100
+ const cachedMatches = router.stores.cachedMatchesSnapshot.get().filter(filter)
101
101
 
102
102
  if (activeMatch || pendingMatch || cachedMatches.length > 0) {
103
103
  // Clear stale match data for removed route options BEFORE invalidating.
@@ -121,7 +121,7 @@ function handleRouteUpdate(
121
121
  router.stores.activeMatchStoresById.get(matchId) ||
122
122
  router.stores.cachedMatchStoresById.get(matchId)
123
123
  if (store) {
124
- store.setState((prev) => {
124
+ store.set((prev) => {
125
125
  const next: AnyRouteMatchWithPrivateProps = { ...prev }
126
126
 
127
127
  if (removedKeys.has('loader')) {
@@ -159,15 +159,20 @@ function handleRouteUpdate(
159
159
 
160
160
  const handleRouteUpdateStr = handleRouteUpdate.toString()
161
161
 
162
- export function createRouteHmrStatement(stableRouteOptionKeys: Array<string>) {
162
+ export function createRouteHmrStatement(
163
+ stableRouteOptionKeys: Array<string>,
164
+ opts?: { hotExpression?: string },
165
+ ) {
163
166
  return template.statement(
164
167
  `
165
- if (import.meta.hot) {
166
- import.meta.hot.accept((newModule) => {
168
+ if (%%hotExpression%%) {
169
+ const hot = %%hotExpression%%
170
+ const hotData = hot.data ??= {}
171
+ hot.accept((newModule) => {
167
172
  if (Route && newModule && newModule.Route) {
168
- const routeId = import.meta.hot.data['tsr-route-id'] ?? Route.id
173
+ const routeId = hotData['tsr-route-id'] ?? Route.id
169
174
  if (routeId) {
170
- import.meta.hot.data['tsr-route-id'] = routeId
175
+ hotData['tsr-route-id'] = routeId
171
176
  }
172
177
  (${handleRouteUpdateStr.replace(
173
178
  /['"]__TSR_COMPONENT_TYPES__['"]/,
@@ -177,6 +182,10 @@ if (import.meta.hot) {
177
182
  })
178
183
  }
179
184
  `,
180
- { placeholderPattern: false },
181
- )()
185
+ {
186
+ syntacticPlaceholders: true,
187
+ },
188
+ )({
189
+ hotExpression: createHmrHotExpressionAst(opts?.hotExpression),
190
+ })
182
191
  }
@@ -6,6 +6,7 @@
6
6
  import { fileURLToPath, pathToFileURL } from 'node:url'
7
7
  import { logDiff } from '@tanstack/router-utils'
8
8
  import { getConfig, splitGroupingsSchema } from './config'
9
+ import { resolveHmrHotExpression } from './hmr-hot-expression'
9
10
  import {
10
11
  compileCodeSplitReferenceRoute,
11
12
  compileCodeSplitSharedRoute,
@@ -158,6 +159,9 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
158
159
 
159
160
  const addHmr =
160
161
  (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction
162
+ const hmrHotExpression = resolveHmrHotExpression(
163
+ userConfig.plugin?.hmr?.hotExpression,
164
+ )
161
165
 
162
166
  const compiledReferenceRoute = compileCodeSplitReferenceRoute({
163
167
  code,
@@ -169,10 +173,12 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
169
173
  ? new Set(userConfig.codeSplittingOptions.deleteNodes)
170
174
  : undefined,
171
175
  addHmr,
176
+ hmrHotExpression,
172
177
  sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,
173
178
  compilerPlugins: getReferenceRouteCompilerPlugins({
174
179
  targetFramework: userConfig.target,
175
180
  addHmr,
181
+ hmrHotExpression,
176
182
  }),
177
183
  })
178
184
 
@@ -317,26 +323,14 @@ export const unpluginRouterCodeSplitterFactory: UnpluginFactory<
317
323
  },
318
324
  },
319
325
 
320
- rspack(compiler) {
326
+ rspack() {
321
327
  ROOT = process.cwd()
322
328
  initUserConfig()
323
-
324
- if (compiler.options.mode === 'production') {
325
- compiler.hooks.done.tap(PLUGIN_NAME, () => {
326
- console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')
327
- })
328
- }
329
329
  },
330
330
 
331
- webpack(compiler) {
331
+ webpack() {
332
332
  ROOT = process.cwd()
333
333
  initUserConfig()
334
-
335
- if (compiler.options.mode === 'production') {
336
- compiler.hooks.done.tap(PLUGIN_NAME, () => {
337
- console.info('✅ ' + PLUGIN_NAME + ': code-splitting done!')
338
- })
339
- }
340
334
  },
341
335
  },
342
336
  {
@@ -4,6 +4,7 @@ import { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framew
4
4
  import { createRouteHmrStatement } from './route-hmr-statement'
5
5
  import { debug, normalizePath } from './utils'
6
6
  import { getConfig } from './config'
7
+ import { resolveHmrHotExpression } from './hmr-hot-expression'
7
8
  import type { UnpluginFactory } from 'unplugin'
8
9
  import type { Config } from './config'
9
10
 
@@ -43,16 +44,22 @@ export const unpluginRouterHmrFactory: UnpluginFactory<
43
44
 
44
45
  if (debug) console.info('Adding HMR handling to route ', normalizedId)
45
46
 
47
+ const hmrHotExpression = resolveHmrHotExpression(
48
+ userConfig.plugin?.hmr?.hotExpression,
49
+ )
50
+
46
51
  if (userConfig.target === 'react') {
47
52
  const compilerPlugins = getReferenceRouteCompilerPlugins({
48
53
  targetFramework: 'react',
49
54
  addHmr: true,
55
+ hmrHotExpression,
50
56
  })
51
57
  const compiled = compileCodeSplitReferenceRoute({
52
58
  code,
53
59
  filename: normalizedId,
54
60
  id: normalizedId,
55
61
  addHmr: true,
62
+ hmrHotExpression,
56
63
  codeSplitGroupings: [],
57
64
  targetFramework: 'react',
58
65
  compilerPlugins,
@@ -69,7 +76,9 @@ export const unpluginRouterHmrFactory: UnpluginFactory<
69
76
  }
70
77
 
71
78
  const ast = parseAst({ code })
72
- ast.program.body.push(createRouteHmrStatement([]))
79
+ ast.program.body.push(
80
+ createRouteHmrStatement([], { hotExpression: hmrHotExpression }),
81
+ )
73
82
  const result = generateFromAst(ast, {
74
83
  sourceMaps: true,
75
84
  filename: normalizedId,
package/src/index.ts CHANGED
@@ -7,6 +7,7 @@ export type {
7
7
  ConfigOutput,
8
8
  CodeSplittingOptions,
9
9
  DeletableNodes,
10
+ HmrOptions,
10
11
  } from './core/config'
11
12
  export {
12
13
  tsrSplit,
package/src/rspack.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createRspackPlugin } from 'unplugin'
2
2
 
3
3
  import { configSchema } from './core/config'
4
+ import { withHmrHotExpression } from './core/hmr-hot-expression'
4
5
  import { unpluginRouterCodeSplitterFactory } from './core/router-code-splitter-plugin'
5
6
  import { unpluginRouterGeneratorFactory } from './core/router-generator-plugin'
6
7
  import { unpluginRouterComposedFactory } from './core/router-composed-plugin'
@@ -37,7 +38,14 @@ const TanStackRouterGeneratorRspack = /* #__PURE__ */ createRspackPlugin(
37
38
  * ```
38
39
  */
39
40
  const TanStackRouterCodeSplitterRspack = /* #__PURE__ */ createRspackPlugin(
40
- unpluginRouterCodeSplitterFactory,
41
+ (options, meta) =>
42
+ unpluginRouterCodeSplitterFactory(
43
+ withHmrHotExpression(
44
+ options as Partial<Config> | undefined,
45
+ 'import.meta.webpackHot',
46
+ ),
47
+ meta,
48
+ ),
41
49
  )
42
50
 
43
51
  /**
@@ -54,7 +62,14 @@ const TanStackRouterCodeSplitterRspack = /* #__PURE__ */ createRspackPlugin(
54
62
  * ```
55
63
  */
56
64
  const TanStackRouterRspack = /* #__PURE__ */ createRspackPlugin(
57
- unpluginRouterComposedFactory,
65
+ (options, meta) =>
66
+ unpluginRouterComposedFactory(
67
+ withHmrHotExpression(
68
+ options as Partial<Config> | undefined,
69
+ 'import.meta.webpackHot',
70
+ ),
71
+ meta,
72
+ ),
58
73
  )
59
74
  const tanstackRouter = TanStackRouterRspack
60
75
  export default TanStackRouterRspack
package/src/webpack.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { createWebpackPlugin } from 'unplugin'
2
2
 
3
3
  import { configSchema } from './core/config'
4
+ import { withHmrHotExpression } from './core/hmr-hot-expression'
4
5
  import { unpluginRouterCodeSplitterFactory } from './core/router-code-splitter-plugin'
5
6
  import { unpluginRouterGeneratorFactory } from './core/router-generator-plugin'
6
7
  import { unpluginRouterComposedFactory } from './core/router-composed-plugin'
@@ -29,7 +30,14 @@ const TanStackRouterGeneratorWebpack = /* #__PURE__ */ createWebpackPlugin(
29
30
  * ```
30
31
  */
31
32
  const TanStackRouterCodeSplitterWebpack = /* #__PURE__ */ createWebpackPlugin(
32
- unpluginRouterCodeSplitterFactory,
33
+ (options, meta) =>
34
+ unpluginRouterCodeSplitterFactory(
35
+ withHmrHotExpression(
36
+ options as Partial<Config> | undefined,
37
+ 'import.meta.webpackHot',
38
+ ),
39
+ meta,
40
+ ),
33
41
  )
34
42
 
35
43
  /**
@@ -42,7 +50,14 @@ const TanStackRouterCodeSplitterWebpack = /* #__PURE__ */ createWebpackPlugin(
42
50
  * ```
43
51
  */
44
52
  const TanStackRouterWebpack = /* #__PURE__ */ createWebpackPlugin(
45
- unpluginRouterComposedFactory,
53
+ (options, meta) =>
54
+ unpluginRouterComposedFactory(
55
+ withHmrHotExpression(
56
+ options as Partial<Config> | undefined,
57
+ 'import.meta.webpackHot',
58
+ ),
59
+ meta,
60
+ ),
46
61
  )
47
62
 
48
63
  const tanstackRouter = TanStackRouterWebpack