@tanstack/start-plugin-core 1.167.34 → 1.168.0
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/esm/import-protection/adapterUtils.d.ts +27 -0
- package/dist/esm/import-protection/adapterUtils.js +31 -0
- package/dist/esm/import-protection/adapterUtils.js.map +1 -0
- package/dist/esm/import-protection/analysis.d.ts +36 -0
- package/dist/esm/import-protection/analysis.js +407 -0
- package/dist/esm/import-protection/analysis.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/ast.js +1 -1
- package/dist/esm/import-protection/ast.js.map +1 -0
- package/dist/esm/import-protection/constants.d.ts +11 -0
- package/dist/esm/{import-protection-plugin → import-protection}/constants.js +7 -2
- package/dist/esm/import-protection/constants.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/defaults.js +1 -1
- package/dist/esm/import-protection/defaults.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/extensionlessAbsoluteIdResolver.js +1 -1
- package/dist/esm/import-protection/extensionlessAbsoluteIdResolver.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/matchers.js +1 -1
- package/dist/esm/import-protection/matchers.js.map +1 -0
- package/dist/esm/{import-protection-plugin/rewriteDeniedImports.d.ts → import-protection/rewrite.d.ts} +0 -4
- package/dist/esm/import-protection/rewrite.js +121 -0
- package/dist/esm/import-protection/rewrite.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/sourceLocation.d.ts +32 -3
- package/dist/esm/{import-protection-plugin → import-protection}/sourceLocation.js +65 -10
- package/dist/esm/import-protection/sourceLocation.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/trace.d.ts +0 -1
- package/dist/esm/{import-protection-plugin → import-protection}/trace.js +1 -1
- package/dist/esm/import-protection/trace.js.map +1 -0
- package/dist/esm/{import-protection-plugin → import-protection}/utils.d.ts +18 -1
- package/dist/esm/{import-protection-plugin → import-protection}/utils.js +12 -19
- package/dist/esm/import-protection/utils.js.map +1 -0
- package/dist/esm/import-protection/virtualModules.d.ts +25 -0
- package/dist/esm/{import-protection-plugin → import-protection}/virtualModules.js +5 -117
- package/dist/esm/import-protection/virtualModules.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/post-build.d.ts +9 -0
- package/dist/esm/post-build.js +37 -0
- package/dist/esm/post-build.js.map +1 -0
- package/dist/esm/prerender.d.ts +11 -0
- package/dist/esm/prerender.js +159 -0
- package/dist/esm/prerender.js.map +1 -0
- package/dist/esm/rsbuild/dev-server.d.ts +21 -0
- package/dist/esm/rsbuild/dev-server.js +76 -0
- package/dist/esm/rsbuild/dev-server.js.map +1 -0
- package/dist/esm/rsbuild/import-protection.d.ts +10 -0
- package/dist/esm/rsbuild/import-protection.js +775 -0
- package/dist/esm/rsbuild/import-protection.js.map +1 -0
- package/dist/esm/rsbuild/normalized-client-build.d.ts +18 -0
- package/dist/esm/rsbuild/normalized-client-build.js +207 -0
- package/dist/esm/rsbuild/normalized-client-build.js.map +1 -0
- package/dist/esm/rsbuild/planning.d.ts +52 -0
- package/dist/esm/rsbuild/planning.js +108 -0
- package/dist/esm/rsbuild/planning.js.map +1 -0
- package/dist/esm/rsbuild/plugin.d.ts +4 -0
- package/dist/esm/rsbuild/plugin.js +344 -0
- package/dist/esm/rsbuild/plugin.js.map +1 -0
- package/dist/esm/rsbuild/post-build.d.ts +6 -0
- package/dist/esm/rsbuild/post-build.js +57 -0
- package/dist/esm/rsbuild/post-build.js.map +1 -0
- package/dist/esm/rsbuild/schema.d.ts +3372 -0
- package/dist/esm/rsbuild/schema.js +12 -0
- package/dist/esm/rsbuild/schema.js.map +1 -0
- package/dist/esm/rsbuild/start-compiler-host.d.ts +20 -0
- package/dist/esm/rsbuild/start-compiler-host.js +150 -0
- package/dist/esm/rsbuild/start-compiler-host.js.map +1 -0
- package/dist/esm/rsbuild/start-router-plugin.d.ts +18 -0
- package/dist/esm/rsbuild/start-router-plugin.js +63 -0
- package/dist/esm/rsbuild/start-router-plugin.js.map +1 -0
- package/dist/esm/rsbuild/swc-rsc.d.ts +14 -0
- package/dist/esm/rsbuild/swc-rsc.js +93 -0
- package/dist/esm/rsbuild/swc-rsc.js.map +1 -0
- package/dist/esm/rsbuild/types.d.ts +17 -0
- package/dist/esm/rsbuild/types.js +0 -0
- package/dist/esm/rsbuild/virtual-modules.d.ts +53 -0
- package/dist/esm/rsbuild/virtual-modules.js +287 -0
- package/dist/esm/rsbuild/virtual-modules.js.map +1 -0
- package/dist/esm/schema.d.ts +43 -43
- package/dist/esm/schema.js +1 -1
- package/dist/esm/start-compiler/compiler.d.ts +1 -1
- package/dist/esm/start-compiler/compiler.js +80 -9
- package/dist/esm/start-compiler/compiler.js.map +1 -1
- package/dist/esm/start-compiler/handleCreateServerFn.js +9 -0
- package/dist/esm/start-compiler/handleCreateServerFn.js.map +1 -1
- package/dist/esm/start-compiler/host.js +5 -1
- package/dist/esm/start-compiler/host.js.map +1 -1
- package/dist/esm/start-compiler/types.d.ts +1 -0
- package/dist/esm/start-manifest-plugin/manifestBuilder.d.ts +3 -6
- package/dist/esm/start-manifest-plugin/manifestBuilder.js +34 -81
- package/dist/esm/start-manifest-plugin/manifestBuilder.js.map +1 -1
- package/dist/esm/utils.d.ts +1 -0
- package/dist/esm/utils.js +4 -1
- package/dist/esm/utils.js.map +1 -1
- package/dist/esm/{import-protection-plugin → vite/import-protection-plugin}/plugin.js +41 -92
- package/dist/esm/vite/import-protection-plugin/plugin.js.map +1 -0
- package/dist/esm/{import-protection-plugin → vite/import-protection-plugin}/types.d.ts +5 -5
- package/dist/esm/vite/import-protection-plugin/virtualModules.d.ts +8 -0
- package/dist/esm/vite/import-protection-plugin/virtualModules.js +49 -0
- package/dist/esm/vite/import-protection-plugin/virtualModules.js.map +1 -0
- package/dist/esm/vite/plugin.js +4 -12
- package/dist/esm/vite/plugin.js.map +1 -1
- package/dist/esm/vite/plugins.d.ts +1 -5
- package/dist/esm/vite/plugins.js +2 -17
- package/dist/esm/vite/plugins.js.map +1 -1
- package/dist/esm/vite/post-server-build.js +14 -32
- package/dist/esm/vite/post-server-build.js.map +1 -1
- package/dist/esm/vite/prerender.d.ts +2 -2
- package/dist/esm/vite/prerender.js +17 -147
- package/dist/esm/vite/prerender.js.map +1 -1
- package/dist/esm/vite/schema.d.ts +23 -23
- package/dist/esm/vite/start-compiler-plugin/hot-update.d.ts +2 -0
- package/dist/esm/vite/start-compiler-plugin/hot-update.js +16 -0
- package/dist/esm/vite/start-compiler-plugin/hot-update.js.map +1 -0
- package/dist/esm/vite/start-compiler-plugin/module-specifier.js +9 -4
- package/dist/esm/vite/start-compiler-plugin/module-specifier.js.map +1 -1
- package/dist/esm/vite/start-compiler-plugin/plugin.js +86 -13
- package/dist/esm/vite/start-compiler-plugin/plugin.js.map +1 -1
- package/dist/esm/vite/start-manifest-plugin/normalized-client-build.js +2 -2
- package/dist/esm/vite/start-manifest-plugin/normalized-client-build.js.map +1 -1
- package/dist/esm/vite/start-manifest-plugin/plugin.d.ts +1 -2
- package/dist/esm/vite/start-manifest-plugin/plugin.js +48 -14
- package/dist/esm/vite/start-manifest-plugin/plugin.js.map +1 -1
- package/package.json +17 -4
- package/src/import-protection/INTERNALS.md +266 -0
- package/src/import-protection/adapterUtils.ts +94 -0
- package/src/import-protection/analysis.ts +853 -0
- package/src/{import-protection-plugin → import-protection}/constants.ts +7 -0
- package/src/import-protection/rewrite.ts +229 -0
- package/src/{import-protection-plugin → import-protection}/sourceLocation.ts +125 -9
- package/src/{import-protection-plugin → import-protection}/trace.ts +0 -1
- package/src/{import-protection-plugin → import-protection}/utils.ts +35 -20
- package/src/{import-protection-plugin → import-protection}/virtualModules.ts +30 -177
- package/src/index.ts +5 -0
- package/src/post-build.ts +64 -0
- package/src/prerender.ts +292 -0
- package/src/rsbuild/INTERNALS-import-protection.md +169 -0
- package/src/rsbuild/dev-server.ts +129 -0
- package/src/rsbuild/import-protection.ts +1600 -0
- package/src/rsbuild/normalized-client-build.ts +346 -0
- package/src/rsbuild/planning.ts +234 -0
- package/src/rsbuild/plugin.ts +754 -0
- package/src/rsbuild/post-build.ts +96 -0
- package/src/rsbuild/schema.ts +31 -0
- package/src/rsbuild/start-compiler-host.ts +250 -0
- package/src/rsbuild/start-router-plugin.ts +86 -0
- package/src/rsbuild/swc-rsc.ts +166 -0
- package/src/rsbuild/types.ts +20 -0
- package/src/rsbuild/virtual-modules.ts +565 -0
- package/src/start-compiler/compiler.ts +153 -19
- package/src/start-compiler/handleCreateServerFn.ts +18 -0
- package/src/start-compiler/types.ts +1 -0
- package/src/start-manifest-plugin/manifestBuilder.ts +53 -116
- package/src/utils.ts +4 -0
- package/src/vite/import-protection-plugin/INTERNALS.md +187 -0
- package/src/{import-protection-plugin → vite/import-protection-plugin}/plugin.ts +73 -158
- package/src/{import-protection-plugin → vite/import-protection-plugin}/types.ts +5 -5
- package/src/vite/import-protection-plugin/virtualModules.ts +122 -0
- package/src/vite/plugin.ts +1 -18
- package/src/vite/plugins.ts +2 -33
- package/src/vite/post-server-build.ts +14 -57
- package/src/vite/prerender.ts +19 -260
- package/src/vite/start-compiler-plugin/hot-update.ts +24 -0
- package/src/vite/start-compiler-plugin/module-specifier.ts +15 -5
- package/src/vite/start-compiler-plugin/plugin.ts +193 -18
- package/src/vite/start-manifest-plugin/normalized-client-build.ts +15 -16
- package/src/vite/start-manifest-plugin/plugin.ts +121 -38
- package/dist/esm/import-protection-plugin/ast.js.map +0 -1
- package/dist/esm/import-protection-plugin/constants.d.ts +0 -6
- package/dist/esm/import-protection-plugin/constants.js.map +0 -1
- package/dist/esm/import-protection-plugin/defaults.js.map +0 -1
- package/dist/esm/import-protection-plugin/extensionlessAbsoluteIdResolver.js.map +0 -1
- package/dist/esm/import-protection-plugin/matchers.js.map +0 -1
- package/dist/esm/import-protection-plugin/plugin.js.map +0 -1
- package/dist/esm/import-protection-plugin/postCompileUsage.d.ts +0 -13
- package/dist/esm/import-protection-plugin/postCompileUsage.js +0 -63
- package/dist/esm/import-protection-plugin/postCompileUsage.js.map +0 -1
- package/dist/esm/import-protection-plugin/rewriteDeniedImports.js +0 -205
- package/dist/esm/import-protection-plugin/rewriteDeniedImports.js.map +0 -1
- package/dist/esm/import-protection-plugin/sourceLocation.js.map +0 -1
- package/dist/esm/import-protection-plugin/trace.js.map +0 -1
- package/dist/esm/import-protection-plugin/utils.js.map +0 -1
- package/dist/esm/import-protection-plugin/virtualModules.d.ts +0 -78
- package/dist/esm/import-protection-plugin/virtualModules.js.map +0 -1
- package/dist/esm/start-compiler/load-module.d.ts +0 -14
- package/dist/esm/start-compiler/load-module.js +0 -18
- package/dist/esm/start-compiler/load-module.js.map +0 -1
- package/src/import-protection-plugin/INTERNALS.md +0 -700
- package/src/import-protection-plugin/postCompileUsage.ts +0 -100
- package/src/import-protection-plugin/rewriteDeniedImports.ts +0 -379
- package/src/start-compiler/load-module.ts +0 -31
- /package/dist/esm/{import-protection-plugin → import-protection}/ast.d.ts +0 -0
- /package/dist/esm/{import-protection-plugin → import-protection}/defaults.d.ts +0 -0
- /package/dist/esm/{import-protection-plugin → import-protection}/extensionlessAbsoluteIdResolver.d.ts +0 -0
- /package/dist/esm/{import-protection-plugin → import-protection}/matchers.d.ts +0 -0
- /package/dist/esm/{import-protection-plugin → vite/import-protection-plugin}/plugin.d.ts +0 -0
- /package/src/{import-protection-plugin → import-protection}/ast.ts +0 -0
- /package/src/{import-protection-plugin → import-protection}/defaults.ts +0 -0
- /package/src/{import-protection-plugin → import-protection}/extensionlessAbsoluteIdResolver.ts +0 -0
- /package/src/{import-protection-plugin → import-protection}/matchers.ts +0 -0
|
@@ -13,6 +13,7 @@ import { handleCreateMiddleware } from './handleCreateMiddleware'
|
|
|
13
13
|
import { handleCreateIsomorphicFn } from './handleCreateIsomorphicFn'
|
|
14
14
|
import { handleEnvOnlyFn } from './handleEnvOnly'
|
|
15
15
|
import { handleClientOnlyJSX } from './handleClientOnlyJSX'
|
|
16
|
+
import { cleanId } from './utils'
|
|
16
17
|
import type {
|
|
17
18
|
CompilationContext,
|
|
18
19
|
DevServerFnModuleSpecifierEncoder,
|
|
@@ -259,6 +260,19 @@ function isNestedDirectCallCandidate(node: t.CallExpression): boolean {
|
|
|
259
260
|
return calleeName !== undefined && DirectCallFactoryNames.has(calleeName)
|
|
260
261
|
}
|
|
261
262
|
|
|
263
|
+
function isSimpleDirectCallExpression(node: t.CallExpression): boolean {
|
|
264
|
+
return (
|
|
265
|
+
t.isIdentifier(node.callee) ||
|
|
266
|
+
(t.isMemberExpression(node.callee) &&
|
|
267
|
+
t.isIdentifier(node.callee.object) &&
|
|
268
|
+
t.isIdentifier(node.callee.property))
|
|
269
|
+
)
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function isTopLevelDirectCallCandidateNode(node: t.CallExpression): boolean {
|
|
273
|
+
return isSimpleDirectCallExpression(node)
|
|
274
|
+
}
|
|
275
|
+
|
|
262
276
|
/**
|
|
263
277
|
* Checks if a CallExpression path is a top-level direct-call candidate.
|
|
264
278
|
* Top-level means the call is the init of a VariableDeclarator at program level.
|
|
@@ -272,13 +286,7 @@ function isTopLevelDirectCallCandidate(
|
|
|
272
286
|
const node = path.node
|
|
273
287
|
|
|
274
288
|
// Must be a simple identifier call or namespace call
|
|
275
|
-
|
|
276
|
-
t.isIdentifier(node.callee) ||
|
|
277
|
-
(t.isMemberExpression(node.callee) &&
|
|
278
|
-
t.isIdentifier(node.callee.object) &&
|
|
279
|
-
t.isIdentifier(node.callee.property))
|
|
280
|
-
|
|
281
|
-
if (!isSimpleCall) {
|
|
289
|
+
if (!isSimpleDirectCallExpression(node)) {
|
|
282
290
|
return false
|
|
283
291
|
}
|
|
284
292
|
|
|
@@ -294,6 +302,12 @@ function isTopLevelDirectCallCandidate(
|
|
|
294
302
|
return t.isProgram(path.parentPath.parentPath?.parent)
|
|
295
303
|
}
|
|
296
304
|
|
|
305
|
+
function isDirectCallCandidateForKind(
|
|
306
|
+
kind: Exclude<LookupKind, 'ClientOnlyJSX'>,
|
|
307
|
+
): boolean {
|
|
308
|
+
return LookupSetup[kind].type === 'directCall'
|
|
309
|
+
}
|
|
310
|
+
|
|
297
311
|
export class StartCompiler {
|
|
298
312
|
private moduleCache = new Map<string, ModuleInfo>()
|
|
299
313
|
private initialized = false
|
|
@@ -530,7 +544,6 @@ export class StartCompiler {
|
|
|
530
544
|
|
|
531
545
|
/**
|
|
532
546
|
* Extracts bindings and exports from an already-parsed AST.
|
|
533
|
-
* This is the core logic shared by ingestModule and ingestModuleFromAst.
|
|
534
547
|
*/
|
|
535
548
|
private extractModuleInfo(
|
|
536
549
|
ast: ReturnType<typeof parseAst>,
|
|
@@ -642,10 +655,105 @@ export class StartCompiler {
|
|
|
642
655
|
}
|
|
643
656
|
|
|
644
657
|
public invalidateModule(id: string) {
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
658
|
+
const normalizedId = cleanId(id)
|
|
659
|
+
let hasCachedModule = false
|
|
660
|
+
|
|
661
|
+
for (const moduleId of Array.from(this.moduleCache.keys())) {
|
|
662
|
+
if (cleanId(moduleId) === normalizedId) {
|
|
663
|
+
this.moduleCache.delete(moduleId)
|
|
664
|
+
hasCachedModule = true
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// Root import metadata is synthetic compiler state and should survive HMR.
|
|
669
|
+
// The stale dev state lives in per-module resolvedKind memoization.
|
|
670
|
+
for (const [moduleId, moduleInfo] of this.moduleCache) {
|
|
671
|
+
if (this.knownRootImports.has(moduleId)) {
|
|
672
|
+
continue
|
|
673
|
+
}
|
|
674
|
+
|
|
675
|
+
for (const binding of moduleInfo.bindings.values()) {
|
|
676
|
+
binding.resolvedKind = undefined
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
// Build-mode caches are cheap to rebuild and may point at removed entries.
|
|
681
|
+
this.resolveIdCache.clear()
|
|
682
|
+
this.exportResolutionCache.clear()
|
|
683
|
+
|
|
684
|
+
return hasCachedModule
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
public async getTransitiveImporters(id: string): Promise<Set<string>> {
|
|
688
|
+
const discoveredImporters = new Set<string>()
|
|
689
|
+
const pendingTargets = [cleanId(id)]
|
|
690
|
+
const visitedTargets = new Set<string>()
|
|
691
|
+
const resolveCache = new Map<string, Promise<string | null>>()
|
|
692
|
+
|
|
693
|
+
const resolveSource = (source: string, importer: string) => {
|
|
694
|
+
const cacheKey = `${importer}::${source}`
|
|
695
|
+
let resolved = resolveCache.get(cacheKey)
|
|
696
|
+
|
|
697
|
+
if (!resolved) {
|
|
698
|
+
resolved = this.resolveIdCached(source, importer)
|
|
699
|
+
resolveCache.set(cacheKey, resolved)
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
return resolved
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
while (pendingTargets.length > 0) {
|
|
706
|
+
const targetId = pendingTargets.pop()!
|
|
707
|
+
|
|
708
|
+
if (visitedTargets.has(targetId)) {
|
|
709
|
+
continue
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
visitedTargets.add(targetId)
|
|
713
|
+
|
|
714
|
+
const importerIds = await Promise.all(
|
|
715
|
+
Array.from(this.moduleCache.values()).map(async (moduleInfo) => {
|
|
716
|
+
if (this.knownRootImports.has(moduleInfo.id)) {
|
|
717
|
+
return null
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
const moduleId = cleanId(moduleInfo.id)
|
|
721
|
+
|
|
722
|
+
if (moduleId === targetId) {
|
|
723
|
+
return null
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
const importSources = new Set(moduleInfo.reExportAllSources)
|
|
727
|
+
|
|
728
|
+
for (const binding of moduleInfo.bindings.values()) {
|
|
729
|
+
if (binding.type === 'import') {
|
|
730
|
+
importSources.add(binding.source)
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
for (const source of importSources) {
|
|
735
|
+
const resolved = await resolveSource(source, moduleInfo.id)
|
|
736
|
+
|
|
737
|
+
if (resolved && cleanId(resolved) === targetId) {
|
|
738
|
+
return moduleId
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
return null
|
|
743
|
+
}),
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
for (const importerId of importerIds) {
|
|
747
|
+
if (!importerId || discoveredImporters.has(importerId)) {
|
|
748
|
+
continue
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
discoveredImporters.add(importerId)
|
|
752
|
+
pendingTargets.push(importerId)
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
return discoveredImporters
|
|
649
757
|
}
|
|
650
758
|
|
|
651
759
|
public async compile({
|
|
@@ -719,7 +827,10 @@ export class StartCompiler {
|
|
|
719
827
|
if (declarations) {
|
|
720
828
|
for (const decl of declarations) {
|
|
721
829
|
if (decl.init && t.isCallExpression(decl.init)) {
|
|
722
|
-
if (
|
|
830
|
+
if (
|
|
831
|
+
isMethodChainCandidate(decl.init, fileKinds) ||
|
|
832
|
+
isTopLevelDirectCallCandidateNode(decl.init)
|
|
833
|
+
) {
|
|
723
834
|
candidateIndices.push(i)
|
|
724
835
|
break // Only need to mark this statement once
|
|
725
836
|
}
|
|
@@ -760,6 +871,11 @@ export class StartCompiler {
|
|
|
760
871
|
// Method chain pattern
|
|
761
872
|
if (isMethodChainCandidate(node, fileKinds)) {
|
|
762
873
|
candidatePaths.push(path)
|
|
874
|
+
return
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
if (isTopLevelDirectCallCandidate(path)) {
|
|
878
|
+
candidatePaths.push(path)
|
|
763
879
|
}
|
|
764
880
|
},
|
|
765
881
|
})
|
|
@@ -792,11 +908,14 @@ export class StartCompiler {
|
|
|
792
908
|
return
|
|
793
909
|
}
|
|
794
910
|
|
|
911
|
+
if (isTopLevelDirectCallCandidate(path)) {
|
|
912
|
+
candidatePaths.push(path)
|
|
913
|
+
return
|
|
914
|
+
}
|
|
915
|
+
|
|
795
916
|
// Pattern 2: Direct call pattern
|
|
796
917
|
if (checkDirectCalls) {
|
|
797
|
-
if (
|
|
798
|
-
candidatePaths.push(path)
|
|
799
|
-
} else if (isNestedDirectCallCandidate(node)) {
|
|
918
|
+
if (isNestedDirectCallCandidate(node)) {
|
|
800
919
|
candidatePaths.push(path)
|
|
801
920
|
}
|
|
802
921
|
}
|
|
@@ -845,9 +964,23 @@ export class StartCompiler {
|
|
|
845
964
|
)
|
|
846
965
|
|
|
847
966
|
// Filter to valid candidates
|
|
848
|
-
const validCandidates = resolvedCandidates.filter(({ kind }) =>
|
|
849
|
-
|
|
850
|
-
|
|
967
|
+
const validCandidates = resolvedCandidates.filter(({ path, kind }) => {
|
|
968
|
+
if (
|
|
969
|
+
!this.validLookupKinds.has(kind as Exclude<LookupKind, 'ClientOnlyJSX'>)
|
|
970
|
+
) {
|
|
971
|
+
return false
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
if (
|
|
975
|
+
isLookupKind(kind) &&
|
|
976
|
+
kind !== 'ClientOnlyJSX' &&
|
|
977
|
+
!isMethodChainCandidate(path.node, fileKinds)
|
|
978
|
+
) {
|
|
979
|
+
return isDirectCallCandidateForKind(kind)
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
return true
|
|
983
|
+
}) as Array<{
|
|
851
984
|
path: babel.NodePath<t.CallExpression>
|
|
852
985
|
kind: Exclude<LookupKind, 'ClientOnlyJSX'>
|
|
853
986
|
}>
|
|
@@ -925,6 +1058,7 @@ export class StartCompiler {
|
|
|
925
1058
|
code,
|
|
926
1059
|
env: this.options.env,
|
|
927
1060
|
envName: this.options.envName,
|
|
1061
|
+
mode: this.mode,
|
|
928
1062
|
root: this.options.root,
|
|
929
1063
|
framework: this.options.framework,
|
|
930
1064
|
providerEnvName: this.options.providerEnvName,
|
|
@@ -7,6 +7,20 @@ import type { CompileStartFrameworkOptions } from '../types'
|
|
|
7
7
|
|
|
8
8
|
const TSS_SERVERFN_SPLIT_PARAM = 'tss-serverfn-split'
|
|
9
9
|
|
|
10
|
+
const providerHmrAcceptTemplate = babel.template.statements(
|
|
11
|
+
`
|
|
12
|
+
if (import.meta.hot) {
|
|
13
|
+
import.meta.hot.accept(() => {})
|
|
14
|
+
}
|
|
15
|
+
if (import.meta.webpackHot) {
|
|
16
|
+
import.meta.webpackHot.accept(() => {})
|
|
17
|
+
}
|
|
18
|
+
`,
|
|
19
|
+
{
|
|
20
|
+
placeholderPattern: false,
|
|
21
|
+
},
|
|
22
|
+
)
|
|
23
|
+
|
|
10
24
|
// ============================================================================
|
|
11
25
|
// Pre-compiled babel templates (compiled once at module load time)
|
|
12
26
|
// ============================================================================
|
|
@@ -414,6 +428,10 @@ export function handleCreateServerFn(
|
|
|
414
428
|
),
|
|
415
429
|
)
|
|
416
430
|
}
|
|
431
|
+
|
|
432
|
+
if (context.mode === 'dev') {
|
|
433
|
+
context.ast.program.body.push(...providerHmrAcceptTemplate())
|
|
434
|
+
}
|
|
417
435
|
}
|
|
418
436
|
|
|
419
437
|
// Notify about discovered functions (only for non-provider files)
|
|
@@ -12,6 +12,7 @@ export interface CompilationContext {
|
|
|
12
12
|
readonly id: string
|
|
13
13
|
readonly env: 'client' | 'server'
|
|
14
14
|
readonly envName: string
|
|
15
|
+
readonly mode: 'dev' | 'build'
|
|
15
16
|
readonly root: string
|
|
16
17
|
/** The framework being used (e.g., 'react', 'solid') */
|
|
17
18
|
readonly framework: CompileStartFrameworkOptions
|
|
@@ -10,8 +10,6 @@ import {
|
|
|
10
10
|
import type { ManifestAssetLink, RouterManagedTag } from '@tanstack/router-core'
|
|
11
11
|
import type { NormalizedClientBuild, NormalizedClientChunk } from '../types'
|
|
12
12
|
|
|
13
|
-
const ROUTER_MANAGED_MODE = 1
|
|
14
|
-
const NON_ROUTE_DYNAMIC_MODE = 2
|
|
15
13
|
const VISITING_CHUNK = 1
|
|
16
14
|
|
|
17
15
|
type RouteTreeRoute = {
|
|
@@ -27,7 +25,6 @@ interface ScannedClientChunks {
|
|
|
27
25
|
entryChunk: NormalizedClientChunk
|
|
28
26
|
chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>
|
|
29
27
|
routeChunksByFilePath: ReadonlyMap<string, Array<NormalizedClientChunk>>
|
|
30
|
-
routeEntryChunks: ReadonlySet<NormalizedClientChunk>
|
|
31
28
|
}
|
|
32
29
|
|
|
33
30
|
interface ManifestAssetResolvers {
|
|
@@ -114,19 +111,25 @@ export function appendUniqueAssets(
|
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
function getAssetIdentity(asset: RouterManagedTag) {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
114
|
+
return JSON.stringify({
|
|
115
|
+
tag: asset.tag,
|
|
116
|
+
attrs: normalizeAssetAttrs(asset.attrs),
|
|
117
|
+
children: 'children' in asset ? (asset.children ?? null) : null,
|
|
118
|
+
})
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
function normalizeAssetAttrs(attrs: Record<string, any> | undefined) {
|
|
122
|
+
if (!attrs) {
|
|
123
|
+
return null
|
|
127
124
|
}
|
|
128
125
|
|
|
129
|
-
|
|
126
|
+
const entries = Object.entries(attrs)
|
|
127
|
+
if (entries.length === 0) {
|
|
128
|
+
return null
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
entries.sort(([left], [right]) => left.localeCompare(right))
|
|
132
|
+
return Object.fromEntries(entries)
|
|
130
133
|
}
|
|
131
134
|
|
|
132
135
|
function mergeRouteChunkData(options: {
|
|
@@ -149,17 +152,12 @@ export function buildStartManifest(options: {
|
|
|
149
152
|
clientBuild: NormalizedClientBuild
|
|
150
153
|
routeTreeRoutes: RouteTreeRoutes
|
|
151
154
|
basePath: string
|
|
155
|
+
additionalRouteAssets?: Partial<
|
|
156
|
+
Record<string, ReadonlyArray<RouterManagedTag>>
|
|
157
|
+
>
|
|
152
158
|
}): StartManifest {
|
|
153
159
|
const scannedChunks = scanClientChunks(options.clientBuild)
|
|
154
|
-
const
|
|
155
|
-
scannedChunks.routeEntryChunks,
|
|
156
|
-
scannedChunks.chunksByFileName,
|
|
157
|
-
scannedChunks.entryChunk,
|
|
158
|
-
)
|
|
159
|
-
const assetResolvers = createManifestAssetResolvers({
|
|
160
|
-
basePath: options.basePath,
|
|
161
|
-
hashedCssFiles,
|
|
162
|
-
})
|
|
160
|
+
const assetResolvers = createManifestAssetResolvers(options.basePath)
|
|
163
161
|
|
|
164
162
|
const routes = buildRouteManifestRoutes({
|
|
165
163
|
routeTreeRoutes: options.routeTreeRoutes,
|
|
@@ -167,6 +165,7 @@ export function buildStartManifest(options: {
|
|
|
167
165
|
chunksByFileName: scannedChunks.chunksByFileName,
|
|
168
166
|
entryChunk: scannedChunks.entryChunk,
|
|
169
167
|
assetResolvers,
|
|
168
|
+
additionalRouteAssets: options.additionalRouteAssets,
|
|
170
169
|
})
|
|
171
170
|
|
|
172
171
|
dedupeNestedRouteManifestEntries(rootRouteId, routes[rootRouteId]!, routes)
|
|
@@ -202,13 +201,10 @@ export function scanClientChunks(
|
|
|
202
201
|
throw new Error(`Missing entry chunk: ${clientBuild.entryChunkFileName}`)
|
|
203
202
|
}
|
|
204
203
|
|
|
205
|
-
const routeEntryChunks = new Set<NormalizedClientChunk>()
|
|
206
204
|
const routeChunksByFilePath = new Map<string, Array<NormalizedClientChunk>>()
|
|
207
205
|
|
|
208
206
|
for (const chunk of clientBuild.chunksByFileName.values()) {
|
|
209
207
|
if (chunk.routeFilePaths.length > 0) {
|
|
210
|
-
routeEntryChunks.add(chunk)
|
|
211
|
-
|
|
212
208
|
for (const routeFilePath of chunk.routeFilePaths) {
|
|
213
209
|
let chunks = routeChunksByFilePath.get(routeFilePath)
|
|
214
210
|
if (chunks === undefined) {
|
|
@@ -224,92 +220,12 @@ export function scanClientChunks(
|
|
|
224
220
|
entryChunk,
|
|
225
221
|
chunksByFileName: clientBuild.chunksByFileName,
|
|
226
222
|
routeChunksByFilePath,
|
|
227
|
-
routeEntryChunks,
|
|
228
223
|
}
|
|
229
224
|
}
|
|
230
225
|
|
|
231
|
-
export function
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
entryChunk?: NormalizedClientChunk,
|
|
235
|
-
) {
|
|
236
|
-
const routerManagedCssFiles = new Set<string>()
|
|
237
|
-
const nonRouteDynamicCssFiles = new Set<string>()
|
|
238
|
-
const hashedCssFiles = new Set<string>()
|
|
239
|
-
const visitedByChunk = new Map<NormalizedClientChunk, number>()
|
|
240
|
-
const chunkStack: Array<NormalizedClientChunk> = []
|
|
241
|
-
const modeStack: Array<number> = []
|
|
242
|
-
|
|
243
|
-
for (const routeEntryChunk of routeEntryChunks) {
|
|
244
|
-
chunkStack.push(routeEntryChunk)
|
|
245
|
-
modeStack.push(ROUTER_MANAGED_MODE)
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (entryChunk) {
|
|
249
|
-
chunkStack.push(entryChunk)
|
|
250
|
-
modeStack.push(ROUTER_MANAGED_MODE)
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
while (chunkStack.length > 0) {
|
|
254
|
-
const chunk = chunkStack.pop()!
|
|
255
|
-
const mode = modeStack.pop()!
|
|
256
|
-
const previousMode = visitedByChunk.get(chunk) ?? 0
|
|
257
|
-
|
|
258
|
-
if ((previousMode & mode) === mode) {
|
|
259
|
-
continue
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
visitedByChunk.set(chunk, previousMode | mode)
|
|
263
|
-
|
|
264
|
-
if ((mode & ROUTER_MANAGED_MODE) !== 0) {
|
|
265
|
-
for (const cssFile of chunk.css) {
|
|
266
|
-
routerManagedCssFiles.add(cssFile)
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
if ((mode & NON_ROUTE_DYNAMIC_MODE) !== 0) {
|
|
271
|
-
for (const cssFile of chunk.css) {
|
|
272
|
-
nonRouteDynamicCssFiles.add(cssFile)
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
for (let i = 0; i < chunk.imports.length; i++) {
|
|
277
|
-
const importedChunk = chunksByFileName.get(chunk.imports[i]!)
|
|
278
|
-
if (importedChunk) {
|
|
279
|
-
chunkStack.push(importedChunk)
|
|
280
|
-
modeStack.push(mode)
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
for (let i = 0; i < chunk.dynamicImports.length; i++) {
|
|
285
|
-
const dynamicImportedChunk = chunksByFileName.get(
|
|
286
|
-
chunk.dynamicImports[i]!,
|
|
287
|
-
)
|
|
288
|
-
if (dynamicImportedChunk) {
|
|
289
|
-
chunkStack.push(dynamicImportedChunk)
|
|
290
|
-
modeStack.push(
|
|
291
|
-
(mode & NON_ROUTE_DYNAMIC_MODE) !== 0 ||
|
|
292
|
-
!routeEntryChunks.has(dynamicImportedChunk)
|
|
293
|
-
? NON_ROUTE_DYNAMIC_MODE
|
|
294
|
-
: ROUTER_MANAGED_MODE,
|
|
295
|
-
)
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
for (const cssFile of routerManagedCssFiles) {
|
|
301
|
-
if (nonRouteDynamicCssFiles.has(cssFile)) {
|
|
302
|
-
hashedCssFiles.add(cssFile)
|
|
303
|
-
}
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
return hashedCssFiles
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
export function createManifestAssetResolvers(options: {
|
|
310
|
-
basePath: string
|
|
311
|
-
hashedCssFiles?: Set<string>
|
|
312
|
-
}): ManifestAssetResolvers {
|
|
226
|
+
export function createManifestAssetResolvers(
|
|
227
|
+
basePath: string,
|
|
228
|
+
): ManifestAssetResolvers {
|
|
313
229
|
const assetPathByFileName = new Map<string, string>()
|
|
314
230
|
const stylesheetAssetByFileName = new Map<string, RouterManagedTag>()
|
|
315
231
|
const preloadsByChunk = new Map<NormalizedClientChunk, Array<string>>()
|
|
@@ -320,7 +236,7 @@ export function createManifestAssetResolvers(options: {
|
|
|
320
236
|
return cachedPath
|
|
321
237
|
}
|
|
322
238
|
|
|
323
|
-
const assetPath = joinURL(
|
|
239
|
+
const assetPath = joinURL(basePath, fileName)
|
|
324
240
|
assetPathByFileName.set(fileName, assetPath)
|
|
325
241
|
return assetPath
|
|
326
242
|
}
|
|
@@ -336,7 +252,7 @@ export function createManifestAssetResolvers(options: {
|
|
|
336
252
|
tag: 'link',
|
|
337
253
|
attrs: {
|
|
338
254
|
rel: 'stylesheet',
|
|
339
|
-
href
|
|
255
|
+
href,
|
|
340
256
|
type: 'text/css',
|
|
341
257
|
},
|
|
342
258
|
} satisfies RouterManagedTag
|
|
@@ -380,15 +296,14 @@ export function createChunkCssAssetCollector(options: {
|
|
|
380
296
|
|
|
381
297
|
const appendAsset = (
|
|
382
298
|
assets: Array<RouterManagedTag>,
|
|
383
|
-
seenAssets: Set<
|
|
299
|
+
seenAssets: Set<RouterManagedTag>,
|
|
384
300
|
asset: RouterManagedTag,
|
|
385
301
|
) => {
|
|
386
|
-
|
|
387
|
-
if (seenAssets.has(identity)) {
|
|
302
|
+
if (seenAssets.has(asset)) {
|
|
388
303
|
return
|
|
389
304
|
}
|
|
390
305
|
|
|
391
|
-
seenAssets.add(
|
|
306
|
+
seenAssets.add(asset)
|
|
392
307
|
assets.push(asset)
|
|
393
308
|
}
|
|
394
309
|
|
|
@@ -406,7 +321,7 @@ export function createChunkCssAssetCollector(options: {
|
|
|
406
321
|
stateByChunk.set(chunk, VISITING_CHUNK)
|
|
407
322
|
|
|
408
323
|
const assets: Array<RouterManagedTag> = []
|
|
409
|
-
const seenAssets = new Set<
|
|
324
|
+
const seenAssets = new Set<RouterManagedTag>()
|
|
410
325
|
|
|
411
326
|
for (const cssFile of chunk.css) {
|
|
412
327
|
appendAsset(assets, seenAssets, options.getStylesheetAsset(cssFile))
|
|
@@ -441,6 +356,9 @@ export function buildRouteManifestRoutes(options: {
|
|
|
441
356
|
chunksByFileName: ReadonlyMap<string, NormalizedClientChunk>
|
|
442
357
|
entryChunk: NormalizedClientChunk
|
|
443
358
|
assetResolvers: ManifestAssetResolvers
|
|
359
|
+
additionalRouteAssets?: Partial<
|
|
360
|
+
Record<string, ReadonlyArray<RouterManagedTag>>
|
|
361
|
+
>
|
|
444
362
|
}) {
|
|
445
363
|
const routes: Record<string, RouteTreeRoute> = {}
|
|
446
364
|
const getChunkCssAssets = createChunkCssAssetCollector({
|
|
@@ -485,6 +403,25 @@ export function buildRouteManifestRoutes(options: {
|
|
|
485
403
|
getChunkPreloads: options.assetResolvers.getChunkPreloads,
|
|
486
404
|
})
|
|
487
405
|
|
|
406
|
+
if (options.additionalRouteAssets) {
|
|
407
|
+
for (const [routeId, assets] of Object.entries(
|
|
408
|
+
options.additionalRouteAssets,
|
|
409
|
+
)) {
|
|
410
|
+
if (!assets || assets.length === 0) {
|
|
411
|
+
continue
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
if (!(routeId in options.routeTreeRoutes)) {
|
|
415
|
+
throw new Error(
|
|
416
|
+
`expected additionalRouteAssets routeId to exist in routeTreeRoutes: ${routeId}`,
|
|
417
|
+
)
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const route = (routes[routeId] = routes[routeId] || {})
|
|
421
|
+
route.assets = appendUniqueAssets(route.assets, [...assets])
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
488
425
|
return routes
|
|
489
426
|
}
|
|
490
427
|
|