@tanstack/router-plugin 1.168.5 → 1.168.7
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.
- package/dist/cjs/core/code-splitter/compilers.cjs +32 -233
- package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/compilers.d.cts +2 -57
- package/dist/cjs/core/code-splitter/plugins.d.cts +1 -0
- package/dist/cjs/core/config.cjs +1 -1
- package/dist/cjs/core/config.cjs.map +1 -1
- package/dist/cjs/core/config.d.cts +44 -163
- package/dist/cjs/core/hmr/handle-route-update.cjs +17 -18
- package/dist/cjs/core/hmr/handle-route-update.cjs.map +1 -1
- package/dist/cjs/core/router-code-splitter-plugin.cjs +5 -6
- package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
- package/dist/cjs/esbuild.d.cts +26 -26
- package/dist/cjs/index.cjs +2 -0
- package/dist/cjs/index.d.cts +2 -0
- package/dist/cjs/vite.d.cts +26 -26
- package/dist/esm/core/code-splitter/compilers.d.ts +2 -57
- package/dist/esm/core/code-splitter/compilers.js +15 -216
- package/dist/esm/core/code-splitter/compilers.js.map +1 -1
- package/dist/esm/core/code-splitter/plugins.d.ts +1 -0
- package/dist/esm/core/config.d.ts +44 -163
- package/dist/esm/core/config.js +1 -1
- package/dist/esm/core/config.js.map +1 -1
- package/dist/esm/core/hmr/handle-route-update.js +17 -18
- package/dist/esm/core/hmr/handle-route-update.js.map +1 -1
- package/dist/esm/core/router-code-splitter-plugin.js +5 -6
- package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
- package/dist/esm/esbuild.d.ts +26 -26
- package/dist/esm/index.d.ts +2 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/vite.d.ts +26 -26
- package/package.json +7 -7
- package/src/core/code-splitter/compilers.ts +51 -411
- package/src/core/code-splitter/plugins.ts +3 -0
- package/src/core/config.ts +12 -1
- package/src/core/hmr/handle-route-update.ts +30 -35
- package/src/core/router-code-splitter-plugin.ts +11 -9
- package/src/index.ts +5 -0
- package/dist/cjs/core/code-splitter/path-ids.cjs +0 -32
- package/dist/cjs/core/code-splitter/path-ids.cjs.map +0 -1
- package/dist/cjs/core/code-splitter/path-ids.d.cts +0 -2
- package/dist/esm/core/code-splitter/path-ids.d.ts +0 -2
- package/dist/esm/core/code-splitter/path-ids.js +0 -31
- package/dist/esm/core/code-splitter/path-ids.js.map +0 -1
- package/src/core/code-splitter/path-ids.ts +0 -39
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { CreateFileRoute, RegisteredRouter, RouteIds } from '@tanstack/router-core';
|
|
3
3
|
import { CodeSplitGroupings } from './constants.js';
|
|
4
|
-
export declare const splitGroupingsSchema: z.
|
|
4
|
+
export declare const splitGroupingsSchema: z.ZodArray<z.ZodArray<z.ZodUnion<readonly [z.ZodLiteral<"loader">, z.ZodLiteral<"component">, z.ZodLiteral<"pendingComponent">, z.ZodLiteral<"errorComponent">, z.ZodLiteral<"notFoundComponent">]>>>;
|
|
5
5
|
export type CodeSplittingOptions = {
|
|
6
6
|
/**
|
|
7
7
|
* Use this function to programmatically control the code splitting behavior
|
|
@@ -42,99 +42,73 @@ export type HmrOptions = {
|
|
|
42
42
|
type FileRouteKeys = keyof (Parameters<CreateFileRoute<any, any, any, any, any>>[0] & {});
|
|
43
43
|
export type DeletableNodes = FileRouteKeys | (string & {});
|
|
44
44
|
export declare const configSchema: z.ZodObject<{
|
|
45
|
-
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<
|
|
46
|
-
|
|
45
|
+
target: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
46
|
+
vue: "vue";
|
|
47
|
+
react: "react";
|
|
48
|
+
solid: "solid";
|
|
49
|
+
}>>>;
|
|
50
|
+
virtualRouteConfig: z.ZodOptional<z.ZodUnion<[z.ZodType<import('@tanstack/virtual-file-routes').VirtualRootRoute, unknown, z.core.$ZodTypeInternals<import('@tanstack/virtual-file-routes').VirtualRootRoute, unknown>>, z.ZodString]>>;
|
|
47
51
|
routeFilePrefix: z.ZodOptional<z.ZodString>;
|
|
48
52
|
routeFileIgnorePrefix: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
49
53
|
routeFileIgnorePattern: z.ZodOptional<z.ZodString>;
|
|
50
54
|
routesDirectory: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
51
|
-
quoteStyle: z.ZodDefault<z.ZodOptional<z.ZodEnum<
|
|
55
|
+
quoteStyle: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
|
|
56
|
+
single: "single";
|
|
57
|
+
double: "double";
|
|
58
|
+
}>>>;
|
|
52
59
|
semicolons: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
53
60
|
disableLogging: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
54
|
-
routeTreeFileHeader: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString
|
|
55
|
-
indexToken: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.
|
|
61
|
+
routeTreeFileHeader: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
|
|
62
|
+
indexToken: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
|
|
56
63
|
regex: z.ZodString;
|
|
57
64
|
flags: z.ZodOptional<z.ZodString>;
|
|
58
|
-
},
|
|
59
|
-
|
|
60
|
-
flags?: string | undefined;
|
|
61
|
-
}, {
|
|
62
|
-
regex: string;
|
|
63
|
-
flags?: string | undefined;
|
|
64
|
-
}>]>>>;
|
|
65
|
-
routeToken: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodType<RegExp, z.ZodTypeDef, RegExp>, z.ZodObject<{
|
|
65
|
+
}, z.core.$strip>]>>>;
|
|
66
|
+
routeToken: z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodCustom<RegExp, RegExp>, z.ZodObject<{
|
|
66
67
|
regex: z.ZodString;
|
|
67
68
|
flags: z.ZodOptional<z.ZodString>;
|
|
68
|
-
},
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
}, z.core.$strip>]>>>;
|
|
70
|
+
pathParamsAllowedCharacters: z.ZodOptional<z.ZodArray<z.ZodEnum<{
|
|
71
|
+
":": ":";
|
|
72
|
+
$: "$";
|
|
73
|
+
";": ";";
|
|
74
|
+
"@": "@";
|
|
75
|
+
"&": "&";
|
|
76
|
+
"=": "=";
|
|
77
|
+
"+": "+";
|
|
78
|
+
",": ",";
|
|
79
|
+
}>>>;
|
|
77
80
|
generatedRouteTree: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
78
81
|
disableTypes: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
79
|
-
addExtensions: z.
|
|
82
|
+
addExtensions: z.ZodPipe<z.ZodDefault<z.ZodOptional<z.ZodUnion<readonly [z.ZodBoolean, z.ZodString]>>>, z.ZodTransform<string | boolean, string | boolean>>;
|
|
80
83
|
enableRouteTreeFormatting: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
81
|
-
routeTreeFileFooter: z.ZodOptional<z.ZodUnion<[z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString
|
|
84
|
+
routeTreeFileFooter: z.ZodOptional<z.ZodUnion<readonly [z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>, z.ZodCustom<() => Array<string>, () => Array<string>>]>>;
|
|
82
85
|
autoCodeSplitting: z.ZodOptional<z.ZodBoolean>;
|
|
83
86
|
customScaffolding: z.ZodOptional<z.ZodObject<{
|
|
84
87
|
routeTemplate: z.ZodOptional<z.ZodString>;
|
|
85
88
|
lazyRouteTemplate: z.ZodOptional<z.ZodString>;
|
|
86
|
-
},
|
|
87
|
-
routeTemplate?: string | undefined;
|
|
88
|
-
lazyRouteTemplate?: string | undefined;
|
|
89
|
-
}, {
|
|
90
|
-
routeTemplate?: string | undefined;
|
|
91
|
-
lazyRouteTemplate?: string | undefined;
|
|
92
|
-
}>>;
|
|
89
|
+
}, z.core.$strip>>;
|
|
93
90
|
experimental: z.ZodOptional<z.ZodObject<{
|
|
94
91
|
enableCodeSplitting: z.ZodOptional<z.ZodBoolean>;
|
|
95
|
-
},
|
|
96
|
-
|
|
97
|
-
}, {
|
|
98
|
-
enableCodeSplitting?: boolean | undefined;
|
|
99
|
-
}>>;
|
|
100
|
-
plugins: z.ZodOptional<z.ZodArray<z.ZodType<import('@tanstack/router-generator').GeneratorPlugin, z.ZodTypeDef, import('@tanstack/router-generator').GeneratorPlugin>, "many">>;
|
|
92
|
+
}, z.core.$strip>>;
|
|
93
|
+
plugins: z.ZodOptional<z.ZodArray<z.ZodCustom<import('@tanstack/router-generator').GeneratorPlugin, import('@tanstack/router-generator').GeneratorPlugin>>>;
|
|
101
94
|
tmpDir: z.ZodDefault<z.ZodOptional<z.ZodString>>;
|
|
102
95
|
importRoutesUsingAbsolutePaths: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
103
|
-
} & {
|
|
104
96
|
enableRouteGeneration: z.ZodOptional<z.ZodBoolean>;
|
|
105
|
-
codeSplittingOptions: z.ZodOptional<z.
|
|
97
|
+
codeSplittingOptions: z.ZodOptional<z.ZodCustom<CodeSplittingOptions, CodeSplittingOptions>>;
|
|
106
98
|
plugin: z.ZodOptional<z.ZodObject<{
|
|
107
99
|
hmr: z.ZodOptional<z.ZodObject<{
|
|
108
|
-
style: z.ZodOptional<z.ZodEnum<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}>>;
|
|
100
|
+
style: z.ZodOptional<z.ZodEnum<{
|
|
101
|
+
vite: "vite";
|
|
102
|
+
webpack: "webpack";
|
|
103
|
+
}>>;
|
|
104
|
+
}, z.core.$strip>>;
|
|
114
105
|
vite: z.ZodOptional<z.ZodObject<{
|
|
115
106
|
environmentName: z.ZodOptional<z.ZodString>;
|
|
116
|
-
},
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}, "strip", z.ZodTypeAny, {
|
|
122
|
-
vite?: {
|
|
123
|
-
environmentName?: string | undefined;
|
|
124
|
-
} | undefined;
|
|
125
|
-
hmr?: {
|
|
126
|
-
style?: "vite" | "webpack" | undefined;
|
|
127
|
-
} | undefined;
|
|
128
|
-
}, {
|
|
129
|
-
vite?: {
|
|
130
|
-
environmentName?: string | undefined;
|
|
131
|
-
} | undefined;
|
|
132
|
-
hmr?: {
|
|
133
|
-
style?: "vite" | "webpack" | undefined;
|
|
134
|
-
} | undefined;
|
|
135
|
-
}>>;
|
|
136
|
-
}, "strip", z.ZodTypeAny, {
|
|
137
|
-
target: "react" | "solid" | "vue";
|
|
107
|
+
}, z.core.$strip>>;
|
|
108
|
+
}, z.core.$strip>>;
|
|
109
|
+
}, z.core.$strip>;
|
|
110
|
+
export declare const getConfig: (inlineConfig: Partial<Config>, root: string) => {
|
|
111
|
+
target: "vue" | "react" | "solid";
|
|
138
112
|
routeFileIgnorePrefix: string;
|
|
139
113
|
routesDirectory: string;
|
|
140
114
|
quoteStyle: "single" | "double";
|
|
@@ -155,21 +129,11 @@ export declare const configSchema: z.ZodObject<{
|
|
|
155
129
|
enableRouteTreeFormatting: boolean;
|
|
156
130
|
tmpDir: string;
|
|
157
131
|
importRoutesUsingAbsolutePaths: boolean;
|
|
158
|
-
enableRouteGeneration?: boolean | undefined;
|
|
159
|
-
codeSplittingOptions?: CodeSplittingOptions | undefined;
|
|
160
|
-
plugin?: {
|
|
161
|
-
vite?: {
|
|
162
|
-
environmentName?: string | undefined;
|
|
163
|
-
} | undefined;
|
|
164
|
-
hmr?: {
|
|
165
|
-
style?: "vite" | "webpack" | undefined;
|
|
166
|
-
} | undefined;
|
|
167
|
-
} | undefined;
|
|
168
132
|
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
169
133
|
routeFilePrefix?: string | undefined;
|
|
170
134
|
routeFileIgnorePattern?: string | undefined;
|
|
171
|
-
pathParamsAllowedCharacters?: ("
|
|
172
|
-
routeTreeFileFooter?: string[] | ((
|
|
135
|
+
pathParamsAllowedCharacters?: (":" | "$" | ";" | "@" | "&" | "=" | "+" | ",")[] | undefined;
|
|
136
|
+
routeTreeFileFooter?: string[] | (() => Array<string>) | undefined;
|
|
173
137
|
autoCodeSplitting?: boolean | undefined;
|
|
174
138
|
customScaffolding?: {
|
|
175
139
|
routeTemplate?: string | undefined;
|
|
@@ -179,99 +143,16 @@ export declare const configSchema: z.ZodObject<{
|
|
|
179
143
|
enableCodeSplitting?: boolean | undefined;
|
|
180
144
|
} | undefined;
|
|
181
145
|
plugins?: import('@tanstack/router-generator').GeneratorPlugin[] | undefined;
|
|
182
|
-
}, {
|
|
183
146
|
enableRouteGeneration?: boolean | undefined;
|
|
184
147
|
codeSplittingOptions?: CodeSplittingOptions | undefined;
|
|
185
148
|
plugin?: {
|
|
186
|
-
vite?: {
|
|
187
|
-
environmentName?: string | undefined;
|
|
188
|
-
} | undefined;
|
|
189
149
|
hmr?: {
|
|
190
150
|
style?: "vite" | "webpack" | undefined;
|
|
191
151
|
} | undefined;
|
|
192
|
-
} | undefined;
|
|
193
|
-
target?: "react" | "solid" | "vue" | undefined;
|
|
194
|
-
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
195
|
-
routeFilePrefix?: string | undefined;
|
|
196
|
-
routeFileIgnorePrefix?: string | undefined;
|
|
197
|
-
routeFileIgnorePattern?: string | undefined;
|
|
198
|
-
routesDirectory?: string | undefined;
|
|
199
|
-
quoteStyle?: "single" | "double" | undefined;
|
|
200
|
-
semicolons?: boolean | undefined;
|
|
201
|
-
disableLogging?: boolean | undefined;
|
|
202
|
-
routeTreeFileHeader?: string[] | undefined;
|
|
203
|
-
indexToken?: string | RegExp | {
|
|
204
|
-
regex: string;
|
|
205
|
-
flags?: string | undefined;
|
|
206
|
-
} | undefined;
|
|
207
|
-
routeToken?: string | RegExp | {
|
|
208
|
-
regex: string;
|
|
209
|
-
flags?: string | undefined;
|
|
210
|
-
} | undefined;
|
|
211
|
-
pathParamsAllowedCharacters?: (";" | ":" | "@" | "&" | "=" | "+" | "$" | ",")[] | undefined;
|
|
212
|
-
generatedRouteTree?: string | undefined;
|
|
213
|
-
disableTypes?: boolean | undefined;
|
|
214
|
-
addExtensions?: string | boolean | undefined;
|
|
215
|
-
enableRouteTreeFormatting?: boolean | undefined;
|
|
216
|
-
routeTreeFileFooter?: string[] | ((...args: unknown[]) => string[]) | undefined;
|
|
217
|
-
autoCodeSplitting?: boolean | undefined;
|
|
218
|
-
customScaffolding?: {
|
|
219
|
-
routeTemplate?: string | undefined;
|
|
220
|
-
lazyRouteTemplate?: string | undefined;
|
|
221
|
-
} | undefined;
|
|
222
|
-
experimental?: {
|
|
223
|
-
enableCodeSplitting?: boolean | undefined;
|
|
224
|
-
} | undefined;
|
|
225
|
-
plugins?: import('@tanstack/router-generator').GeneratorPlugin[] | undefined;
|
|
226
|
-
tmpDir?: string | undefined;
|
|
227
|
-
importRoutesUsingAbsolutePaths?: boolean | undefined;
|
|
228
|
-
}>;
|
|
229
|
-
export declare const getConfig: (inlineConfig: Partial<Config>, root: string) => {
|
|
230
|
-
target: "react" | "solid" | "vue";
|
|
231
|
-
routeFileIgnorePrefix: string;
|
|
232
|
-
routesDirectory: string;
|
|
233
|
-
quoteStyle: "single" | "double";
|
|
234
|
-
semicolons: boolean;
|
|
235
|
-
disableLogging: boolean;
|
|
236
|
-
routeTreeFileHeader: string[];
|
|
237
|
-
indexToken: string | RegExp | {
|
|
238
|
-
regex: string;
|
|
239
|
-
flags?: string | undefined;
|
|
240
|
-
};
|
|
241
|
-
routeToken: string | RegExp | {
|
|
242
|
-
regex: string;
|
|
243
|
-
flags?: string | undefined;
|
|
244
|
-
};
|
|
245
|
-
generatedRouteTree: string;
|
|
246
|
-
disableTypes: boolean;
|
|
247
|
-
addExtensions: string | boolean;
|
|
248
|
-
enableRouteTreeFormatting: boolean;
|
|
249
|
-
tmpDir: string;
|
|
250
|
-
importRoutesUsingAbsolutePaths: boolean;
|
|
251
|
-
enableRouteGeneration?: boolean | undefined;
|
|
252
|
-
codeSplittingOptions?: CodeSplittingOptions | undefined;
|
|
253
|
-
plugin?: {
|
|
254
152
|
vite?: {
|
|
255
153
|
environmentName?: string | undefined;
|
|
256
154
|
} | undefined;
|
|
257
|
-
hmr?: {
|
|
258
|
-
style?: "vite" | "webpack" | undefined;
|
|
259
|
-
} | undefined;
|
|
260
155
|
} | undefined;
|
|
261
|
-
virtualRouteConfig?: string | import('@tanstack/virtual-file-routes').VirtualRootRoute | undefined;
|
|
262
|
-
routeFilePrefix?: string | undefined;
|
|
263
|
-
routeFileIgnorePattern?: string | undefined;
|
|
264
|
-
pathParamsAllowedCharacters?: (";" | ":" | "@" | "&" | "=" | "+" | "$" | ",")[] | undefined;
|
|
265
|
-
routeTreeFileFooter?: string[] | ((...args: unknown[]) => string[]) | undefined;
|
|
266
|
-
autoCodeSplitting?: boolean | undefined;
|
|
267
|
-
customScaffolding?: {
|
|
268
|
-
routeTemplate?: string | undefined;
|
|
269
|
-
lazyRouteTemplate?: string | undefined;
|
|
270
|
-
} | undefined;
|
|
271
|
-
experimental?: {
|
|
272
|
-
enableCodeSplitting?: boolean | undefined;
|
|
273
|
-
} | undefined;
|
|
274
|
-
plugins?: import('@tanstack/router-generator').GeneratorPlugin[] | undefined;
|
|
275
156
|
};
|
|
276
157
|
export type Config = z.infer<typeof configSchema>;
|
|
277
158
|
export type ConfigInput = z.input<typeof configSchema>;
|
package/dist/esm/core/config.js
CHANGED
|
@@ -15,7 +15,7 @@ var splitGroupingsSchema = z.array(z.array(z.union([
|
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
17
|
var codeSplittingOptionsSchema = z.object({
|
|
18
|
-
splitBehavior: z.
|
|
18
|
+
splitBehavior: z.custom((value) => typeof value === "function").optional(),
|
|
19
19
|
defaultBehavior: splitGroupingsSchema.optional(),
|
|
20
20
|
deleteNodes: z.array(z.string()).optional(),
|
|
21
21
|
addHmr: z.boolean().optional().default(true)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","names":[],"sources":["../../../src/core/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport {\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport type {\n CreateFileRoute,\n RegisteredRouter,\n RouteIds,\n} from '@tanstack/router-core'\nimport type { CodeSplitGroupings } from './constants'\n\nexport const splitGroupingsSchema = z\n .array(\n z.array(\n z.union([\n z.literal('loader'),\n z.literal('component'),\n z.literal('pendingComponent'),\n z.literal('errorComponent'),\n z.literal('notFoundComponent'),\n ]),\n ),\n {\n message:\n \" Must be an Array of Arrays containing the split groupings. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']]\",\n },\n )\n .superRefine((val, ctx) => {\n const flattened = val.flat()\n const unique = [...new Set(flattened)]\n\n // Elements must be unique,\n // ie. this shouldn't be allows [['component'], ['component', 'loader']]\n if (unique.length !== flattened.length) {\n ctx.addIssue({\n code: 'custom',\n message:\n \" Split groupings must be unique and not repeated. i.e. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']].\" +\n `\\n You input was: ${JSON.stringify(val)}.`,\n })\n }\n })\n\nexport type CodeSplittingOptions = {\n /**\n * Use this function to programmatically control the code splitting behavior\n * based on the `routeId` for each route.\n *\n * If you just need to change the default behavior, you can use the `defaultBehavior` option.\n * @param params\n */\n splitBehavior?: (params: {\n routeId: RouteIds<RegisteredRouter['routeTree']>\n }) => CodeSplitGroupings | undefined | void\n\n /**\n * The default/global configuration to control your code splitting behavior per route.\n * @default [['component'],['pendingComponent'],['errorComponent'],['notFoundComponent']]\n */\n defaultBehavior?: CodeSplitGroupings\n\n /**\n * The nodes that shall be deleted from the route.\n * @default undefined\n */\n deleteNodes?: Array<DeletableNodes>\n\n /**\n * @default true\n */\n addHmr?: boolean\n}\n\nexport type HmrStyle = 'vite' | 'webpack'\n\nexport type HmrOptions = {\n /**\n * Selects the HMR runtime style to emit code for.\n * - `'vite'` (default): ESM `import.meta.hot` with Vite accept-callback semantics.\n * - `'webpack'`: `import.meta.webpackHot` with webpack / Rspack `module.hot` re-execution semantics.\n *\n * Bundler-specific plugin entries (e.g. `rspack.ts`, `webpack.ts`) set this explicitly.\n */\n style?: HmrStyle\n}\n\nconst codeSplittingOptionsSchema = z.object({\n splitBehavior: z.
|
|
1
|
+
{"version":3,"file":"config.js","names":[],"sources":["../../../src/core/config.ts"],"sourcesContent":["import { z } from 'zod'\nimport {\n configSchema as generatorConfigSchema,\n getConfig as getGeneratorConfig,\n} from '@tanstack/router-generator'\nimport type {\n CreateFileRoute,\n RegisteredRouter,\n RouteIds,\n} from '@tanstack/router-core'\nimport type { CodeSplitGroupings } from './constants'\nimport type { ReferenceRouteCompilerPlugin } from './code-splitter/plugins'\n\nexport const splitGroupingsSchema = z\n .array(\n z.array(\n z.union([\n z.literal('loader'),\n z.literal('component'),\n z.literal('pendingComponent'),\n z.literal('errorComponent'),\n z.literal('notFoundComponent'),\n ]),\n ),\n {\n message:\n \" Must be an Array of Arrays containing the split groupings. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']]\",\n },\n )\n .superRefine((val, ctx) => {\n const flattened = val.flat()\n const unique = [...new Set(flattened)]\n\n // Elements must be unique,\n // ie. this shouldn't be allows [['component'], ['component', 'loader']]\n if (unique.length !== flattened.length) {\n ctx.addIssue({\n code: 'custom',\n message:\n \" Split groupings must be unique and not repeated. i.e. i.e. [['component'], ['pendingComponent'], ['errorComponent', 'notFoundComponent']].\" +\n `\\n You input was: ${JSON.stringify(val)}.`,\n })\n }\n })\n\nexport type CodeSplittingOptions = {\n /**\n * Use this function to programmatically control the code splitting behavior\n * based on the `routeId` for each route.\n *\n * If you just need to change the default behavior, you can use the `defaultBehavior` option.\n * @param params\n */\n splitBehavior?: (params: {\n routeId: RouteIds<RegisteredRouter['routeTree']>\n }) => CodeSplitGroupings | undefined | void\n\n /**\n * The default/global configuration to control your code splitting behavior per route.\n * @default [['component'],['pendingComponent'],['errorComponent'],['notFoundComponent']]\n */\n defaultBehavior?: CodeSplitGroupings\n\n /**\n * The nodes that shall be deleted from the route.\n * @default undefined\n */\n deleteNodes?: Array<DeletableNodes>\n\n /**\n * @default true\n */\n addHmr?: boolean\n\n /**\n * Internal compiler plugins used by framework integrations.\n * @internal\n */\n compilerPlugins?: Array<ReferenceRouteCompilerPlugin>\n}\n\nexport type HmrStyle = 'vite' | 'webpack'\n\nexport type HmrOptions = {\n /**\n * Selects the HMR runtime style to emit code for.\n * - `'vite'` (default): ESM `import.meta.hot` with Vite accept-callback semantics.\n * - `'webpack'`: `import.meta.webpackHot` with webpack / Rspack `module.hot` re-execution semantics.\n *\n * Bundler-specific plugin entries (e.g. `rspack.ts`, `webpack.ts`) set this explicitly.\n */\n style?: HmrStyle\n}\n\nconst codeSplittingOptionsSchema = z.object({\n splitBehavior: z\n .custom<\n CodeSplittingOptions['splitBehavior']\n >((value) => typeof value === 'function')\n .optional(),\n defaultBehavior: splitGroupingsSchema.optional(),\n deleteNodes: z.array(z.string()).optional(),\n addHmr: z.boolean().optional().default(true),\n})\n\ntype FileRouteKeys = keyof (Parameters<\n CreateFileRoute<any, any, any, any, any>\n>[0] & {})\nexport type DeletableNodes = FileRouteKeys | (string & {})\n\nexport const configSchema = generatorConfigSchema.extend({\n enableRouteGeneration: z.boolean().optional(),\n codeSplittingOptions: z\n .custom<CodeSplittingOptions>((v) => {\n return codeSplittingOptionsSchema.parse(v)\n })\n .optional(),\n plugin: z\n .object({\n hmr: z\n .object({\n style: z.enum(['vite', 'webpack']).optional(),\n })\n .optional(),\n vite: z\n .object({\n environmentName: z.string().optional(),\n })\n .optional(),\n })\n .optional(),\n})\n\nexport const getConfig = (inlineConfig: Partial<Config>, root: string) => {\n const config = getGeneratorConfig(inlineConfig, root)\n\n return configSchema.parse({ ...inlineConfig, ...config })\n}\n\nexport type Config = z.infer<typeof configSchema>\nexport type ConfigInput = z.input<typeof configSchema>\nexport type ConfigOutput = z.output<typeof configSchema>\n"],"mappings":";;;AAaA,IAAa,uBAAuB,EACjC,MACC,EAAE,MACA,EAAE,MAAM;CACN,EAAE,QAAQ,SAAS;CACnB,EAAE,QAAQ,YAAY;CACtB,EAAE,QAAQ,mBAAmB;CAC7B,EAAE,QAAQ,iBAAiB;CAC3B,EAAE,QAAQ,oBAAoB;CAC/B,CAAC,CACH,EACD,EACE,SACE,oJACH,CACF,CACA,aAAa,KAAK,QAAQ;CACzB,MAAM,YAAY,IAAI,MAAM;AAK5B,KAJe,CAAC,GAAG,IAAI,IAAI,UAAU,CAAC,CAI3B,WAAW,UAAU,OAC9B,KAAI,SAAS;EACX,MAAM;EACN,SACE,kKACsB,KAAK,UAAU,IAAI,CAAC;EAC7C,CAAC;EAEJ;AAmDJ,IAAM,6BAA6B,EAAE,OAAO;CAC1C,eAAe,EACZ,QAEE,UAAU,OAAO,UAAU,WAAW,CACxC,UAAU;CACb,iBAAiB,qBAAqB,UAAU;CAChD,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,UAAU;CAC3C,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,QAAQ,KAAK;CAC7C,CAAC;AAOF,IAAa,iBAAe,aAAsB,OAAO;CACvD,uBAAuB,EAAE,SAAS,CAAC,UAAU;CAC7C,sBAAsB,EACnB,QAA8B,MAAM;AACnC,SAAO,2BAA2B,MAAM,EAAE;GAC1C,CACD,UAAU;CACb,QAAQ,EACL,OAAO;EACN,KAAK,EACF,OAAO,EACN,OAAO,EAAE,KAAK,CAAC,QAAQ,UAAU,CAAC,CAAC,UAAU,EAC9C,CAAC,CACD,UAAU;EACb,MAAM,EACH,OAAO,EACN,iBAAiB,EAAE,QAAQ,CAAC,UAAU,EACvC,CAAC,CACD,UAAU;EACd,CAAC,CACD,UAAU;CACd,CAAC;AAEF,IAAa,eAAa,cAA+B,SAAiB;CACxE,MAAM,SAAS,UAAmB,cAAc,KAAK;AAErD,QAAO,eAAa,MAAM;EAAE,GAAG;EAAc,GAAG;EAAQ,CAAC"}
|
|
@@ -3,9 +3,18 @@ function handleRouteUpdate(routeId, newRoute) {
|
|
|
3
3
|
const router = window.__TSR_ROUTER__;
|
|
4
4
|
const oldRoute = router.routesById[routeId];
|
|
5
5
|
if (!oldRoute) return;
|
|
6
|
+
const generatedRouteOptionKeys = new Set([
|
|
7
|
+
"id",
|
|
8
|
+
"path",
|
|
9
|
+
"getParentRoute"
|
|
10
|
+
]);
|
|
11
|
+
const generatedRouteOptions = {};
|
|
12
|
+
generatedRouteOptionKeys.forEach((key) => {
|
|
13
|
+
if (key in oldRoute.options) generatedRouteOptions[key] = oldRoute.options[key];
|
|
14
|
+
});
|
|
6
15
|
const removedKeys = /* @__PURE__ */ new Set();
|
|
7
16
|
Object.keys(oldRoute.options).forEach((key) => {
|
|
8
|
-
if (!(key in newRoute.options)) {
|
|
17
|
+
if (!generatedRouteOptionKeys.has(key) && !(key in newRoute.options)) {
|
|
9
18
|
removedKeys.add(key);
|
|
10
19
|
delete oldRoute.options[key];
|
|
11
20
|
}
|
|
@@ -15,17 +24,16 @@ function handleRouteUpdate(routeId, newRoute) {
|
|
|
15
24
|
if (preserveComponentIdentity) componentKeys.forEach((key) => {
|
|
16
25
|
if (key in oldRoute.options && key in newRoute.options) newRoute.options[key] = oldRoute.options[key];
|
|
17
26
|
});
|
|
18
|
-
|
|
19
|
-
|
|
27
|
+
const nextOptions = {
|
|
28
|
+
...newRoute.options,
|
|
29
|
+
...generatedRouteOptions
|
|
30
|
+
};
|
|
31
|
+
oldRoute.options = nextOptions;
|
|
32
|
+
oldRoute.update(nextOptions);
|
|
20
33
|
oldRoute._componentsPromise = void 0;
|
|
21
34
|
oldRoute._lazyPromise = void 0;
|
|
22
|
-
router.
|
|
23
|
-
router.routesByPath[oldRoute.fullPath] = oldRoute;
|
|
24
|
-
router.processedTree.matchCache.clear();
|
|
25
|
-
router.processedTree.flatCache?.clear();
|
|
26
|
-
router.processedTree.singleCache.clear();
|
|
35
|
+
router.setRoutes(router.buildRouteTree());
|
|
27
36
|
router.resolvePathCache.clear();
|
|
28
|
-
walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree);
|
|
29
37
|
const filter = (m) => m.routeId === oldRoute.id;
|
|
30
38
|
const activeMatch = router.stores.matches.get().find(filter);
|
|
31
39
|
const pendingMatch = router.stores.pendingMatches.get().find(filter);
|
|
@@ -57,15 +65,6 @@ function handleRouteUpdate(routeId, newRoute) {
|
|
|
57
65
|
sync: true
|
|
58
66
|
});
|
|
59
67
|
}
|
|
60
|
-
function walkReplaceSegmentTree(route, node) {
|
|
61
|
-
if (node.route?.id === route.id) node.route = route;
|
|
62
|
-
if (node.index) walkReplaceSegmentTree(route, node.index);
|
|
63
|
-
node.static?.forEach((child) => walkReplaceSegmentTree(route, child));
|
|
64
|
-
node.staticInsensitive?.forEach((child) => walkReplaceSegmentTree(route, child));
|
|
65
|
-
node.dynamic?.forEach((child) => walkReplaceSegmentTree(route, child));
|
|
66
|
-
node.optional?.forEach((child) => walkReplaceSegmentTree(route, child));
|
|
67
|
-
node.wildcard?.forEach((child) => walkReplaceSegmentTree(route, child));
|
|
68
|
-
}
|
|
69
68
|
function getStoreMatch(matchId) {
|
|
70
69
|
return router.stores.pendingMatchStores.get(matchId)?.get() || router.stores.matchStores.get(matchId)?.get() || router.stores.cachedMatchStores.get(matchId)?.get();
|
|
71
70
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handle-route-update.js","names":[],"sources":["../../../../src/core/hmr/handle-route-update.ts"],"sourcesContent":["import type {\n AnyRoute,\n AnyRouteMatch,\n AnyRouter,\n RouterWritableStore,\n} from '@tanstack/router-core'\n\ntype AnyRouteWithPrivateProps = AnyRoute & {\n options: Record<string, unknown>\n _componentsPromise?: Promise<void>\n _lazyPromise?: Promise<void>\n update: (options: Record<string, unknown>) => unknown\n _path: string\n _id: string\n _fullPath: string\n _to: string\n}\n\ntype AnyRouterWithPrivateMaps = AnyRouter & {\n routesById: Record<string, AnyRoute>\n routesByPath: Record<string, AnyRoute>\n stores: AnyRouter['stores'] & {\n cachedMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'get' | 'set'>\n >\n pendingMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'get' | 'set'>\n >\n matchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'get' | 'set'>\n >\n }\n}\n\ntype AnyRouteMatchWithPrivateProps = AnyRouteMatch & {\n __beforeLoadContext?: unknown\n __routeContext?: Record<string, unknown>\n context?: Record<string, unknown>\n}\n\nfunction handleRouteUpdate(\n routeId: string,\n newRoute: AnyRouteWithPrivateProps,\n) {\n const router = window.__TSR_ROUTER__ as AnyRouterWithPrivateMaps\n const oldRoute = router.routesById[routeId] as\n | AnyRouteWithPrivateProps\n | undefined\n\n if (!oldRoute) {\n return\n }\n\n // Keys whose identity must remain stable to prevent React from\n // unmounting/remounting the component tree. React Fast Refresh already\n // handles hot-updating the function bodies of these components — our job\n // is only to update non-component route options (loader, head, etc.).\n // For code-split (splittable) routes, the lazyRouteComponent wrapper is\n // already cached in the bundler hot data so its identity is stable.\n // For unsplittable routes (e.g. root routes), the component is a plain\n // function reference that gets recreated on every module re-execution,\n // so we must explicitly preserve the old reference.\n const removedKeys = new Set<string>()\n Object.keys(oldRoute.options).forEach((key) => {\n if (!(key in newRoute.options)) {\n removedKeys.add(key)\n delete oldRoute.options[key]\n }\n })\n\n const oldHasShellComponent = 'shellComponent' in oldRoute.options\n const newHasShellComponent = 'shellComponent' in newRoute.options\n const preserveComponentIdentity =\n oldHasShellComponent === newHasShellComponent\n\n // Preserve component identity so React doesn't remount.\n // React Fast Refresh patches the function bodies in-place.\n const componentKeys = '__TSR_COMPONENT_TYPES__' as unknown as Array<string>\n if (preserveComponentIdentity) {\n componentKeys.forEach((key) => {\n if (key in oldRoute.options && key in newRoute.options) {\n newRoute.options[key] = oldRoute.options[key]\n }\n })\n }\n\n oldRoute.options = newRoute.options\n oldRoute.update(newRoute.options)\n oldRoute._componentsPromise = undefined\n oldRoute._lazyPromise = undefined\n\n router.routesById[oldRoute.id] = oldRoute\n router.routesByPath[oldRoute.fullPath] = oldRoute\n\n router.processedTree.matchCache.clear()\n router.processedTree.flatCache?.clear()\n router.processedTree.singleCache.clear()\n router.resolvePathCache.clear()\n walkReplaceSegmentTree(oldRoute, router.processedTree.segmentTree)\n\n const filter = (m: AnyRouteMatch) => m.routeId === oldRoute.id\n const activeMatch = router.stores.matches.get().find(filter)\n const pendingMatch = router.stores.pendingMatches.get().find(filter)\n const cachedMatches = router.stores.cachedMatches.get().filter(filter)\n\n if (activeMatch || pendingMatch || cachedMatches.length > 0) {\n // Clear stale match data for removed route options BEFORE invalidating.\n // Without this, router.invalidate() -> matchRoutes() reuses the existing\n // match from the store (via ...existingMatch spread) and the stale\n // loaderData / __beforeLoadContext survives the reload cycle.\n //\n // We must update the store directly (not via router.updateMatch) because\n // updateMatch wraps in startTransition which may defer the state update,\n // and we need the clear to be visible before invalidate reads the store.\n if (removedKeys.has('loader') || removedKeys.has('beforeLoad')) {\n const matchIds = [\n activeMatch?.id,\n pendingMatch?.id,\n ...cachedMatches.map((match) => match.id),\n ].filter(Boolean) as Array<string>\n router.batch(() => {\n for (const matchId of matchIds) {\n const store =\n router.stores.pendingMatchStores.get(matchId) ||\n router.stores.matchStores.get(matchId) ||\n router.stores.cachedMatchStores.get(matchId)\n if (store) {\n store.set((prev) => {\n const next: AnyRouteMatchWithPrivateProps = { ...prev }\n\n if (removedKeys.has('loader')) {\n next.loaderData = undefined\n }\n if (removedKeys.has('beforeLoad')) {\n next.__beforeLoadContext = undefined\n next.context = rebuildMatchContextWithoutBeforeLoad(next)\n }\n\n return next\n })\n }\n }\n })\n }\n\n router.invalidate({ filter, sync: true })\n }\n\n function walkReplaceSegmentTree(\n route: AnyRouteWithPrivateProps,\n node: AnyRouter['processedTree']['segmentTree'],\n ) {\n if (node.route?.id === route.id) node.route = route\n if (node.index) walkReplaceSegmentTree(route, node.index)\n node.static?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.staticInsensitive?.forEach((child) =>\n walkReplaceSegmentTree(route, child),\n )\n node.dynamic?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.optional?.forEach((child) => walkReplaceSegmentTree(route, child))\n node.wildcard?.forEach((child) => walkReplaceSegmentTree(route, child))\n }\n\n function getStoreMatch(matchId: string) {\n return (\n router.stores.pendingMatchStores.get(matchId)?.get() ||\n router.stores.matchStores.get(matchId)?.get() ||\n router.stores.cachedMatchStores.get(matchId)?.get()\n )\n }\n\n function getMatchList(matchId: string) {\n const pendingMatches = router.stores.pendingMatches.get()\n if (pendingMatches.some((match) => match.id === matchId)) {\n return pendingMatches\n }\n\n const activeMatches = router.stores.matches.get()\n if (activeMatches.some((match) => match.id === matchId)) {\n return activeMatches\n }\n\n const cachedMatches = router.stores.cachedMatches.get()\n if (cachedMatches.some((match) => match.id === matchId)) {\n return cachedMatches\n }\n\n return []\n }\n\n function getParentMatch(match: AnyRouteMatch) {\n const matchList = getMatchList(match.id)\n const matchIndex = matchList.findIndex((item) => item.id === match.id)\n\n if (matchIndex <= 0) {\n return undefined\n }\n\n const parentMatch = matchList[matchIndex - 1]!\n return getStoreMatch(parentMatch.id) || parentMatch\n }\n\n function rebuildMatchContextWithoutBeforeLoad(\n match: AnyRouteMatchWithPrivateProps,\n ) {\n const parentMatch = getParentMatch(match)\n const getParentContext = (\n router as unknown as {\n getParentContext?: (\n parentMatch?: AnyRouteMatch,\n ) => Record<string, unknown> | undefined\n }\n ).getParentContext\n const parentContext = getParentContext\n ? getParentContext.call(router, parentMatch)\n : (parentMatch?.context ?? router.options.context)\n\n return {\n ...(parentContext ?? {}),\n ...(match.__routeContext ?? {}),\n }\n }\n}\n\nconst handleRouteUpdateStr = handleRouteUpdate.toString()\n\nexport function getHandleRouteUpdateCode(stableRouteOptionKeys: Array<string>) {\n return handleRouteUpdateStr.replace(\n /['\"]__TSR_COMPONENT_TYPES__['\"]/,\n JSON.stringify(stableRouteOptionKeys),\n )\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"handle-route-update.js","names":[],"sources":["../../../../src/core/hmr/handle-route-update.ts"],"sourcesContent":["import type {\n AnyRoute,\n AnyRouteMatch,\n AnyRouter,\n RouterWritableStore,\n} from '@tanstack/router-core'\n\ntype AnyRouteWithPrivateProps = AnyRoute & {\n options: Record<string, unknown>\n _componentsPromise?: Promise<void>\n _lazyPromise?: Promise<void>\n update: (options: Record<string, unknown>) => unknown\n _path: string\n _id: string\n _fullPath: string\n _to: string\n}\n\ntype AnyRouterWithPrivateMaps = AnyRouter & {\n routesById: Record<string, AnyRoute>\n buildRouteTree: () => Parameters<AnyRouter['setRoutes']>[0]\n setRoutes: AnyRouter['setRoutes']\n stores: AnyRouter['stores'] & {\n cachedMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'get' | 'set'>\n >\n pendingMatchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'get' | 'set'>\n >\n matchStores: Map<\n string,\n Pick<RouterWritableStore<AnyRouteMatch>, 'get' | 'set'>\n >\n }\n}\n\ntype AnyRouteMatchWithPrivateProps = AnyRouteMatch & {\n __beforeLoadContext?: unknown\n __routeContext?: Record<string, unknown>\n context?: Record<string, unknown>\n}\n\nfunction handleRouteUpdate(\n routeId: string,\n newRoute: AnyRouteWithPrivateProps,\n) {\n const router = window.__TSR_ROUTER__ as AnyRouterWithPrivateMaps\n const oldRoute = router.routesById[routeId] as\n | AnyRouteWithPrivateProps\n | undefined\n\n if (!oldRoute) {\n return\n }\n\n // Generated route-tree options are not present on the freshly imported route\n // module, but they must stay on the live route before rebuilding indexes.\n const generatedRouteOptionKeys = new Set(['id', 'path', 'getParentRoute'])\n const generatedRouteOptions: Record<string, unknown> = {}\n generatedRouteOptionKeys.forEach((key) => {\n if (key in oldRoute.options) {\n generatedRouteOptions[key] = oldRoute.options[key]\n }\n })\n\n const removedKeys = new Set<string>()\n Object.keys(oldRoute.options).forEach((key) => {\n if (!generatedRouteOptionKeys.has(key) && !(key in newRoute.options)) {\n removedKeys.add(key)\n delete oldRoute.options[key]\n }\n })\n\n const oldHasShellComponent = 'shellComponent' in oldRoute.options\n const newHasShellComponent = 'shellComponent' in newRoute.options\n const preserveComponentIdentity =\n oldHasShellComponent === newHasShellComponent\n\n // Keys whose identity must remain stable to prevent React from\n // unmounting/remounting the component tree. React Fast Refresh already\n // handles hot-updating the function bodies of these components — our job\n // is only to update non-component route options (loader, head, etc.).\n // For code-split (splittable) routes, the lazyRouteComponent wrapper is\n // already cached in the bundler hot data so its identity is stable.\n // For unsplittable routes (e.g. root routes), the component is a plain\n // function reference that gets recreated on every module re-execution,\n // so we must explicitly preserve the old reference.\n // Preserve component identity so React doesn't remount.\n // React Fast Refresh patches the function bodies in-place.\n const componentKeys = '__TSR_COMPONENT_TYPES__' as unknown as Array<string>\n if (preserveComponentIdentity) {\n componentKeys.forEach((key) => {\n if (key in oldRoute.options && key in newRoute.options) {\n newRoute.options[key] = oldRoute.options[key]\n }\n })\n }\n\n const nextOptions = {\n ...newRoute.options,\n ...generatedRouteOptions,\n }\n\n oldRoute.options = nextOptions\n oldRoute.update(nextOptions)\n oldRoute._componentsPromise = undefined\n oldRoute._lazyPromise = undefined\n\n router.setRoutes(router.buildRouteTree())\n router.resolvePathCache.clear()\n\n const filter = (m: AnyRouteMatch) => m.routeId === oldRoute.id\n const activeMatch = router.stores.matches.get().find(filter)\n const pendingMatch = router.stores.pendingMatches.get().find(filter)\n const cachedMatches = router.stores.cachedMatches.get().filter(filter)\n\n if (activeMatch || pendingMatch || cachedMatches.length > 0) {\n // Clear stale match data for removed route options BEFORE invalidating.\n // Without this, router.invalidate() -> matchRoutes() reuses the existing\n // match from the store (via ...existingMatch spread) and the stale\n // loaderData / __beforeLoadContext survives the reload cycle.\n //\n // We must update the store directly (not via router.updateMatch) because\n // updateMatch wraps in startTransition which may defer the state update,\n // and we need the clear to be visible before invalidate reads the store.\n if (removedKeys.has('loader') || removedKeys.has('beforeLoad')) {\n const matchIds = [\n activeMatch?.id,\n pendingMatch?.id,\n ...cachedMatches.map((match) => match.id),\n ].filter(Boolean) as Array<string>\n router.batch(() => {\n for (const matchId of matchIds) {\n const store =\n router.stores.pendingMatchStores.get(matchId) ||\n router.stores.matchStores.get(matchId) ||\n router.stores.cachedMatchStores.get(matchId)\n if (store) {\n store.set((prev) => {\n const next: AnyRouteMatchWithPrivateProps = { ...prev }\n\n if (removedKeys.has('loader')) {\n next.loaderData = undefined\n }\n if (removedKeys.has('beforeLoad')) {\n next.__beforeLoadContext = undefined\n next.context = rebuildMatchContextWithoutBeforeLoad(next)\n }\n\n return next\n })\n }\n }\n })\n }\n\n router.invalidate({ filter, sync: true })\n }\n\n function getStoreMatch(matchId: string) {\n return (\n router.stores.pendingMatchStores.get(matchId)?.get() ||\n router.stores.matchStores.get(matchId)?.get() ||\n router.stores.cachedMatchStores.get(matchId)?.get()\n )\n }\n\n function getMatchList(matchId: string) {\n const pendingMatches = router.stores.pendingMatches.get()\n if (pendingMatches.some((match) => match.id === matchId)) {\n return pendingMatches\n }\n\n const activeMatches = router.stores.matches.get()\n if (activeMatches.some((match) => match.id === matchId)) {\n return activeMatches\n }\n\n const cachedMatches = router.stores.cachedMatches.get()\n if (cachedMatches.some((match) => match.id === matchId)) {\n return cachedMatches\n }\n\n return []\n }\n\n function getParentMatch(match: AnyRouteMatch) {\n const matchList = getMatchList(match.id)\n const matchIndex = matchList.findIndex((item) => item.id === match.id)\n\n if (matchIndex <= 0) {\n return undefined\n }\n\n const parentMatch = matchList[matchIndex - 1]!\n return getStoreMatch(parentMatch.id) || parentMatch\n }\n\n function rebuildMatchContextWithoutBeforeLoad(\n match: AnyRouteMatchWithPrivateProps,\n ) {\n const parentMatch = getParentMatch(match)\n const getParentContext = (\n router as unknown as {\n getParentContext?: (\n parentMatch?: AnyRouteMatch,\n ) => Record<string, unknown> | undefined\n }\n ).getParentContext\n const parentContext = getParentContext\n ? getParentContext.call(router, parentMatch)\n : (parentMatch?.context ?? router.options.context)\n\n return {\n ...(parentContext ?? {}),\n ...(match.__routeContext ?? {}),\n }\n }\n}\n\nconst handleRouteUpdateStr = handleRouteUpdate.toString()\n\nexport function getHandleRouteUpdateCode(stableRouteOptionKeys: Array<string>) {\n return handleRouteUpdateStr.replace(\n /['\"]__TSR_COMPONENT_TYPES__['\"]/,\n JSON.stringify(stableRouteOptionKeys),\n )\n}\n"],"mappings":"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"}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import { getConfig, splitGroupingsSchema } from "./config.js";
|
|
2
2
|
import { defaultCodeSplitGroupings, splitRouteIdentNodes, tsrShared, tsrSplit } from "./constants.js";
|
|
3
3
|
import { debug, normalizePath, routeFactoryCallCodeFilter } from "./utils.js";
|
|
4
|
-
import { decodeIdentifier } from "./code-splitter/path-ids.js";
|
|
5
4
|
import { compileCodeSplitReferenceRoute, compileCodeSplitSharedRoute, compileCodeSplitVirtualRoute, computeSharedBindings, detectCodeSplitGroupingsFromRoute } from "./code-splitter/compilers.js";
|
|
6
5
|
import { getReferenceRouteCompilerPlugins } from "./code-splitter/plugins/framework-plugins.js";
|
|
7
6
|
import { createRouterPluginContext } from "./router-plugin-context.js";
|
|
8
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
9
|
-
import { logDiff } from "@tanstack/router-utils";
|
|
8
|
+
import { decodeIdentifier, logDiff } from "@tanstack/router-utils";
|
|
10
9
|
//#region src/core/router-code-splitter-plugin.ts
|
|
11
10
|
/**
|
|
12
11
|
* It is important to familiarize yourself with how the code-splitting works in this plugin.
|
|
@@ -65,7 +64,7 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
65
64
|
if (fromCode.groupings !== void 0) {
|
|
66
65
|
const res = splitGroupingsSchema.safeParse(fromCode.groupings);
|
|
67
66
|
if (!res.success) {
|
|
68
|
-
const message = res.error.
|
|
67
|
+
const message = res.error.issues.map((e) => e.message).join(". ");
|
|
69
68
|
throw new Error(`The groupings for the route "${id}" are invalid.\n${message}`);
|
|
70
69
|
}
|
|
71
70
|
}
|
|
@@ -73,7 +72,7 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
73
72
|
if (pluginSplitBehavior) {
|
|
74
73
|
const res = splitGroupingsSchema.safeParse(pluginSplitBehavior);
|
|
75
74
|
if (!res.success) {
|
|
76
|
-
const message = res.error.
|
|
75
|
+
const message = res.error.issues.map((e) => e.message).join(". ");
|
|
77
76
|
throw new Error(`The groupings returned when using \`splitBehavior\` for the route "${id}" are invalid.\n${message}`);
|
|
78
77
|
}
|
|
79
78
|
}
|
|
@@ -98,11 +97,11 @@ function createRouterCodeSplitterPlugin(options = {}, routerPluginContext) {
|
|
|
98
97
|
hmrStyle,
|
|
99
98
|
hmrRouteId: generatorNodeInfo.routeId,
|
|
100
99
|
sharedBindings: sharedBindings.size > 0 ? sharedBindings : void 0,
|
|
101
|
-
compilerPlugins: getReferenceRouteCompilerPlugins({
|
|
100
|
+
compilerPlugins: [...getReferenceRouteCompilerPlugins({
|
|
102
101
|
targetFramework: userConfig.target,
|
|
103
102
|
addHmr,
|
|
104
103
|
hmrStyle
|
|
105
|
-
})
|
|
104
|
+
}) ?? [], ...userConfig.codeSplittingOptions?.compilerPlugins ?? []]
|
|
106
105
|
});
|
|
107
106
|
if (compiledReferenceRoute === null) {
|
|
108
107
|
if (debug) console.info(`No changes made to route "${id}", skipping code-splitting.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router-code-splitter-plugin.js","names":[],"sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitSharedRoute,\n compileCodeSplitVirtualRoute,\n computeSharedBindings,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrShared,\n tsrSplit,\n} from './constants'\nimport { decodeIdentifier } from './code-splitter/path-ids'\nimport { debug, normalizePath, routeFactoryCallCodeFilter } from './utils'\nimport { createRouterPluginContext } from './router-plugin-context'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type { RouterPluginContext } from './router-plugin-context'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst CODE_SPLITTER_PLUGIN_NAME =\n 'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n pluginNames: Array<string>\n pkg: string\n usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n string,\n Array<TransformationPluginInfo>\n> = {\n react: [\n {\n // Babel-based React plugin\n pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n pkg: '@vitejs/plugin-react',\n usage: 'react()',\n },\n {\n // SWC-based React plugin\n pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n pkg: '@vitejs/plugin-react-swc',\n usage: 'reactSwc()',\n },\n {\n // OXC-based React plugin (deprecated but should still be handled)\n pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n pkg: '@vitejs/plugin-react-oxc',\n usage: 'reactOxc()',\n },\n ],\n solid: [\n {\n pluginNames: ['solid'],\n pkg: 'vite-plugin-solid',\n usage: 'solid()',\n },\n ],\n}\n\nexport function createRouterCodeSplitterPlugin(\n options: Partial<Config | (() => Config)> | undefined = {},\n routerPluginContext: RouterPluginContext,\n): ReturnType<UnpluginFactory<Partial<Config | (() => Config)> | undefined>> {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n // Map from normalized route file path → set of shared binding names.\n // Populated by the reference compiler, consumed by virtual and shared compilers.\n const sharedBindingsMap = new Map<string, Set<string>>()\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n filename: id,\n })\n\n if (fromCode.groupings !== undefined) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routeId,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.errors.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings ?? pluginSplitBehavior ?? getGlobalCodeSplitGroupings()\n\n // Compute shared bindings before compiling the reference route\n const sharedBindings = computeSharedBindings({\n code,\n filename: id,\n codeSplitGroupings: splitGroupings,\n })\n if (sharedBindings.size > 0) {\n sharedBindingsMap.set(id, sharedBindings)\n } else {\n sharedBindingsMap.delete(id)\n }\n\n const addHmr =\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n const hmrStyle = userConfig.plugin?.hmr?.style ?? 'vite'\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr,\n hmrStyle,\n hmrRouteId: generatorNodeInfo.routeId,\n sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n compilerPlugins: getReferenceRouteCompilerPlugins({\n targetFramework: userConfig.target,\n addHmr,\n hmrStyle,\n }),\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const baseId = id.split('?')[0]!\n const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n sharedBindings: resolvedSharedBindings,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: [tsrSplit, tsrShared],\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: routeFactoryCallCodeFilter,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n routerPluginContext.routesByFile.get(normalizedId)\n if (generatorFileInfo) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n\n // Validate plugin order - router must come before JSX transformation plugins\n const routerPluginIndex = config.plugins.findIndex(\n (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n )\n\n if (routerPluginIndex === -1) return\n\n const frameworkPlugins =\n TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n if (!frameworkPlugins) return\n\n for (const transformPlugin of frameworkPlugins) {\n const transformPluginIndex = config.plugins.findIndex((p) =>\n transformPlugin.pluginNames.includes(p.name),\n )\n\n if (\n transformPluginIndex !== -1 &&\n transformPluginIndex < routerPluginIndex\n ) {\n throw new Error(\n `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n `Please update your Vite config:\\n\\n` +\n ` plugins: [\\n` +\n ` tanstackRouter(),\\n` +\n ` ${transformPlugin.usage},\\n` +\n ` ]\\n`,\n )\n }\n }\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-shared-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-shared/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n const [baseId] = normalizedId.split('?')\n\n if (!baseId) return null\n\n const sharedBindings = sharedBindingsMap.get(baseId)\n if (!sharedBindings || sharedBindings.size === 0) return null\n\n if (debug) console.info('Compiling Shared Module: ', id)\n\n const result = compileCodeSplitSharedRoute({\n code,\n sharedBindings,\n filename: normalizedId,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n ]\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\n return createRouterCodeSplitterPlugin(options, createRouterPluginContext())\n}\n"],"mappings":";;;;;;;;;;;;;;AAkCA,IAAM,4BACJ;;;;;AAYF,IAAM,sCAGF;CACF,OAAO;EACL;GAEE,aAAa,CAAC,oBAAoB,qBAAqB;GACvD,KAAK;GACL,OAAO;GACR;EACD;GAEE,aAAa,CAAC,kBAAkB,iCAAiC;GACjE,KAAK;GACL,OAAO;GACR;EACD;GAEE,aAAa,CAAC,yBAAyB,iCAAiC;GACxE,KAAK;GACL,OAAO;GACR;EACF;CACD,OAAO,CACL;EACE,aAAa,CAAC,QAAQ;EACtB,KAAK;EACL,OAAO;EACR,CACF;CACF;AAED,SAAgB,+BACd,UAAwD,EAAE,EAC1D,qBAC2E;CAC3E,IAAI,OAAe,QAAQ,KAAK;CAChC,IAAI;CAEJ,SAAS,iBAAiB;AACxB,MAAI,OAAO,YAAY,WACrB,cAAa,SAAS;MAEtB,cAAa,UAAU,SAAS,KAAK;;CAGzC,MAAM,eAAA,QAAA,IAAA,aAAwC;CAG9C,MAAM,oCAAoB,IAAI,KAA0B;CAExD,MAAM,oCAAoC;AACxC,SACE,WAAW,sBAAsB,mBACjC;;CAGJ,MAAM,yBAAyB;AAC7B,SAAO,WAAW,sBAAsB;;CAG1C,MAAM,gCACJ,MACA,IACA,sBAC4B;AAC5B,MAAI,MAAO,SAAQ,KAAK,qBAAqB,GAAG;EAEhD,MAAM,WAAW,kCAAkC;GACjD;GACA,UAAU;GACX,CAAC;AAEF,MAAI,SAAS,cAAc,KAAA,GAAW;GACpC,MAAM,MAAM,qBAAqB,UAAU,SAAS,UAAU;AAC9D,OAAI,CAAC,IAAI,SAAS;IAChB,MAAM,UAAU,IAAI,MAAM,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK;AACjE,UAAM,IAAI,MACR,gCAAgC,GAAG,kBAAkB,UACtD;;;EAML,MAAM,sBAFoB,kBAAkB,GAEI,EAC9C,SAAS,kBAAkB,SAC5B,CAAC;AAEF,MAAI,qBAAqB;GACvB,MAAM,MAAM,qBAAqB,UAAU,oBAAoB;AAC/D,OAAI,CAAC,IAAI,SAAS;IAChB,MAAM,UAAU,IAAI,MAAM,OAAO,KAAK,MAAM,EAAE,QAAQ,CAAC,KAAK,KAAK;AACjE,UAAM,IAAI,MACR,sEAAsE,GAAG,kBAAkB,UAC5F;;;EAIL,MAAM,iBACJ,SAAS,aAAa,uBAAuB,6BAA6B;EAG5E,MAAM,iBAAiB,sBAAsB;GAC3C;GACA,UAAU;GACV,oBAAoB;GACrB,CAAC;AACF,MAAI,eAAe,OAAO,EACxB,mBAAkB,IAAI,IAAI,eAAe;MAEzC,mBAAkB,OAAO,GAAG;EAG9B,MAAM,UACH,WAAW,sBAAsB,UAAU,SAAS,CAAC;EACxD,MAAM,WAAW,WAAW,QAAQ,KAAK,SAAS;EAElD,MAAM,yBAAyB,+BAA+B;GAC5D;GACA,oBAAoB;GACpB,iBAAiB,WAAW;GAC5B,UAAU;GACV;GACA,aAAa,WAAW,sBAAsB,cAC1C,IAAI,IAAI,WAAW,qBAAqB,YAAY,GACpD,KAAA;GACJ;GACA;GACA,YAAY,kBAAkB;GAC9B,gBAAgB,eAAe,OAAO,IAAI,iBAAiB,KAAA;GAC3D,iBAAiB,iCAAiC;IAChD,iBAAiB,WAAW;IAC5B;IACA;IACD,CAAC;GACH,CAAC;AAEF,MAAI,2BAA2B,MAAM;AACnC,OAAI,MACF,SAAQ,KACN,6BAA6B,GAAG,6BACjC;AAEH,UAAO;;AAET,MAAI,OAAO;AACT,WAAQ,MAAM,uBAAuB,KAAK;AAC1C,WAAQ,IAAI,aAAa,uBAAuB,OAAO,OAAO;;AAGhE,SAAO;;CAGT,MAAM,8BACJ,MACA,OAC4B;AAC5B,MAAI,MAAO,SAAQ,KAAK,qBAAqB,GAAG;EAEhD,MAAM,CAAC,GAAG,GAAG,iBAAiB,GAAG,MAAM,IAAI;EAG3C,MAAM,aADe,IAAI,gBAAgB,cAAc,KAAK,IAAI,CAAC,CACjC,IAAI,SAAS;AAE7C,MAAI,CAAC,WACH,OAAM,IAAI,MACR,0CAA0C,GAAG,kBAC9C;EAGH,MAAM,cAAc,iBAAiB,WAAW;EAChD,MAAM,WAAW,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC,CAAC,QAAQ,MACjD,qBAAqB,SAAS,EAAS,CACxC;EAED,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC;EAG7B,MAAM,SAAS,6BAA6B;GAC1C;GACA,UAAU;GACV,cAAc;GACd,gBAN6B,kBAAkB,IAAI,OAAO;GAO3D,CAAC;AAEF,MAAI,OAAO;AACT,WAAQ,MAAM,OAAO,KAAK;AAC1B,WAAQ,IAAI,aAAa,OAAO,OAAO,OAAO;;AAGhD,SAAO;;AAGT,QAAO;EACL;GACE,MAAM;GACN,SAAS;GAET,WAAW;IACT,QAAQ;KACN,IAAI;MACF,SAAS,CAAC,UAAU,UAAU;MAE9B,SAAS;MACV;KACD,MAAM,EACJ,SAAS,4BACV;KACF;IACD,QAAQ,MAAM,IAAI;KAChB,MAAM,eAAe,cAAc,GAAG;KACtC,MAAM,oBACJ,oBAAoB,aAAa,IAAI,aAAa;AACpD,SAAI,kBACF,QAAO,6BACL,MACA,cACA,kBACD;AAGH,YAAO;;IAEV;GAED,MAAM;IACJ,eAAe,QAAQ;AACrB,YAAO,OAAO;AACd,qBAAgB;KAGhB,MAAM,oBAAoB,OAAO,QAAQ,WACtC,MAAM,EAAE,SAAS,0BACnB;AAED,SAAI,sBAAsB,GAAI;KAE9B,MAAM,mBACJ,oCAAoC,WAAW;AACjD,SAAI,CAAC,iBAAkB;AAEvB,UAAK,MAAM,mBAAmB,kBAAkB;MAC9C,MAAM,uBAAuB,OAAO,QAAQ,WAAW,MACrD,gBAAgB,YAAY,SAAS,EAAE,KAAK,CAC7C;AAED,UACE,yBAAyB,MACzB,uBAAuB,kBAEvB,OAAM,IAAI,MACR,wBAAwB,gBAAgB,IAAI,0MAKnC,gBAAgB,MAAM,UAEhC;;;IAIP,mBAAmB,aAAa;AAC9B,SAAI,WAAW,QAAQ,MAAM,gBAC3B,QAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAEhE,YAAO;;IAEV;GAED,SAAS;AACP,WAAO,QAAQ,KAAK;AACpB,oBAAgB;;GAGlB,UAAU;AACR,WAAO,QAAQ,KAAK;AACpB,oBAAgB;;GAEnB;EACD;GACE,MAAM;GACN,SAAS;GAET,WAAW;IACT,QAAQ,EACN,IAAI,aACL;IACD,QAAQ,MAAM,IAAI;KAChB,MAAM,MAAM,cAAc,GAAG;AAC7B,SAAI,aAAa,OAAO,IAAI;AAE5B,YAAO,2BAA2B,MADb,cAAc,cAAc,IAAI,CAAC,CACD;;IAExD;GAED,MAAM,EACJ,mBAAmB,aAAa;AAC9B,QAAI,WAAW,QAAQ,MAAM,gBAC3B,QAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAEhE,WAAO;MAEV;GACF;EACD;GACE,MAAM;GACN,SAAS;GAET,WAAW;IACT,QAAQ,EACN,IAAI,cACL;IACD,QAAQ,MAAM,IAAI;KAChB,MAAM,MAAM,cAAc,GAAG;AAC7B,SAAI,aAAa,OAAO,IAAI;KAC5B,MAAM,eAAe,cAAc,cAAc,IAAI,CAAC;KACtD,MAAM,CAAC,UAAU,aAAa,MAAM,IAAI;AAExC,SAAI,CAAC,OAAQ,QAAO;KAEpB,MAAM,iBAAiB,kBAAkB,IAAI,OAAO;AACpD,SAAI,CAAC,kBAAkB,eAAe,SAAS,EAAG,QAAO;AAEzD,SAAI,MAAO,SAAQ,KAAK,6BAA6B,GAAG;KAExD,MAAM,SAAS,4BAA4B;MACzC;MACA;MACA,UAAU;MACX,CAAC;AAEF,SAAI,OAAO;AACT,cAAQ,MAAM,OAAO,KAAK;AAC1B,cAAQ,IAAI,aAAa,OAAO,OAAO,OAAO;;AAGhD,YAAO;;IAEV;GAED,MAAM,EACJ,mBAAmB,aAAa;AAC9B,QAAI,WAAW,QAAQ,MAAM,gBAC3B,QAAO,WAAW,OAAO,KAAK,oBAAoB,YAAY;AAEhE,WAAO;MAEV;GACF;EACF;;AAGH,IAAa,qCAER,UAAU,EAAE,KAAK;AACpB,QAAO,+BAA+B,SAAS,2BAA2B,CAAC"}
|
|
1
|
+
{"version":3,"file":"router-code-splitter-plugin.js","names":[],"sources":["../../../src/core/router-code-splitter-plugin.ts"],"sourcesContent":["/**\n * It is important to familiarize yourself with how the code-splitting works in this plugin.\n * https://github.com/TanStack/router/pull/3355\n */\n\nimport { fileURLToPath, pathToFileURL } from 'node:url'\nimport { decodeIdentifier, logDiff } from '@tanstack/router-utils'\nimport { getConfig, splitGroupingsSchema } from './config'\nimport {\n compileCodeSplitReferenceRoute,\n compileCodeSplitSharedRoute,\n compileCodeSplitVirtualRoute,\n computeSharedBindings,\n detectCodeSplitGroupingsFromRoute,\n} from './code-splitter/compilers'\nimport { getReferenceRouteCompilerPlugins } from './code-splitter/plugins/framework-plugins'\nimport {\n defaultCodeSplitGroupings,\n splitRouteIdentNodes,\n tsrShared,\n tsrSplit,\n} from './constants'\nimport { debug, normalizePath, routeFactoryCallCodeFilter } from './utils'\nimport { createRouterPluginContext } from './router-plugin-context'\nimport type { CodeSplitGroupings, SplitRouteIdentNodes } from './constants'\nimport type { GetRoutesByFileMapResultValue } from '@tanstack/router-generator'\nimport type { Config } from './config'\nimport type { RouterPluginContext } from './router-plugin-context'\nimport type {\n UnpluginFactory,\n TransformResult as UnpluginTransformResult,\n} from 'unplugin'\n\nconst CODE_SPLITTER_PLUGIN_NAME =\n 'tanstack-router:code-splitter:compile-reference-file'\n\ntype TransformationPluginInfo = {\n pluginNames: Array<string>\n pkg: string\n usage: string\n}\n\n/**\n * JSX transformation plugins grouped by framework.\n * These plugins must come AFTER the TanStack Router plugin in the Vite config.\n */\nconst TRANSFORMATION_PLUGINS_BY_FRAMEWORK: Record<\n string,\n Array<TransformationPluginInfo>\n> = {\n react: [\n {\n // Babel-based React plugin\n pluginNames: ['vite:react-babel', 'vite:react-refresh'],\n pkg: '@vitejs/plugin-react',\n usage: 'react()',\n },\n {\n // SWC-based React plugin\n pluginNames: ['vite:react-swc', 'vite:react-swc:resolve-runtime'],\n pkg: '@vitejs/plugin-react-swc',\n usage: 'reactSwc()',\n },\n {\n // OXC-based React plugin (deprecated but should still be handled)\n pluginNames: ['vite:react-oxc:config', 'vite:react-oxc:refresh-runtime'],\n pkg: '@vitejs/plugin-react-oxc',\n usage: 'reactOxc()',\n },\n ],\n solid: [\n {\n pluginNames: ['solid'],\n pkg: 'vite-plugin-solid',\n usage: 'solid()',\n },\n ],\n}\n\nexport function createRouterCodeSplitterPlugin(\n options: Partial<Config | (() => Config)> | undefined = {},\n routerPluginContext: RouterPluginContext,\n): ReturnType<UnpluginFactory<Partial<Config | (() => Config)> | undefined>> {\n let ROOT: string = process.cwd()\n let userConfig: Config\n\n function initUserConfig() {\n if (typeof options === 'function') {\n userConfig = options()\n } else {\n userConfig = getConfig(options, ROOT)\n }\n }\n const isProduction = process.env.NODE_ENV === 'production'\n // Map from normalized route file path → set of shared binding names.\n // Populated by the reference compiler, consumed by virtual and shared compilers.\n const sharedBindingsMap = new Map<string, Set<string>>()\n\n const getGlobalCodeSplitGroupings = () => {\n return (\n userConfig.codeSplittingOptions?.defaultBehavior ||\n defaultCodeSplitGroupings\n )\n }\n const getShouldSplitFn = () => {\n return userConfig.codeSplittingOptions?.splitBehavior\n }\n\n const handleCompilingReferenceFile = (\n code: string,\n id: string,\n generatorNodeInfo: GetRoutesByFileMapResultValue,\n ): UnpluginTransformResult => {\n if (debug) console.info('Compiling Route: ', id)\n\n const fromCode = detectCodeSplitGroupingsFromRoute({\n code,\n filename: id,\n })\n\n if (fromCode.groupings !== undefined) {\n const res = splitGroupingsSchema.safeParse(fromCode.groupings)\n if (!res.success) {\n const message = res.error.issues.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const userShouldSplitFn = getShouldSplitFn()\n\n const pluginSplitBehavior = userShouldSplitFn?.({\n routeId: generatorNodeInfo.routeId,\n }) as CodeSplitGroupings | undefined\n\n if (pluginSplitBehavior) {\n const res = splitGroupingsSchema.safeParse(pluginSplitBehavior)\n if (!res.success) {\n const message = res.error.issues.map((e) => e.message).join('. ')\n throw new Error(\n `The groupings returned when using \\`splitBehavior\\` for the route \"${id}\" are invalid.\\n${message}`,\n )\n }\n }\n\n const splitGroupings: CodeSplitGroupings =\n fromCode.groupings ?? pluginSplitBehavior ?? getGlobalCodeSplitGroupings()\n\n // Compute shared bindings before compiling the reference route\n const sharedBindings = computeSharedBindings({\n code,\n filename: id,\n codeSplitGroupings: splitGroupings,\n })\n if (sharedBindings.size > 0) {\n sharedBindingsMap.set(id, sharedBindings)\n } else {\n sharedBindingsMap.delete(id)\n }\n\n const addHmr =\n (userConfig.codeSplittingOptions?.addHmr ?? true) && !isProduction\n const hmrStyle = userConfig.plugin?.hmr?.style ?? 'vite'\n\n const compiledReferenceRoute = compileCodeSplitReferenceRoute({\n code,\n codeSplitGroupings: splitGroupings,\n targetFramework: userConfig.target,\n filename: id,\n id,\n deleteNodes: userConfig.codeSplittingOptions?.deleteNodes\n ? new Set(userConfig.codeSplittingOptions.deleteNodes)\n : undefined,\n addHmr,\n hmrStyle,\n hmrRouteId: generatorNodeInfo.routeId,\n sharedBindings: sharedBindings.size > 0 ? sharedBindings : undefined,\n compilerPlugins: [\n ...(getReferenceRouteCompilerPlugins({\n targetFramework: userConfig.target,\n addHmr,\n hmrStyle,\n }) ?? []),\n ...(userConfig.codeSplittingOptions?.compilerPlugins ?? []),\n ],\n })\n\n if (compiledReferenceRoute === null) {\n if (debug) {\n console.info(\n `No changes made to route \"${id}\", skipping code-splitting.`,\n )\n }\n return null\n }\n if (debug) {\n logDiff(code, compiledReferenceRoute.code)\n console.log('Output:\\n', compiledReferenceRoute.code + '\\n\\n')\n }\n\n return compiledReferenceRoute\n }\n\n const handleCompilingVirtualFile = (\n code: string,\n id: string,\n ): UnpluginTransformResult => {\n if (debug) console.info('Splitting Route: ', id)\n\n const [_, ...pathnameParts] = id.split('?')\n\n const searchParams = new URLSearchParams(pathnameParts.join('?'))\n const splitValue = searchParams.get(tsrSplit)\n\n if (!splitValue) {\n throw new Error(\n `The split value for the virtual route \"${id}\" was not found.`,\n )\n }\n\n const rawGrouping = decodeIdentifier(splitValue)\n const grouping = [...new Set(rawGrouping)].filter((p) =>\n splitRouteIdentNodes.includes(p as any),\n ) as Array<SplitRouteIdentNodes>\n\n const baseId = id.split('?')[0]!\n const resolvedSharedBindings = sharedBindingsMap.get(baseId)\n\n const result = compileCodeSplitVirtualRoute({\n code,\n filename: id,\n splitTargets: grouping,\n sharedBindings: resolvedSharedBindings,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n }\n\n return [\n {\n name: 'tanstack-router:code-splitter:compile-reference-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: {\n exclude: [tsrSplit, tsrShared],\n // this is necessary for webpack / rspack to avoid matching .html files\n include: /\\.(m|c)?(j|t)sx?$/,\n },\n code: {\n include: routeFactoryCallCodeFilter,\n },\n },\n handler(code, id) {\n const normalizedId = normalizePath(id)\n const generatorFileInfo =\n routerPluginContext.routesByFile.get(normalizedId)\n if (generatorFileInfo) {\n return handleCompilingReferenceFile(\n code,\n normalizedId,\n generatorFileInfo,\n )\n }\n\n return null\n },\n },\n\n vite: {\n configResolved(config) {\n ROOT = config.root\n initUserConfig()\n\n // Validate plugin order - router must come before JSX transformation plugins\n const routerPluginIndex = config.plugins.findIndex(\n (p) => p.name === CODE_SPLITTER_PLUGIN_NAME,\n )\n\n if (routerPluginIndex === -1) return\n\n const frameworkPlugins =\n TRANSFORMATION_PLUGINS_BY_FRAMEWORK[userConfig.target]\n if (!frameworkPlugins) return\n\n for (const transformPlugin of frameworkPlugins) {\n const transformPluginIndex = config.plugins.findIndex((p) =>\n transformPlugin.pluginNames.includes(p.name),\n )\n\n if (\n transformPluginIndex !== -1 &&\n transformPluginIndex < routerPluginIndex\n ) {\n throw new Error(\n `Plugin order error: '${transformPlugin.pkg}' is placed before '@tanstack/router-plugin'.\\n\\n` +\n `The TanStack Router plugin must come BEFORE JSX transformation plugins.\\n\\n` +\n `Please update your Vite config:\\n\\n` +\n ` plugins: [\\n` +\n ` tanstackRouter(),\\n` +\n ` ${transformPlugin.usage},\\n` +\n ` ]\\n`,\n )\n }\n }\n },\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n\n rspack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n\n webpack() {\n ROOT = process.cwd()\n initUserConfig()\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-virtual-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-split/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n return handleCompilingVirtualFile(code, normalizedId)\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n {\n name: 'tanstack-router:code-splitter:compile-shared-file',\n enforce: 'pre',\n\n transform: {\n filter: {\n id: /tsr-shared/,\n },\n handler(code, id) {\n const url = pathToFileURL(id)\n url.searchParams.delete('v')\n const normalizedId = normalizePath(fileURLToPath(url))\n const [baseId] = normalizedId.split('?')\n\n if (!baseId) return null\n\n const sharedBindings = sharedBindingsMap.get(baseId)\n if (!sharedBindings || sharedBindings.size === 0) return null\n\n if (debug) console.info('Compiling Shared Module: ', id)\n\n const result = compileCodeSplitSharedRoute({\n code,\n sharedBindings,\n filename: normalizedId,\n })\n\n if (debug) {\n logDiff(code, result.code)\n console.log('Output:\\n', result.code + '\\n\\n')\n }\n\n return result\n },\n },\n\n vite: {\n applyToEnvironment(environment) {\n if (userConfig.plugin?.vite?.environmentName) {\n return userConfig.plugin.vite.environmentName === environment.name\n }\n return true\n },\n },\n },\n ]\n}\n\nexport const unpluginRouterCodeSplitterFactory: UnpluginFactory<\n Partial<Config | (() => Config)> | undefined\n> = (options = {}) => {\n return createRouterCodeSplitterPlugin(options, createRouterPluginContext())\n}\n"],"mappings":"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"}
|