@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.
- package/dist/cjs/core/code-splitter/compilers.cjs +195 -194
- package/dist/cjs/core/code-splitter/compilers.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/compilers.d.cts +3 -0
- package/dist/cjs/core/code-splitter/framework-options.cjs +4 -8
- package/dist/cjs/core/code-splitter/framework-options.cjs.map +1 -1
- package/dist/cjs/core/code-splitter/framework-options.d.cts +0 -2
- package/dist/cjs/core/config.d.cts +31 -40
- package/dist/cjs/core/route-autoimport-plugin.cjs +98 -0
- package/dist/cjs/core/route-autoimport-plugin.cjs.map +1 -0
- package/dist/cjs/core/route-autoimport-plugin.d.cts +6 -0
- package/dist/cjs/core/route-hmr-statement.cjs +33 -0
- package/dist/cjs/core/route-hmr-statement.cjs.map +1 -0
- package/dist/cjs/core/route-hmr-statement.d.cts +1 -0
- package/dist/cjs/core/router-code-splitter-plugin.cjs +11 -20
- package/dist/cjs/core/router-code-splitter-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-composed-plugin.cjs +19 -5
- package/dist/cjs/core/router-composed-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-generator-plugin.cjs +8 -2
- package/dist/cjs/core/router-generator-plugin.cjs.map +1 -1
- package/dist/cjs/core/router-hmr-plugin.cjs +51 -0
- package/dist/cjs/core/router-hmr-plugin.cjs.map +1 -0
- package/dist/cjs/core/router-hmr-plugin.d.cts +8 -0
- package/dist/cjs/core/utils.cjs +12 -0
- package/dist/cjs/core/utils.cjs.map +1 -0
- package/dist/cjs/core/utils.d.cts +2 -0
- package/dist/cjs/esbuild.cjs +2 -0
- package/dist/cjs/esbuild.cjs.map +1 -1
- package/dist/cjs/esbuild.d.cts +53 -27
- package/dist/cjs/rspack.cjs +2 -0
- package/dist/cjs/rspack.cjs.map +1 -1
- package/dist/cjs/rspack.d.cts +53 -27
- package/dist/cjs/vite.cjs +2 -0
- package/dist/cjs/vite.cjs.map +1 -1
- package/dist/cjs/vite.d.cts +52 -26
- package/dist/cjs/webpack.cjs +2 -0
- package/dist/cjs/webpack.cjs.map +1 -1
- package/dist/cjs/webpack.d.cts +53 -27
- package/dist/esm/core/code-splitter/compilers.d.ts +3 -0
- package/dist/esm/core/code-splitter/compilers.js +195 -194
- package/dist/esm/core/code-splitter/compilers.js.map +1 -1
- package/dist/esm/core/code-splitter/framework-options.d.ts +0 -2
- package/dist/esm/core/code-splitter/framework-options.js +4 -8
- package/dist/esm/core/code-splitter/framework-options.js.map +1 -1
- package/dist/esm/core/config.d.ts +31 -40
- package/dist/esm/core/route-autoimport-plugin.d.ts +6 -0
- package/dist/esm/core/route-autoimport-plugin.js +81 -0
- package/dist/esm/core/route-autoimport-plugin.js.map +1 -0
- package/dist/esm/core/route-hmr-statement.d.ts +1 -0
- package/dist/esm/core/route-hmr-statement.js +16 -0
- package/dist/esm/core/route-hmr-statement.js.map +1 -0
- package/dist/esm/core/router-code-splitter-plugin.js +5 -14
- package/dist/esm/core/router-code-splitter-plugin.js.map +1 -1
- package/dist/esm/core/router-composed-plugin.js +19 -5
- package/dist/esm/core/router-composed-plugin.js.map +1 -1
- package/dist/esm/core/router-generator-plugin.js +8 -2
- package/dist/esm/core/router-generator-plugin.js.map +1 -1
- package/dist/esm/core/router-hmr-plugin.d.ts +8 -0
- package/dist/esm/core/router-hmr-plugin.js +51 -0
- package/dist/esm/core/router-hmr-plugin.js.map +1 -0
- package/dist/esm/core/utils.d.ts +2 -0
- package/dist/esm/core/utils.js +12 -0
- package/dist/esm/core/utils.js.map +1 -0
- package/dist/esm/esbuild.d.ts +53 -27
- package/dist/esm/esbuild.js +3 -1
- package/dist/esm/esbuild.js.map +1 -1
- package/dist/esm/rspack.d.ts +53 -27
- package/dist/esm/rspack.js +3 -1
- package/dist/esm/rspack.js.map +1 -1
- package/dist/esm/vite.d.ts +52 -26
- package/dist/esm/vite.js +3 -1
- package/dist/esm/vite.js.map +1 -1
- package/dist/esm/webpack.d.ts +53 -27
- package/dist/esm/webpack.js +3 -1
- package/dist/esm/webpack.js.map +1 -1
- package/package.json +6 -6
- package/src/core/code-splitter/compilers.ts +265 -277
- package/src/core/code-splitter/framework-options.ts +0 -6
- package/src/core/route-autoimport-plugin.ts +102 -0
- package/src/core/route-hmr-statement.ts +13 -0
- package/src/core/router-code-splitter-plugin.ts +3 -23
- package/src/core/router-composed-plugin.ts +20 -10
- package/src/core/router-generator-plugin.ts +12 -1
- package/src/core/router-hmr-plugin.ts +65 -0
- package/src/core/utils.ts +18 -0
- package/src/esbuild.ts +3 -2
- package/src/rspack.ts +3 -2
- package/src/vite.ts +3 -0
- package/src/webpack.ts +3 -1
|
@@ -7,33 +7,13 @@ import {
|
|
|
7
7
|
} from 'babel-dead-code-elimination'
|
|
8
8
|
import { generateFromAst, parseAst } from '@tanstack/router-utils'
|
|
9
9
|
import { tsrSplit } from '../constants'
|
|
10
|
+
import { routeHmrStatement } from '../route-hmr-statement'
|
|
10
11
|
import { createIdentifier } from './path-ids'
|
|
11
12
|
import { getFrameworkOptions } from './framework-options'
|
|
12
13
|
import type { GeneratorResult, ParseAstOptions } from '@tanstack/router-utils'
|
|
13
14
|
import type { CodeSplitGroupings, SplitRouteIdentNodes } from '../constants'
|
|
14
15
|
import type { Config } from '../config'
|
|
15
16
|
|
|
16
|
-
// eslint-disable-next-line unused-imports/no-unused-vars
|
|
17
|
-
const debug = process.env.TSR_VITE_DEBUG
|
|
18
|
-
|
|
19
|
-
type SplitModulesById = Record<
|
|
20
|
-
string,
|
|
21
|
-
{ id: string; node: t.FunctionExpression }
|
|
22
|
-
>
|
|
23
|
-
|
|
24
|
-
interface State {
|
|
25
|
-
filename: string
|
|
26
|
-
opts: {
|
|
27
|
-
minify: boolean
|
|
28
|
-
root: string
|
|
29
|
-
}
|
|
30
|
-
imported: Record<string, boolean>
|
|
31
|
-
refs: Set<any>
|
|
32
|
-
serverIndex: number
|
|
33
|
-
splitIndex: number
|
|
34
|
-
splitModulesById: SplitModulesById
|
|
35
|
-
}
|
|
36
|
-
|
|
37
17
|
type SplitNodeMeta = {
|
|
38
18
|
routeIdent: SplitRouteIdentNodes
|
|
39
19
|
splitStrategy: 'lazyFn' | 'lazyRouteComponent'
|
|
@@ -117,6 +97,8 @@ export function compileCodeSplitReferenceRoute(
|
|
|
117
97
|
runtimeEnv: 'dev' | 'prod'
|
|
118
98
|
codeSplitGroupings: CodeSplitGroupings
|
|
119
99
|
targetFramework: Config['target']
|
|
100
|
+
filename: string
|
|
101
|
+
id: string
|
|
120
102
|
},
|
|
121
103
|
): GeneratorResult {
|
|
122
104
|
const ast = parseAst(opts)
|
|
@@ -136,9 +118,7 @@ export function compileCodeSplitReferenceRoute(
|
|
|
136
118
|
|
|
137
119
|
babel.traverse(ast, {
|
|
138
120
|
Program: {
|
|
139
|
-
enter(programPath
|
|
140
|
-
const state = programState as unknown as State
|
|
141
|
-
|
|
121
|
+
enter(programPath) {
|
|
142
122
|
/**
|
|
143
123
|
* If the component for the route is being imported from
|
|
144
124
|
* another file, this is to track the path to that file
|
|
@@ -150,229 +130,228 @@ export function compileCodeSplitReferenceRoute(
|
|
|
150
130
|
*/
|
|
151
131
|
const removableImportPaths = new Set<string>([])
|
|
152
132
|
|
|
153
|
-
programPath.traverse(
|
|
154
|
-
{
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (
|
|
161
|
-
!(
|
|
162
|
-
path.node.callee.name === 'createRoute' ||
|
|
163
|
-
path.node.callee.name === 'createFileRoute'
|
|
164
|
-
)
|
|
165
|
-
) {
|
|
166
|
-
return
|
|
167
|
-
}
|
|
133
|
+
programPath.traverse({
|
|
134
|
+
CallExpression: (path) => {
|
|
135
|
+
if (!t.isIdentifier(path.node.callee)) {
|
|
136
|
+
return
|
|
137
|
+
}
|
|
168
138
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
139
|
+
if (
|
|
140
|
+
!(
|
|
141
|
+
path.node.callee.name === 'createRoute' ||
|
|
142
|
+
path.node.callee.name === 'createFileRoute'
|
|
143
|
+
)
|
|
144
|
+
) {
|
|
145
|
+
return
|
|
146
|
+
}
|
|
174
147
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
148
|
+
function babelHandleReference(routeOptions: t.Node | undefined) {
|
|
149
|
+
const hasImportedOrDefinedIdentifier = (name: string) => {
|
|
150
|
+
return programPath.scope.hasBinding(name)
|
|
151
|
+
}
|
|
178
152
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
153
|
+
if (t.isObjectExpression(routeOptions)) {
|
|
154
|
+
routeOptions.properties.forEach((prop) => {
|
|
155
|
+
if (t.isObjectProperty(prop)) {
|
|
156
|
+
if (t.isIdentifier(prop.key)) {
|
|
157
|
+
// If the user has not specified a split grouping for this key
|
|
158
|
+
// then we should not split it
|
|
159
|
+
const codeSplitGroupingByKey = findIndexForSplitNode(
|
|
160
|
+
prop.key.name,
|
|
161
|
+
)
|
|
162
|
+
if (codeSplitGroupingByKey === -1) {
|
|
163
|
+
return
|
|
164
|
+
}
|
|
165
|
+
const codeSplitGroup = [
|
|
166
|
+
...new Set(
|
|
167
|
+
opts.codeSplitGroupings[codeSplitGroupingByKey],
|
|
168
|
+
),
|
|
169
|
+
]
|
|
170
|
+
|
|
171
|
+
const key = prop.key.name
|
|
172
|
+
// find key in nodeSplitConfig
|
|
173
|
+
const isNodeConfigAvailable = SPLIT_NODES_CONFIG.has(
|
|
174
|
+
key as any,
|
|
175
|
+
)
|
|
176
|
+
|
|
177
|
+
if (!isNodeConfigAvailable) {
|
|
178
|
+
return
|
|
179
|
+
}
|
|
206
180
|
|
|
207
|
-
|
|
208
|
-
key as any,
|
|
209
|
-
)!
|
|
181
|
+
const splitNodeMeta = SPLIT_NODES_CONFIG.get(key as any)!
|
|
210
182
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
183
|
+
// We need to extract the existing search params from the filename, if any
|
|
184
|
+
// and add the relevant codesplitPrefix to them, then write them back to the filename
|
|
185
|
+
const splitUrl = addSplitSearchParamToFilename(
|
|
186
|
+
opts.filename,
|
|
187
|
+
codeSplitGroup,
|
|
188
|
+
)
|
|
217
189
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
let shouldSplit = true
|
|
224
|
-
|
|
225
|
-
if (t.isIdentifier(value)) {
|
|
226
|
-
const existingImportPath =
|
|
227
|
-
getImportSpecifierAndPathFromLocalName(
|
|
228
|
-
programPath,
|
|
229
|
-
value.name,
|
|
230
|
-
).path
|
|
231
|
-
if (existingImportPath) {
|
|
232
|
-
removableImportPaths.add(existingImportPath)
|
|
233
|
-
}
|
|
190
|
+
if (
|
|
191
|
+
splitNodeMeta.splitStrategy === 'lazyRouteComponent'
|
|
192
|
+
) {
|
|
193
|
+
const value = prop.value
|
|
234
194
|
|
|
235
|
-
|
|
236
|
-
// since they are already being imported
|
|
237
|
-
// and need to be retained in the compiled file
|
|
238
|
-
const isExported = hasExport(ast, value)
|
|
239
|
-
shouldSplit = !isExported
|
|
195
|
+
let shouldSplit = true
|
|
240
196
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
197
|
+
if (t.isIdentifier(value)) {
|
|
198
|
+
const existingImportPath =
|
|
199
|
+
getImportSpecifierAndPathFromLocalName(
|
|
200
|
+
programPath,
|
|
201
|
+
value.name,
|
|
202
|
+
).path
|
|
203
|
+
if (existingImportPath) {
|
|
204
|
+
removableImportPaths.add(existingImportPath)
|
|
248
205
|
}
|
|
249
206
|
|
|
250
|
-
//
|
|
251
|
-
//
|
|
252
|
-
// to
|
|
207
|
+
// exported identifiers should not be split
|
|
208
|
+
// since they are already being imported
|
|
209
|
+
// and need to be retained in the compiled file
|
|
210
|
+
const isExported = hasExport(ast, value)
|
|
211
|
+
shouldSplit = !isExported
|
|
253
212
|
|
|
254
|
-
if (
|
|
255
|
-
|
|
256
|
-
LAZY_ROUTE_COMPONENT_IDENT,
|
|
257
|
-
)
|
|
258
|
-
) {
|
|
259
|
-
programPath.unshiftContainer('body', [
|
|
260
|
-
template.statement(
|
|
261
|
-
`import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`,
|
|
262
|
-
)(),
|
|
263
|
-
])
|
|
213
|
+
if (shouldSplit) {
|
|
214
|
+
removeIdentifierLiteral(path, value)
|
|
264
215
|
}
|
|
216
|
+
}
|
|
265
217
|
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
!hasImportedOrDefinedIdentifier(
|
|
270
|
-
splitNodeMeta.localImporterIdent,
|
|
271
|
-
)
|
|
272
|
-
) {
|
|
273
|
-
programPath.unshiftContainer('body', [
|
|
274
|
-
template.statement(
|
|
275
|
-
`const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
|
|
276
|
-
)(),
|
|
277
|
-
])
|
|
278
|
-
}
|
|
218
|
+
if (!shouldSplit) {
|
|
219
|
+
return
|
|
220
|
+
}
|
|
279
221
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
`${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}', () => Route.ssr)`,
|
|
284
|
-
)()
|
|
285
|
-
} else {
|
|
286
|
-
prop.value = template.expression(
|
|
287
|
-
`${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
|
|
288
|
-
)()
|
|
289
|
-
}
|
|
222
|
+
// Prepend the import statement to the program along with the importer function
|
|
223
|
+
// Check to see if lazyRouteComponent is already imported before attempting
|
|
224
|
+
// to import it again
|
|
290
225
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
)(),
|
|
302
|
-
])
|
|
303
|
-
}
|
|
226
|
+
if (
|
|
227
|
+
!hasImportedOrDefinedIdentifier(
|
|
228
|
+
LAZY_ROUTE_COMPONENT_IDENT,
|
|
229
|
+
)
|
|
230
|
+
) {
|
|
231
|
+
programPath.unshiftContainer('body', [
|
|
232
|
+
template.statement(
|
|
233
|
+
`import { ${LAZY_ROUTE_COMPONENT_IDENT} } from '${PACKAGE}'`,
|
|
234
|
+
)(),
|
|
235
|
+
])
|
|
304
236
|
}
|
|
305
237
|
|
|
306
|
-
if
|
|
307
|
-
|
|
238
|
+
// Check to see if the importer function is already defined
|
|
239
|
+
// If not, define it with the dynamic import statement
|
|
240
|
+
if (
|
|
241
|
+
!hasImportedOrDefinedIdentifier(
|
|
242
|
+
splitNodeMeta.localImporterIdent,
|
|
243
|
+
)
|
|
244
|
+
) {
|
|
245
|
+
programPath.unshiftContainer('body', [
|
|
246
|
+
template.statement(
|
|
247
|
+
`const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
|
|
248
|
+
)(),
|
|
249
|
+
])
|
|
250
|
+
}
|
|
308
251
|
|
|
309
|
-
|
|
252
|
+
// If it's a component, we need to pass the function to check the Route.ssr value
|
|
253
|
+
if (key === 'component') {
|
|
254
|
+
prop.value = template.expression(
|
|
255
|
+
`${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}', () => Route.ssr)`,
|
|
256
|
+
)()
|
|
257
|
+
} else {
|
|
258
|
+
prop.value = template.expression(
|
|
259
|
+
`${LAZY_ROUTE_COMPONENT_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
|
|
260
|
+
)()
|
|
261
|
+
}
|
|
310
262
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
).path
|
|
317
|
-
if (existingImportPath) {
|
|
318
|
-
removableImportPaths.add(existingImportPath)
|
|
319
|
-
}
|
|
263
|
+
// add HMR handling
|
|
264
|
+
if (opts.runtimeEnv !== 'prod') {
|
|
265
|
+
programPath.pushContainer('body', routeHmrStatement)
|
|
266
|
+
}
|
|
267
|
+
}
|
|
320
268
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
// and need to be retained in the compiled file
|
|
324
|
-
const isExported = hasExport(ast, value)
|
|
325
|
-
shouldSplit = !isExported
|
|
269
|
+
if (splitNodeMeta.splitStrategy === 'lazyFn') {
|
|
270
|
+
const value = prop.value
|
|
326
271
|
|
|
327
|
-
|
|
328
|
-
removeIdentifierLiteral(path, value)
|
|
329
|
-
}
|
|
330
|
-
}
|
|
272
|
+
let shouldSplit = true
|
|
331
273
|
|
|
332
|
-
|
|
333
|
-
|
|
274
|
+
if (t.isIdentifier(value)) {
|
|
275
|
+
const existingImportPath =
|
|
276
|
+
getImportSpecifierAndPathFromLocalName(
|
|
277
|
+
programPath,
|
|
278
|
+
value.name,
|
|
279
|
+
).path
|
|
280
|
+
if (existingImportPath) {
|
|
281
|
+
removableImportPaths.add(existingImportPath)
|
|
334
282
|
}
|
|
335
283
|
|
|
336
|
-
//
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
`import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`,
|
|
342
|
-
)(),
|
|
343
|
-
)
|
|
344
|
-
}
|
|
284
|
+
// exported identifiers should not be split
|
|
285
|
+
// since they are already being imported
|
|
286
|
+
// and need to be retained in the compiled file
|
|
287
|
+
const isExported = hasExport(ast, value)
|
|
288
|
+
shouldSplit = !isExported
|
|
345
289
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (
|
|
349
|
-
!hasImportedOrDefinedIdentifier(
|
|
350
|
-
splitNodeMeta.localImporterIdent,
|
|
351
|
-
)
|
|
352
|
-
) {
|
|
353
|
-
programPath.unshiftContainer('body', [
|
|
354
|
-
template.statement(
|
|
355
|
-
`const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
|
|
356
|
-
)(),
|
|
357
|
-
])
|
|
290
|
+
if (shouldSplit) {
|
|
291
|
+
removeIdentifierLiteral(path, value)
|
|
358
292
|
}
|
|
293
|
+
}
|
|
359
294
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
295
|
+
if (!shouldSplit) {
|
|
296
|
+
return
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
// Prepend the import statement to the program along with the importer function
|
|
300
|
+
if (!hasImportedOrDefinedIdentifier(LAZY_FN_IDENT)) {
|
|
301
|
+
programPath.unshiftContainer(
|
|
302
|
+
'body',
|
|
303
|
+
template.smart(
|
|
304
|
+
`import { ${LAZY_FN_IDENT} } from '${PACKAGE}'`,
|
|
305
|
+
)(),
|
|
306
|
+
)
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// Check to see if the importer function is already defined
|
|
310
|
+
// If not, define it with the dynamic import statement
|
|
311
|
+
if (
|
|
312
|
+
!hasImportedOrDefinedIdentifier(
|
|
313
|
+
splitNodeMeta.localImporterIdent,
|
|
314
|
+
)
|
|
315
|
+
) {
|
|
316
|
+
programPath.unshiftContainer('body', [
|
|
317
|
+
template.statement(
|
|
318
|
+
`const ${splitNodeMeta.localImporterIdent} = () => import('${splitUrl}')`,
|
|
319
|
+
)(),
|
|
320
|
+
])
|
|
364
321
|
}
|
|
322
|
+
|
|
323
|
+
// Add the lazyFn call with the dynamic import to the prop value
|
|
324
|
+
prop.value = template.expression(
|
|
325
|
+
`${LAZY_FN_IDENT}(${splitNodeMeta.localImporterIdent}, '${splitNodeMeta.exporterIdent}')`,
|
|
326
|
+
)()
|
|
365
327
|
}
|
|
366
328
|
}
|
|
329
|
+
}
|
|
367
330
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
}
|
|
331
|
+
programPath.scope.crawl()
|
|
332
|
+
})
|
|
371
333
|
}
|
|
372
|
-
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (t.isCallExpression(path.parentPath.node)) {
|
|
337
|
+
// createFileRoute('/')({ ... })
|
|
338
|
+
const options = resolveIdentifier(
|
|
339
|
+
path,
|
|
340
|
+
path.parentPath.node.arguments[0],
|
|
341
|
+
)
|
|
342
|
+
|
|
343
|
+
babelHandleReference(options)
|
|
344
|
+
} else if (t.isVariableDeclarator(path.parentPath.node)) {
|
|
345
|
+
// createFileRoute({ ... })
|
|
346
|
+
const caller = resolveIdentifier(path, path.parentPath.node.init)
|
|
347
|
+
|
|
348
|
+
if (t.isCallExpression(caller)) {
|
|
349
|
+
const options = resolveIdentifier(path, caller.arguments[0])
|
|
350
|
+
babelHandleReference(options)
|
|
351
|
+
}
|
|
352
|
+
}
|
|
373
353
|
},
|
|
374
|
-
|
|
375
|
-
)
|
|
354
|
+
})
|
|
376
355
|
|
|
377
356
|
/**
|
|
378
357
|
* If the component for the route is being imported,
|
|
@@ -406,6 +385,7 @@ export function compileCodeSplitReferenceRoute(
|
|
|
406
385
|
export function compileCodeSplitVirtualRoute(
|
|
407
386
|
opts: ParseAstOptions & {
|
|
408
387
|
splitTargets: Array<SplitRouteIdentNodes>
|
|
388
|
+
filename: string
|
|
409
389
|
},
|
|
410
390
|
): GeneratorResult {
|
|
411
391
|
const ast = parseAst(opts)
|
|
@@ -417,9 +397,7 @@ export function compileCodeSplitVirtualRoute(
|
|
|
417
397
|
|
|
418
398
|
babel.traverse(ast, {
|
|
419
399
|
Program: {
|
|
420
|
-
enter(programPath
|
|
421
|
-
const state = programState as unknown as State
|
|
422
|
-
|
|
400
|
+
enter(programPath) {
|
|
423
401
|
const trackedNodesToSplitByType: Record<
|
|
424
402
|
SplitRouteIdentNodes,
|
|
425
403
|
{ node: t.Node | undefined; meta: SplitNodeMeta } | undefined
|
|
@@ -432,75 +410,85 @@ export function compileCodeSplitVirtualRoute(
|
|
|
432
410
|
}
|
|
433
411
|
|
|
434
412
|
// Find and track all the known split-able nodes
|
|
435
|
-
programPath.traverse(
|
|
436
|
-
{
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
}
|
|
441
|
-
|
|
442
|
-
if (
|
|
443
|
-
!(
|
|
444
|
-
path.node.callee.name === 'createRoute' ||
|
|
445
|
-
path.node.callee.name === 'createFileRoute'
|
|
446
|
-
)
|
|
447
|
-
) {
|
|
448
|
-
return
|
|
449
|
-
}
|
|
413
|
+
programPath.traverse({
|
|
414
|
+
CallExpression: (path) => {
|
|
415
|
+
if (!t.isIdentifier(path.node.callee)) {
|
|
416
|
+
return
|
|
417
|
+
}
|
|
450
418
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
419
|
+
if (
|
|
420
|
+
!(
|
|
421
|
+
path.node.callee.name === 'createRoute' ||
|
|
422
|
+
path.node.callee.name === 'createFileRoute'
|
|
423
|
+
)
|
|
424
|
+
) {
|
|
425
|
+
return
|
|
426
|
+
}
|
|
456
427
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
428
|
+
function babelHandleVirtual(options: t.Node | undefined) {
|
|
429
|
+
if (t.isObjectExpression(options)) {
|
|
430
|
+
options.properties.forEach((prop) => {
|
|
431
|
+
if (t.isObjectProperty(prop)) {
|
|
432
|
+
// do not use `intendedSplitNodes` here
|
|
433
|
+
// since we have special considerations that need
|
|
434
|
+
// to be accounted for like (not splitting exported identifiers)
|
|
435
|
+
KNOWN_SPLIT_ROUTE_IDENTS.forEach((splitType) => {
|
|
436
|
+
if (
|
|
437
|
+
!t.isIdentifier(prop.key) ||
|
|
438
|
+
prop.key.name !== splitType
|
|
439
|
+
) {
|
|
440
|
+
return
|
|
441
|
+
}
|
|
470
442
|
|
|
471
|
-
|
|
443
|
+
const value = prop.value
|
|
472
444
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
}
|
|
445
|
+
let isExported = false
|
|
446
|
+
if (t.isIdentifier(value)) {
|
|
447
|
+
isExported = hasExport(ast, value)
|
|
448
|
+
if (isExported) {
|
|
449
|
+
knownExportedIdents.add(value.name)
|
|
479
450
|
}
|
|
451
|
+
}
|
|
480
452
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
}
|
|
453
|
+
// If the node is exported, we need to remove
|
|
454
|
+
// the export from the split file
|
|
455
|
+
if (isExported && t.isIdentifier(value)) {
|
|
456
|
+
removeExports(ast, value)
|
|
457
|
+
} else {
|
|
458
|
+
const meta = SPLIT_NODES_CONFIG.get(splitType)!
|
|
459
|
+
trackedNodesToSplitByType[splitType] = {
|
|
460
|
+
node: prop.value,
|
|
461
|
+
meta,
|
|
491
462
|
}
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
463
|
+
}
|
|
464
|
+
})
|
|
465
|
+
}
|
|
466
|
+
})
|
|
495
467
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
468
|
+
// Remove all of the options
|
|
469
|
+
options.properties = []
|
|
499
470
|
}
|
|
500
|
-
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (t.isCallExpression(path.parentPath.node)) {
|
|
474
|
+
// createFileRoute('/')({ ... })
|
|
475
|
+
const options = resolveIdentifier(
|
|
476
|
+
path,
|
|
477
|
+
path.parentPath.node.arguments[0],
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
babelHandleVirtual(options)
|
|
481
|
+
} else if (t.isVariableDeclarator(path.parentPath.node)) {
|
|
482
|
+
// createFileRoute({ ... })
|
|
483
|
+
const caller = resolveIdentifier(path, path.parentPath.node.init)
|
|
484
|
+
|
|
485
|
+
if (t.isCallExpression(caller)) {
|
|
486
|
+
const options = resolveIdentifier(path, caller.arguments[0])
|
|
487
|
+
babelHandleVirtual(options)
|
|
488
|
+
}
|
|
489
|
+
}
|
|
501
490
|
},
|
|
502
|
-
|
|
503
|
-
)
|
|
491
|
+
})
|
|
504
492
|
|
|
505
493
|
// Start the transformation to only exported the intended split nodes
|
|
506
494
|
intendedSplitNodes.forEach((SPLIT_TYPE) => {
|
|
@@ -841,7 +829,7 @@ function getImportSpecifierAndPathFromLocalName(
|
|
|
841
829
|
}
|
|
842
830
|
|
|
843
831
|
// Reusable function to get literal value or resolve variable to literal
|
|
844
|
-
function resolveIdentifier(path: any, node: any) {
|
|
832
|
+
function resolveIdentifier(path: any, node: any): t.Node | undefined {
|
|
845
833
|
if (t.isIdentifier(node)) {
|
|
846
834
|
const binding = path.scope.getBinding(node.name)
|
|
847
835
|
if (
|