@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,9 @@ import * as template from "@babel/template";
4
4
  import { findReferencedIdentifiers, deadCodeElimination } from "babel-dead-code-elimination";
5
5
  import { parseAst, generateFromAst } from "@tanstack/router-utils";
6
6
  import { tsrSplit } from "../constants.js";
7
+ import { routeHmrStatement } from "../route-hmr-statement.js";
7
8
  import { createIdentifier } from "./path-ids.js";
8
9
  import { getFrameworkOptions } from "./framework-options.js";
9
- process.env.TSR_VITE_DEBUG;
10
10
  const SPLIT_NODES_CONFIG = /* @__PURE__ */ new Map([
11
11
  [
12
12
  "loader",
@@ -99,164 +99,160 @@ function compileCodeSplitReferenceRoute(opts) {
99
99
  const LAZY_FN_IDENT = frameworkOptions.idents.lazyFn;
100
100
  babel.traverse(ast, {
101
101
  Program: {
102
- enter(programPath, programState) {
103
- const state = programState;
102
+ enter(programPath) {
104
103
  const removableImportPaths = /* @__PURE__ */ new Set([]);
105
- programPath.traverse(
106
- {
107
- CallExpression: (path) => {
108
- if (!t.isIdentifier(path.node.callee)) {
109
- return;
110
- }
111
- if (!(path.node.callee.name === "createRoute" || path.node.callee.name === "createFileRoute")) {
112
- return;
113
- }
114
- if (t.isCallExpression(path.parentPath.node)) {
115
- const options = resolveIdentifier(
116
- path,
117
- path.parentPath.node.arguments[0]
118
- );
119
- const hasImportedOrDefinedIdentifier = (name) => {
120
- return programPath.scope.hasBinding(name);
121
- };
122
- if (t.isObjectExpression(options)) {
123
- options.properties.forEach((prop) => {
124
- if (t.isObjectProperty(prop)) {
125
- if (t.isIdentifier(prop.key)) {
126
- const codeSplitGroupingByKey = findIndexForSplitNode(
127
- prop.key.name
128
- );
129
- if (codeSplitGroupingByKey === -1) {
130
- return;
104
+ programPath.traverse({
105
+ CallExpression: (path) => {
106
+ if (!t.isIdentifier(path.node.callee)) {
107
+ return;
108
+ }
109
+ if (!(path.node.callee.name === "createRoute" || path.node.callee.name === "createFileRoute")) {
110
+ return;
111
+ }
112
+ function babelHandleReference(routeOptions) {
113
+ const hasImportedOrDefinedIdentifier = (name) => {
114
+ return programPath.scope.hasBinding(name);
115
+ };
116
+ if (t.isObjectExpression(routeOptions)) {
117
+ routeOptions.properties.forEach((prop) => {
118
+ if (t.isObjectProperty(prop)) {
119
+ if (t.isIdentifier(prop.key)) {
120
+ const codeSplitGroupingByKey = findIndexForSplitNode(
121
+ prop.key.name
122
+ );
123
+ if (codeSplitGroupingByKey === -1) {
124
+ return;
125
+ }
126
+ const codeSplitGroup = [
127
+ ...new Set(
128
+ opts.codeSplitGroupings[codeSplitGroupingByKey]
129
+ )
130
+ ];
131
+ const key = prop.key.name;
132
+ const isNodeConfigAvailable = SPLIT_NODES_CONFIG.has(
133
+ key
134
+ );
135
+ if (!isNodeConfigAvailable) {
136
+ return;
137
+ }
138
+ const splitNodeMeta = SPLIT_NODES_CONFIG.get(key);
139
+ const splitUrl = addSplitSearchParamToFilename(
140
+ opts.filename,
141
+ codeSplitGroup
142
+ );
143
+ if (splitNodeMeta.splitStrategy === "lazyRouteComponent") {
144
+ const value = prop.value;
145
+ let shouldSplit = true;
146
+ if (t.isIdentifier(value)) {
147
+ const existingImportPath = getImportSpecifierAndPathFromLocalName(
148
+ programPath,
149
+ value.name
150
+ ).path;
151
+ if (existingImportPath) {
152
+ removableImportPaths.add(existingImportPath);
153
+ }
154
+ const isExported = hasExport(ast, value);
155
+ shouldSplit = !isExported;
156
+ if (shouldSplit) {
157
+ removeIdentifierLiteral(path, value);
158
+ }
131
159
  }
132
- const codeSplitGroup = [
133
- ...new Set(
134
- opts.codeSplitGroupings[codeSplitGroupingByKey]
135
- )
136
- ];
137
- const key = prop.key.name;
138
- const isNodeConfigAvailable = SPLIT_NODES_CONFIG.has(
139
- key
140
- );
141
- if (!isNodeConfigAvailable) {
160
+ if (!shouldSplit) {
142
161
  return;
143
162
  }
144
- const splitNodeMeta = SPLIT_NODES_CONFIG.get(
145
- key
146
- );
147
- const splitUrl = addSplitSearchParamToFilename(
148
- opts.filename,
149
- codeSplitGroup
150
- );
151
- if (splitNodeMeta.splitStrategy === "lazyRouteComponent") {
152
- const value = prop.value;
153
- let shouldSplit = true;
154
- if (t.isIdentifier(value)) {
155
- const existingImportPath = getImportSpecifierAndPathFromLocalName(
156
- programPath,
157
- value.name
158
- ).path;
159
- if (existingImportPath) {
160
- removableImportPaths.add(existingImportPath);
161
- }
162
- const isExported = hasExport(ast, value);
163
- shouldSplit = !isExported;
164
- if (shouldSplit) {
165
- removeIdentifierLiteral(path, value);
166
- }
167
- }
168
- if (!shouldSplit) {
169
- return;
170
- }
171
- if (!hasImportedOrDefinedIdentifier(
172
- LAZY_ROUTE_COMPONENT_IDENT
173
- )) {
174
- programPath.unshiftContainer("body", [
175
- template.statement(
176
- `import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`
177
- )()
178
- ]);
179
- }
180
- if (!hasImportedOrDefinedIdentifier(
181
- splitNodeMeta.localImporterIdent
182
- )) {
183
- programPath.unshiftContainer("body", [
184
- template.statement(
185
- `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`
186
- )()
187
- ]);
188
- }
189
- if (key === "component") {
190
- prop.value = template.expression(
191
- `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}', () => Route.ssr)`
192
- )();
193
- } else {
194
- prop.value = template.expression(
195
- `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`
196
- )();
197
- }
198
- if (opts.runtimeEnv !== "prod" && // only in development
199
- !hasImportedOrDefinedIdentifier(
200
- frameworkOptions.idents.dummyHMRComponent
201
- )) {
202
- programPath.pushContainer("body", [
203
- template.statement(
204
- frameworkOptions.dummyHMRComponent
205
- )()
206
- ]);
207
- }
163
+ if (!hasImportedOrDefinedIdentifier(
164
+ LAZY_ROUTE_COMPONENT_IDENT
165
+ )) {
166
+ programPath.unshiftContainer("body", [
167
+ template.statement(
168
+ `import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`
169
+ )()
170
+ ]);
208
171
  }
209
- if (splitNodeMeta.splitStrategy === "lazyFn") {
210
- const value = prop.value;
211
- let shouldSplit = true;
212
- if (t.isIdentifier(value)) {
213
- const existingImportPath = getImportSpecifierAndPathFromLocalName(
214
- programPath,
215
- value.name
216
- ).path;
217
- if (existingImportPath) {
218
- removableImportPaths.add(existingImportPath);
219
- }
220
- const isExported = hasExport(ast, value);
221
- shouldSplit = !isExported;
222
- if (shouldSplit) {
223
- removeIdentifierLiteral(path, value);
224
- }
225
- }
226
- if (!shouldSplit) {
227
- return;
228
- }
229
- if (!hasImportedOrDefinedIdentifier(LAZY_FN_IDENT)) {
230
- programPath.unshiftContainer(
231
- "body",
232
- template.smart(
233
- `import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`
234
- )()
235
- );
236
- }
237
- if (!hasImportedOrDefinedIdentifier(
238
- splitNodeMeta.localImporterIdent
239
- )) {
240
- programPath.unshiftContainer("body", [
241
- template.statement(
242
- `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`
243
- )()
244
- ]);
245
- }
172
+ if (!hasImportedOrDefinedIdentifier(
173
+ splitNodeMeta.localImporterIdent
174
+ )) {
175
+ programPath.unshiftContainer("body", [
176
+ template.statement(
177
+ `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`
178
+ )()
179
+ ]);
180
+ }
181
+ if (key === "component") {
246
182
  prop.value = template.expression(
247
- `${LAZY_FN_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`
183
+ `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}', () => Route.ssr)`
248
184
  )();
185
+ } else {
186
+ prop.value = template.expression(
187
+ `${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`
188
+ )();
189
+ }
190
+ if (opts.runtimeEnv !== "prod") {
191
+ programPath.pushContainer("body", routeHmrStatement);
192
+ }
193
+ }
194
+ if (splitNodeMeta.splitStrategy === "lazyFn") {
195
+ const value = prop.value;
196
+ let shouldSplit = true;
197
+ if (t.isIdentifier(value)) {
198
+ const existingImportPath = getImportSpecifierAndPathFromLocalName(
199
+ programPath,
200
+ value.name
201
+ ).path;
202
+ if (existingImportPath) {
203
+ removableImportPaths.add(existingImportPath);
204
+ }
205
+ const isExported = hasExport(ast, value);
206
+ shouldSplit = !isExported;
207
+ if (shouldSplit) {
208
+ removeIdentifierLiteral(path, value);
209
+ }
210
+ }
211
+ if (!shouldSplit) {
212
+ return;
213
+ }
214
+ if (!hasImportedOrDefinedIdentifier(LAZY_FN_IDENT)) {
215
+ programPath.unshiftContainer(
216
+ "body",
217
+ template.smart(
218
+ `import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`
219
+ )()
220
+ );
249
221
  }
222
+ if (!hasImportedOrDefinedIdentifier(
223
+ splitNodeMeta.localImporterIdent
224
+ )) {
225
+ programPath.unshiftContainer("body", [
226
+ template.statement(
227
+ `const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`
228
+ )()
229
+ ]);
230
+ }
231
+ prop.value = template.expression(
232
+ `${LAZY_FN_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`
233
+ )();
250
234
  }
251
235
  }
252
- programPath.scope.crawl();
253
- });
254
- }
236
+ }
237
+ programPath.scope.crawl();
238
+ });
255
239
  }
256
240
  }
257
- },
258
- state
259
- );
241
+ if (t.isCallExpression(path.parentPath.node)) {
242
+ const options = resolveIdentifier(
243
+ path,
244
+ path.parentPath.node.arguments[0]
245
+ );
246
+ babelHandleReference(options);
247
+ } else if (t.isVariableDeclarator(path.parentPath.node)) {
248
+ const caller = resolveIdentifier(path, path.parentPath.node.init);
249
+ if (t.isCallExpression(caller)) {
250
+ const options = resolveIdentifier(path, caller.arguments[0]);
251
+ babelHandleReference(options);
252
+ }
253
+ }
254
+ }
255
+ });
260
256
  if (removableImportPaths.size > 0) {
261
257
  programPath.traverse({
262
258
  ImportDeclaration(path) {
@@ -284,8 +280,7 @@ function compileCodeSplitVirtualRoute(opts) {
284
280
  const knownExportedIdents = /* @__PURE__ */ new Set();
285
281
  babel.traverse(ast, {
286
282
  Program: {
287
- enter(programPath, programState) {
288
- const state = programState;
283
+ enter(programPath) {
289
284
  const trackedNodesToSplitByType = {
290
285
  component: void 0,
291
286
  loader: void 0,
@@ -293,54 +288,60 @@ function compileCodeSplitVirtualRoute(opts) {
293
288
  errorComponent: void 0,
294
289
  notFoundComponent: void 0
295
290
  };
296
- programPath.traverse(
297
- {
298
- CallExpression: (path) => {
299
- if (!t.isIdentifier(path.node.callee)) {
300
- return;
301
- }
302
- if (!(path.node.callee.name === "createRoute" || path.node.callee.name === "createFileRoute")) {
303
- return;
304
- }
305
- if (t.isCallExpression(path.parentPath.node)) {
306
- const options = resolveIdentifier(
307
- path,
308
- path.parentPath.node.arguments[0]
309
- );
310
- if (t.isObjectExpression(options)) {
311
- options.properties.forEach((prop) => {
312
- if (t.isObjectProperty(prop)) {
313
- KNOWN_SPLIT_ROUTE_IDENTS.forEach((splitType) => {
314
- if (!t.isIdentifier(prop.key) || prop.key.name !== splitType) {
315
- return;
316
- }
317
- const value = prop.value;
318
- let isExported = false;
319
- if (t.isIdentifier(value)) {
320
- isExported = hasExport(ast, value);
321
- if (isExported) {
322
- knownExportedIdents.add(value.name);
323
- }
324
- }
325
- if (isExported && t.isIdentifier(value)) {
326
- removeExports(ast, value);
327
- } else {
328
- const meta = SPLIT_NODES_CONFIG.get(splitType);
329
- trackedNodesToSplitByType[splitType] = {
330
- node: prop.value,
331
- meta
332
- };
291
+ programPath.traverse({
292
+ CallExpression: (path) => {
293
+ if (!t.isIdentifier(path.node.callee)) {
294
+ return;
295
+ }
296
+ if (!(path.node.callee.name === "createRoute" || path.node.callee.name === "createFileRoute")) {
297
+ return;
298
+ }
299
+ function babelHandleVirtual(options) {
300
+ if (t.isObjectExpression(options)) {
301
+ options.properties.forEach((prop) => {
302
+ if (t.isObjectProperty(prop)) {
303
+ KNOWN_SPLIT_ROUTE_IDENTS.forEach((splitType) => {
304
+ if (!t.isIdentifier(prop.key) || prop.key.name !== splitType) {
305
+ return;
306
+ }
307
+ const value = prop.value;
308
+ let isExported = false;
309
+ if (t.isIdentifier(value)) {
310
+ isExported = hasExport(ast, value);
311
+ if (isExported) {
312
+ knownExportedIdents.add(value.name);
333
313
  }
334
- });
335
- }
336
- });
337
- options.properties = [];
338
- }
314
+ }
315
+ if (isExported && t.isIdentifier(value)) {
316
+ removeExports(ast, value);
317
+ } else {
318
+ const meta = SPLIT_NODES_CONFIG.get(splitType);
319
+ trackedNodesToSplitByType[splitType] = {
320
+ node: prop.value,
321
+ meta
322
+ };
323
+ }
324
+ });
325
+ }
326
+ });
327
+ options.properties = [];
328
+ }
329
+ }
330
+ if (t.isCallExpression(path.parentPath.node)) {
331
+ const options = resolveIdentifier(
332
+ path,
333
+ path.parentPath.node.arguments[0]
334
+ );
335
+ babelHandleVirtual(options);
336
+ } else if (t.isVariableDeclarator(path.parentPath.node)) {
337
+ const caller = resolveIdentifier(path, path.parentPath.node.init);
338
+ if (t.isCallExpression(caller)) {
339
+ const options = resolveIdentifier(path, caller.arguments[0]);
340
+ babelHandleVirtual(options);
339
341
  }
340
342
  }
341
- },
342
- state
343
- );
343
+ }
344
+ });
344
345
  intendedSplitNodes.forEach((SPLIT_TYPE) => {
345
346
  const splitKey = trackedNodesToSplitByType[SPLIT_TYPE];
346
347
  if (!splitKey) {