@tanstack/router-plugin 1.167.12 → 1.167.14

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 +14 -11
  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 +14 -11
  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 +36 -30
  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>
@@ -16,24 +22,15 @@ type AnyRouterWithPrivateMaps = AnyRouter & {
16
22
  routesById: Record<string, AnyRoute>
17
23
  routesByPath: Record<string, AnyRoute>
18
24
  stores: AnyRouter['stores'] & {
19
- cachedMatchStoresById: Map<
25
+ cachedMatchStores: Map<
20
26
  string,
21
- {
22
- setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void
23
- }
27
+ Pick<RouterWritableStore<AnyRouteMatch>, 'set'>
24
28
  >
25
- pendingMatchStoresById: Map<
29
+ pendingMatchStores: Map<
26
30
  string,
27
- {
28
- setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void
29
- }
30
- >
31
- activeMatchStoresById: Map<
32
- string,
33
- {
34
- setState: (updater: (prev: AnyRouteMatch) => AnyRouteMatch) => void
35
- }
31
+ Pick<RouterWritableStore<AnyRouteMatch>, 'set'>
36
32
  >
33
+ matchStores: Map<string, Pick<RouterWritableStore<AnyRouteMatch>, 'set'>>
37
34
  }
38
35
  }
39
36
 
@@ -59,7 +56,7 @@ function handleRouteUpdate(
59
56
  // handles hot-updating the function bodies of these components — our job
60
57
  // is only to update non-component route options (loader, head, etc.).
61
58
  // For code-split (splittable) routes, the lazyRouteComponent wrapper is
62
- // already cached in import.meta.hot.data so its identity is stable.
59
+ // already cached in the bundler hot data so its identity is stable.
63
60
  // For unsplittable routes (e.g. root routes), the component is a plain
64
61
  // function reference that gets recreated on every module re-execution,
65
62
  // so we must explicitly preserve the old reference.
@@ -95,9 +92,9 @@ function handleRouteUpdate(
95
92
  walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree)
96
93
 
97
94
  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)
95
+ const activeMatch = router.stores.matches.get().find(filter)
96
+ const pendingMatch = router.stores.pendingMatches.get().find(filter)
97
+ const cachedMatches = router.stores.cachedMatches.get().filter(filter)
101
98
 
102
99
  if (activeMatch || pendingMatch || cachedMatches.length > 0) {
103
100
  // Clear stale match data for removed route options BEFORE invalidating.
@@ -117,11 +114,11 @@ function handleRouteUpdate(
117
114
  router.batch(() => {
118
115
  for (const matchId of matchIds) {
119
116
  const store =
120
- router.stores.pendingMatchStoresById.get(matchId) ||
121
- router.stores.activeMatchStoresById.get(matchId) ||
122
- router.stores.cachedMatchStoresById.get(matchId)
117
+ router.stores.pendingMatchStores.get(matchId) ||
118
+ router.stores.matchStores.get(matchId) ||
119
+ router.stores.cachedMatchStores.get(matchId)
123
120
  if (store) {
124
- store.setState((prev) => {
121
+ store.set((prev) => {
125
122
  const next: AnyRouteMatchWithPrivateProps = { ...prev }
126
123
 
127
124
  if (removedKeys.has('loader')) {
@@ -159,15 +156,20 @@ function handleRouteUpdate(
159
156
 
160
157
  const handleRouteUpdateStr = handleRouteUpdate.toString()
161
158
 
162
- export function createRouteHmrStatement(stableRouteOptionKeys: Array<string>) {
159
+ export function createRouteHmrStatement(
160
+ stableRouteOptionKeys: Array<string>,
161
+ opts?: { hotExpression?: string },
162
+ ) {
163
163
  return template.statement(
164
164
  `
165
- if (import.meta.hot) {
166
- import.meta.hot.accept((newModule) => {
165
+ if (%%hotExpression%%) {
166
+ const hot = %%hotExpression%%
167
+ const hotData = hot.data ??= {}
168
+ hot.accept((newModule) => {
167
169
  if (Route && newModule && newModule.Route) {
168
- const routeId = import.meta.hot.data['tsr-route-id'] ?? Route.id
170
+ const routeId = hotData['tsr-route-id'] ?? Route.id
169
171
  if (routeId) {
170
- import.meta.hot.data['tsr-route-id'] = routeId
172
+ hotData['tsr-route-id'] = routeId
171
173
  }
172
174
  (${handleRouteUpdateStr.replace(
173
175
  /['"]__TSR_COMPONENT_TYPES__['"]/,
@@ -177,6 +179,10 @@ if (import.meta.hot) {
177
179
  })
178
180
  }
179
181
  `,
180
- { placeholderPattern: false },
181
- )()
182
+ {
183
+ syntacticPlaceholders: true,
184
+ },
185
+ )({
186
+ hotExpression: createHmrHotExpressionAst(opts?.hotExpression),
187
+ })
182
188
  }
@@ -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