@tanstack/start-plugin-core 1.167.35 → 1.169.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 +2 -2
- 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 +13 -20
- 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 +1 -5
- package/dist/esm/index.js +2 -4
- 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/index.d.ts +4 -0
- package/dist/esm/rsbuild/index.js +3 -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/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/utils.d.ts +1 -0
- package/dist/esm/utils.js +10 -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/index.d.ts +5 -0
- package/dist/esm/vite/index.js +4 -0
- package/dist/esm/vite/plugin.js +1 -1
- package/dist/esm/vite/plugin.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/package.json +32 -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 +36 -21
- package/src/{import-protection-plugin → import-protection}/virtualModules.ts +30 -177
- package/src/index.ts +1 -8
- 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 +1599 -0
- package/src/rsbuild/index.ts +4 -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/utils.ts +14 -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/index.ts +8 -0
- package/src/vite/plugin.ts +1 -1
- 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/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
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Rsbuild Import Protection - Adapter Internals
|
|
2
|
+
|
|
3
|
+
## Scope
|
|
4
|
+
|
|
5
|
+
This document covers the Rsbuild-specific orchestration around the shared
|
|
6
|
+
import-protection core in `src/import-protection/INTERNALS.md`.
|
|
7
|
+
|
|
8
|
+
Rsbuild owns:
|
|
9
|
+
|
|
10
|
+
- post-transform enforcement through `api.transform({ order: 'post' })`
|
|
11
|
+
- virtual-module transport through `VirtualModulesPlugin`
|
|
12
|
+
- compilation-truth reporting in `processAssets`
|
|
13
|
+
- final graph reconstruction from Rspack compilation data
|
|
14
|
+
- the small build-only deferred queue for file violations that can disappear
|
|
15
|
+
from the compiled graph
|
|
16
|
+
|
|
17
|
+
Shared AST analysis, rewrite logic, source extraction, usage lookup, source
|
|
18
|
+
locations, trace formatting, and mock code generation are described in the
|
|
19
|
+
shared internals doc.
|
|
20
|
+
|
|
21
|
+
## Mental Model
|
|
22
|
+
|
|
23
|
+
Vite is primarily `resolveId`-driven. Rsbuild is primarily `transform` +
|
|
24
|
+
`processAssets`-driven.
|
|
25
|
+
|
|
26
|
+
That difference explains most of the adapter divergence.
|
|
27
|
+
|
|
28
|
+
Rsbuild does not emulate the Vite pending-queue state machine. It relies more
|
|
29
|
+
directly on post-transform code and final compilation truth.
|
|
30
|
+
|
|
31
|
+
## Native Hook Shape
|
|
32
|
+
|
|
33
|
+
Import protection is attached through Rsbuild hooks, not a dedicated mini-plugin
|
|
34
|
+
object:
|
|
35
|
+
|
|
36
|
+
1. `onBeforeBuild`
|
|
37
|
+
2. `onBeforeDevCompile`
|
|
38
|
+
3. `modifyRspackConfig`
|
|
39
|
+
4. `transform(..., { order: 'post' })`
|
|
40
|
+
5. `processAssets(..., { stage: 'report' })`
|
|
41
|
+
|
|
42
|
+
## State Model
|
|
43
|
+
|
|
44
|
+
Per environment, Rsbuild keeps a smaller runtime state than Vite:
|
|
45
|
+
|
|
46
|
+
- `resolveCache`
|
|
47
|
+
- `seenViolations`
|
|
48
|
+
- `buildTransformResults`
|
|
49
|
+
- `deferredFileViolations`
|
|
50
|
+
- `deferredFileViolationKeys`
|
|
51
|
+
|
|
52
|
+
Shared state is for virtual module transport and compiler fs access:
|
|
53
|
+
|
|
54
|
+
- `virtualModules`
|
|
55
|
+
- `vmPlugins`
|
|
56
|
+
- `readyVmPlugins`
|
|
57
|
+
- `inputFileSystems`
|
|
58
|
+
- `pendingWrites`
|
|
59
|
+
|
|
60
|
+
Notably absent compared to Vite:
|
|
61
|
+
|
|
62
|
+
- no `pendingViolations`
|
|
63
|
+
- no `postTransformImports`
|
|
64
|
+
- no broad `deferredBuildViolations`
|
|
65
|
+
- no resolve-time dev reachability pipeline
|
|
66
|
+
|
|
67
|
+
## Transform Phase
|
|
68
|
+
|
|
69
|
+
Rsbuild enforcement runs after the Start compiler in a `post` transform.
|
|
70
|
+
|
|
71
|
+
That matters because many compiler-safe imports are already stripped by the time
|
|
72
|
+
import protection runs. This naturally suppresses a large class of false
|
|
73
|
+
positives without a Vite-style pending verification pass.
|
|
74
|
+
|
|
75
|
+
The transform phase is responsible for:
|
|
76
|
+
|
|
77
|
+
- self-denial for forbidden files
|
|
78
|
+
- self-denial for marker-protected files in the wrong environment
|
|
79
|
+
- direct specifier rewrites to mock-edge modules
|
|
80
|
+
- build-time transformed/original source preloading for later diagnostics
|
|
81
|
+
- recording build-only deferred file violations when original unsafe usage may
|
|
82
|
+
outlive a direct compiled graph edge
|
|
83
|
+
|
|
84
|
+
## Virtual Module Transport
|
|
85
|
+
|
|
86
|
+
Rsbuild reuses the shared mock generators, but not the Vite id transport.
|
|
87
|
+
|
|
88
|
+
Instead it writes environment-scoped virtual files under:
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
<root>/node_modules/.virtual/import-protection/<env>/
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The important forms are:
|
|
95
|
+
|
|
96
|
+
- `mock-silent.mjs`
|
|
97
|
+
- `mock-runtime-<base64>.mjs`
|
|
98
|
+
- `mock-edge-<base64>.mjs`
|
|
99
|
+
|
|
100
|
+
Writes may happen before the `VirtualModulesPlugin` instance is ready, so the
|
|
101
|
+
adapter queues them and flushes during compilation setup.
|
|
102
|
+
|
|
103
|
+
## Reporting Phase
|
|
104
|
+
|
|
105
|
+
`processAssets({ stage: 'report' })` is the authoritative reporting step.
|
|
106
|
+
|
|
107
|
+
It reconstructs the final view of the compilation from Rspack data by:
|
|
108
|
+
|
|
109
|
+
1. building a `TransformResultProvider` from `compilation.modules`
|
|
110
|
+
2. rebuilding the active compilation graph from outgoing connections
|
|
111
|
+
3. reconstructing surviving specifier violations from compiled mock-edge files
|
|
112
|
+
4. reporting live file violations from active edges
|
|
113
|
+
5. reporting live marker violations from active edges plus original source
|
|
114
|
+
6. reporting deferred file violations only when both importer and target truly
|
|
115
|
+
survived compilation
|
|
116
|
+
|
|
117
|
+
This is the core Rsbuild-native replacement for Vite's `generateBundle`
|
|
118
|
+
verification plus dev pending-violation flow.
|
|
119
|
+
|
|
120
|
+
## Why The Deferred Queue Is Narrow
|
|
121
|
+
|
|
122
|
+
Rsbuild only needs explicit build deferral for file violations whose direct edge
|
|
123
|
+
may disappear after compilation.
|
|
124
|
+
|
|
125
|
+
Specifier violations are rediscovered from surviving mock-edge virtual files.
|
|
126
|
+
Marker violations are rediscovered from live compiled edges.
|
|
127
|
+
|
|
128
|
+
Only file violations need extra bookkeeping when the final compiled graph can no
|
|
129
|
+
longer show the original denied edge directly.
|
|
130
|
+
|
|
131
|
+
## Source And Compilation APIs
|
|
132
|
+
|
|
133
|
+
The Rsbuild adapter intentionally prefers native Rspack APIs where possible.
|
|
134
|
+
|
|
135
|
+
Transform-time:
|
|
136
|
+
|
|
137
|
+
- `ctx.resource`
|
|
138
|
+
- `ctx.context`
|
|
139
|
+
- `ctx.resolve(...)`
|
|
140
|
+
- captured `compiler.inputFileSystem.readFile(...)`
|
|
141
|
+
|
|
142
|
+
Compilation-time:
|
|
143
|
+
|
|
144
|
+
- `module.nameForCondition?.()`
|
|
145
|
+
- `module.resourceResolveData?.resource`
|
|
146
|
+
- `module.originalSource().sourceAndMap()`
|
|
147
|
+
- sourcemap `sourcesContent`
|
|
148
|
+
- `compilation.inputFileSystem.readFile(...)`
|
|
149
|
+
|
|
150
|
+
This keeps the adapter closer to Rsbuild/Rspack truth and avoids falling back to
|
|
151
|
+
Node fs when the compilation already has the needed data.
|
|
152
|
+
|
|
153
|
+
## Marker Handling
|
|
154
|
+
|
|
155
|
+
Unlike Vite, Rsbuild does not introduce plugin-owned virtual marker modules for
|
|
156
|
+
normal operation.
|
|
157
|
+
|
|
158
|
+
The real package marker files are used as source-level markers, and the adapter
|
|
159
|
+
later infers marker kind from original source while reporting compiled edges.
|
|
160
|
+
|
|
161
|
+
## Practical Maintainer Rule
|
|
162
|
+
|
|
163
|
+
When changing Rsbuild import protection, ask:
|
|
164
|
+
|
|
165
|
+
1. Can the change be expressed in shared analysis/rewrite/mock codegen instead?
|
|
166
|
+
2. If it is adapter-specific, is it really about post-transform enforcement,
|
|
167
|
+
virtual-file transport, or compilation-time reporting?
|
|
168
|
+
3. Can final compilation truth answer the question more simply than adding a new
|
|
169
|
+
pending state machine?
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { NodeRequest, sendNodeResponse } from 'srvx/node'
|
|
2
|
+
import { RSBUILD_ENVIRONMENT_NAMES } from './planning'
|
|
3
|
+
import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
4
|
+
import type { RsbuildConfig } from '@rsbuild/core'
|
|
5
|
+
|
|
6
|
+
type ServerSetupFn = Extract<
|
|
7
|
+
NonNullable<NonNullable<RsbuildConfig['server']>['setup']>,
|
|
8
|
+
(...args: Array<any>) => any
|
|
9
|
+
>
|
|
10
|
+
type SSRMiddleware = (
|
|
11
|
+
req: IncomingMessage & { originalUrl?: string },
|
|
12
|
+
res: ServerResponse,
|
|
13
|
+
next: () => void,
|
|
14
|
+
) => Promise<void>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Returns a `server.setup` function for rsbuild v2.
|
|
18
|
+
*
|
|
19
|
+
* Two middleware positions are used:
|
|
20
|
+
*
|
|
21
|
+
* 1. **Setup body** (BEFORE built-ins): Intercepts `/_serverFn/` URLs so
|
|
22
|
+
* they never reach rsbuild's htmlFallback/htmlCompletion middleware,
|
|
23
|
+
* which can swallow long base64 function IDs.
|
|
24
|
+
*
|
|
25
|
+
* 2. **Returned callback** (AFTER built-ins, BEFORE fallback): Handles
|
|
26
|
+
* all remaining SSR requests (page navigations). This position lets
|
|
27
|
+
* rsbuild's asset middleware serve compiled JS/CSS first.
|
|
28
|
+
*
|
|
29
|
+
* See rsbuild source: devMiddlewares.ts `applyDefaultMiddlewares()`.
|
|
30
|
+
*/
|
|
31
|
+
export function createServerSetup(opts: {
|
|
32
|
+
serverFnBasePath: string
|
|
33
|
+
}): ServerSetupFn {
|
|
34
|
+
return (context) => {
|
|
35
|
+
// Only install SSR middleware in dev mode
|
|
36
|
+
if (context.action !== 'dev') {
|
|
37
|
+
return () => {}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const serverFnBase = opts.serverFnBasePath
|
|
41
|
+
|
|
42
|
+
const handleSSR: SSRMiddleware = async (req, res, next) => {
|
|
43
|
+
const ssrEnv =
|
|
44
|
+
context.server.environments[RSBUILD_ENVIRONMENT_NAMES.server]
|
|
45
|
+
|
|
46
|
+
if (!ssrEnv) {
|
|
47
|
+
console.error(
|
|
48
|
+
`[tanstack-start] SSR environment "${RSBUILD_ENVIRONMENT_NAMES.server}" not found`,
|
|
49
|
+
)
|
|
50
|
+
return next()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const serverEntry = await ssrEnv.loadBundle<{
|
|
55
|
+
default: { fetch: (req: Request) => Promise<Response> }
|
|
56
|
+
}>('index')
|
|
57
|
+
|
|
58
|
+
// Restore the original URL (rsbuild may rewrite to /index.html)
|
|
59
|
+
if (req.originalUrl) {
|
|
60
|
+
req.url = req.originalUrl
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const webReq = new NodeRequest({ req, res })
|
|
64
|
+
const webRes = await serverEntry.default.fetch(webReq)
|
|
65
|
+
return sendNodeResponse(res, webRes)
|
|
66
|
+
} catch (e) {
|
|
67
|
+
console.error('[tanstack-start] SSR error:', e)
|
|
68
|
+
|
|
69
|
+
const webReq = new NodeRequest({ req, res })
|
|
70
|
+
if (webReq.headers.get('content-type')?.includes('application/json')) {
|
|
71
|
+
return sendNodeResponse(
|
|
72
|
+
res,
|
|
73
|
+
new Response(
|
|
74
|
+
JSON.stringify(
|
|
75
|
+
{
|
|
76
|
+
status: 500,
|
|
77
|
+
error: 'Internal Server Error',
|
|
78
|
+
message:
|
|
79
|
+
'An unexpected error occurred. Please try again later.',
|
|
80
|
+
timestamp: new Date().toISOString(),
|
|
81
|
+
},
|
|
82
|
+
null,
|
|
83
|
+
2,
|
|
84
|
+
),
|
|
85
|
+
{
|
|
86
|
+
status: 500,
|
|
87
|
+
headers: { 'Content-Type': 'application/json' },
|
|
88
|
+
},
|
|
89
|
+
),
|
|
90
|
+
)
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
return sendNodeResponse(
|
|
94
|
+
res,
|
|
95
|
+
new Response(
|
|
96
|
+
`<!DOCTYPE html>
|
|
97
|
+
<html lang="en">
|
|
98
|
+
<head><meta charset="UTF-8" /><title>Error</title></head>
|
|
99
|
+
<body>
|
|
100
|
+
<h1>Internal Server Error</h1>
|
|
101
|
+
<pre>${e instanceof Error ? e.message : String(e)}</pre>
|
|
102
|
+
</body>
|
|
103
|
+
</html>`,
|
|
104
|
+
{
|
|
105
|
+
status: 500,
|
|
106
|
+
headers: { 'Content-Type': 'text/html' },
|
|
107
|
+
},
|
|
108
|
+
),
|
|
109
|
+
)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Position 1: BEFORE built-ins — intercept server function calls
|
|
114
|
+
// early so they are not swallowed by htmlFallback or assetsMiddleware.
|
|
115
|
+
context.server.middlewares.use(async (req, res, next) => {
|
|
116
|
+
const url = req.url || '/'
|
|
117
|
+
if (url.startsWith(serverFnBase)) {
|
|
118
|
+
return handleSSR(req, res, next)
|
|
119
|
+
}
|
|
120
|
+
return next()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Position 2: AFTER built-ins, before fallback — SSR catch-all for
|
|
124
|
+
// page navigations. Assets are already handled by rsbuild middleware.
|
|
125
|
+
return () => {
|
|
126
|
+
context.server.middlewares.use(handleSSR)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|