@rangojs/router 0.0.0-experimental.8a4d0430 → 0.0.0-experimental.8bcfea43
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/AGENTS.md +4 -0
- package/README.md +126 -38
- package/dist/bin/rango.js +138 -50
- package/dist/vite/index.js +1171 -461
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +19 -16
- package/skills/breadcrumbs/SKILL.md +3 -1
- package/skills/cache-guide/SKILL.md +32 -0
- package/skills/caching/SKILL.md +45 -4
- package/skills/handler-use/SKILL.md +362 -0
- package/skills/hooks/SKILL.md +28 -20
- package/skills/intercept/SKILL.md +20 -0
- package/skills/layout/SKILL.md +22 -0
- package/skills/links/SKILL.md +91 -17
- package/skills/loader/SKILL.md +88 -45
- package/skills/middleware/SKILL.md +34 -3
- package/skills/migrate-nextjs/SKILL.md +560 -0
- package/skills/migrate-react-router/SKILL.md +765 -0
- package/skills/parallel/SKILL.md +185 -0
- package/skills/prerender/SKILL.md +110 -68
- package/skills/rango/SKILL.md +24 -22
- package/skills/response-routes/SKILL.md +8 -0
- package/skills/route/SKILL.md +55 -0
- package/skills/router-setup/SKILL.md +87 -2
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/typesafety/SKILL.md +13 -1
- package/src/__internal.ts +1 -1
- package/src/browser/app-shell.ts +52 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/event-controller.ts +5 -0
- package/src/browser/navigation-bridge.ts +90 -16
- package/src/browser/navigation-client.ts +167 -59
- package/src/browser/navigation-store.ts +68 -9
- package/src/browser/navigation-transaction.ts +11 -9
- package/src/browser/partial-update.ts +113 -17
- package/src/browser/prefetch/cache.ts +184 -16
- package/src/browser/prefetch/fetch.ts +180 -33
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +123 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +53 -13
- package/src/browser/react/Link.tsx +81 -9
- package/src/browser/react/NavigationProvider.tsx +89 -14
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/use-handle.ts +9 -58
- package/src/browser/react/use-navigation.ts +22 -2
- package/src/browser/react/use-params.ts +11 -1
- package/src/browser/react/use-router.ts +29 -9
- package/src/browser/rsc-router.tsx +168 -65
- package/src/browser/scroll-restoration.ts +41 -42
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/server-action-bridge.ts +8 -6
- package/src/browser/types.ts +49 -5
- package/src/build/generate-manifest.ts +6 -6
- package/src/build/generate-route-types.ts +3 -0
- package/src/build/route-trie.ts +50 -24
- package/src/build/route-types/include-resolution.ts +8 -1
- package/src/build/route-types/router-processing.ts +223 -74
- package/src/build/route-types/scan-filter.ts +8 -1
- package/src/cache/cache-runtime.ts +15 -11
- package/src/cache/cache-scope.ts +48 -7
- package/src/cache/cf/cf-cache-store.ts +455 -15
- package/src/cache/cf/index.ts +5 -1
- package/src/cache/document-cache.ts +17 -7
- package/src/cache/index.ts +1 -0
- package/src/cache/taint.ts +55 -0
- package/src/client.tsx +84 -230
- package/src/context-var.ts +72 -2
- package/src/debug.ts +2 -2
- package/src/handle.ts +40 -0
- package/src/index.rsc.ts +6 -1
- package/src/index.ts +49 -6
- package/src/outlet-context.ts +1 -1
- package/src/prerender/store.ts +5 -4
- package/src/prerender.ts +138 -77
- package/src/response-utils.ts +28 -0
- package/src/reverse.ts +27 -2
- package/src/route-definition/dsl-helpers.ts +240 -40
- package/src/route-definition/helpers-types.ts +67 -19
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +11 -3
- package/src/route-definition/resolve-handler-use.ts +155 -0
- package/src/route-map-builder.ts +7 -1
- package/src/route-types.ts +18 -0
- package/src/router/content-negotiation.ts +100 -1
- package/src/router/find-match.ts +4 -2
- package/src/router/handler-context.ts +101 -25
- package/src/router/intercept-resolution.ts +11 -4
- package/src/router/lazy-includes.ts +10 -7
- package/src/router/loader-resolution.ts +159 -21
- package/src/router/logging.ts +5 -2
- package/src/router/manifest.ts +31 -16
- package/src/router/match-api.ts +127 -192
- package/src/router/match-middleware/background-revalidation.ts +30 -2
- package/src/router/match-middleware/cache-lookup.ts +94 -17
- package/src/router/match-middleware/cache-store.ts +53 -10
- package/src/router/match-middleware/intercept-resolution.ts +9 -7
- package/src/router/match-middleware/segment-resolution.ts +61 -5
- package/src/router/match-result.ts +104 -10
- package/src/router/metrics.ts +6 -1
- package/src/router/middleware-types.ts +8 -30
- package/src/router/middleware.ts +36 -10
- package/src/router/navigation-snapshot.ts +182 -0
- package/src/router/pattern-matching.ts +60 -9
- package/src/router/prerender-match.ts +110 -10
- package/src/router/preview-match.ts +30 -102
- package/src/router/request-classification.ts +310 -0
- package/src/router/route-snapshot.ts +245 -0
- package/src/router/router-context.ts +6 -1
- package/src/router/router-interfaces.ts +36 -4
- package/src/router/router-options.ts +37 -11
- package/src/router/segment-resolution/fresh.ts +198 -20
- package/src/router/segment-resolution/helpers.ts +29 -24
- package/src/router/segment-resolution/loader-cache.ts +1 -0
- package/src/router/segment-resolution/revalidation.ts +438 -300
- package/src/router/segment-wrappers.ts +2 -0
- package/src/router/trie-matching.ts +10 -4
- package/src/router/types.ts +1 -0
- package/src/router/url-params.ts +49 -0
- package/src/router.ts +60 -8
- package/src/rsc/handler.ts +478 -374
- package/src/rsc/helpers.ts +69 -41
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +5 -1
- package/src/rsc/progressive-enhancement.ts +16 -2
- package/src/rsc/response-route-handler.ts +14 -1
- package/src/rsc/rsc-rendering.ts +19 -1
- package/src/rsc/server-action.ts +10 -0
- package/src/rsc/ssr-setup.ts +2 -2
- package/src/rsc/types.ts +9 -1
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +122 -0
- package/src/segment-system.tsx +109 -23
- package/src/server/context.ts +166 -17
- package/src/server/handle-store.ts +19 -0
- package/src/server/loader-registry.ts +9 -8
- package/src/server/request-context.ts +194 -60
- package/src/ssr/index.tsx +4 -0
- package/src/static-handler.ts +18 -6
- package/src/types/cache-types.ts +4 -4
- package/src/types/handler-context.ts +137 -65
- package/src/types/loader-types.ts +41 -15
- package/src/types/request-scope.ts +126 -0
- package/src/types/route-entry.ts +19 -1
- package/src/types/segments.ts +2 -0
- package/src/urls/include-helper.ts +24 -14
- package/src/urls/path-helper-types.ts +39 -6
- package/src/urls/path-helper.ts +48 -13
- package/src/urls/pattern-types.ts +12 -0
- package/src/urls/response-types.ts +18 -16
- package/src/use-loader.tsx +77 -5
- package/src/vite/debug.ts +55 -0
- package/src/vite/discovery/bundle-postprocess.ts +30 -33
- package/src/vite/discovery/discover-routers.ts +5 -1
- package/src/vite/discovery/prerender-collection.ts +128 -74
- package/src/vite/discovery/state.ts +13 -6
- package/src/vite/index.ts +4 -0
- package/src/vite/plugin-types.ts +51 -79
- package/src/vite/plugins/cloudflare-protocol-loader-hook.d.mts +23 -0
- package/src/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/src/vite/plugins/cloudflare-protocol-stub.ts +214 -0
- package/src/vite/plugins/expose-action-id.ts +1 -3
- package/src/vite/plugins/expose-id-utils.ts +12 -0
- package/src/vite/plugins/expose-ids/handler-transform.ts +30 -0
- package/src/vite/plugins/expose-internal-ids.ts +257 -40
- package/src/vite/plugins/performance-tracks.ts +86 -0
- package/src/vite/plugins/refresh-cmd.ts +88 -26
- package/src/vite/plugins/version-plugin.ts +13 -1
- package/src/vite/rango.ts +204 -217
- package/src/vite/router-discovery.ts +335 -64
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/package-resolution.ts +41 -1
- package/src/vite/utils/prerender-utils.ts +37 -5
- package/src/vite/utils/shared-utils.ts +3 -2
package/src/vite/rango.ts
CHANGED
|
@@ -12,11 +12,10 @@ import { VIRTUAL_IDS } from "./plugins/virtual-entries.js";
|
|
|
12
12
|
import {
|
|
13
13
|
getExcludeDeps,
|
|
14
14
|
getPackageAliases,
|
|
15
|
+
getPublishedPackageName,
|
|
16
|
+
getVendorAliases,
|
|
15
17
|
} from "./utils/package-resolution.js";
|
|
16
|
-
import {
|
|
17
|
-
createScanFilter,
|
|
18
|
-
findRouterFiles,
|
|
19
|
-
} from "../build/generate-route-types.js";
|
|
18
|
+
import { findRouterFiles } from "../build/generate-route-types.js";
|
|
20
19
|
import { createVersionPlugin } from "./plugins/version-plugin.js";
|
|
21
20
|
import {
|
|
22
21
|
sharedEsbuildOptions,
|
|
@@ -24,15 +23,15 @@ import {
|
|
|
24
23
|
onwarn,
|
|
25
24
|
getManualChunks,
|
|
26
25
|
} from "./utils/shared-utils.js";
|
|
27
|
-
import type {
|
|
28
|
-
RangoOptions,
|
|
29
|
-
RangoNodeOptions,
|
|
30
|
-
RscPluginOptions,
|
|
31
|
-
} from "./plugin-types.js";
|
|
26
|
+
import type { RangoOptions } from "./plugin-types.js";
|
|
32
27
|
import { printBanner, rangoVersion } from "./utils/banner.js";
|
|
33
28
|
import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
34
29
|
import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
|
|
35
30
|
import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
31
|
+
import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
32
|
+
import { createRangoDebugger } from "./debug.js";
|
|
33
|
+
|
|
34
|
+
const debugConfig = createRangoDebugger("rango:config");
|
|
36
35
|
|
|
37
36
|
/**
|
|
38
37
|
* Vite plugin for @rangojs/router.
|
|
@@ -43,7 +42,7 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
|
43
42
|
* @example Node.js (default)
|
|
44
43
|
* ```ts
|
|
45
44
|
* export default defineConfig({
|
|
46
|
-
* plugins: [react(), rango(
|
|
45
|
+
* plugins: [react(), rango()],
|
|
47
46
|
* });
|
|
48
47
|
* ```
|
|
49
48
|
*
|
|
@@ -59,18 +58,40 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
|
59
58
|
* ```
|
|
60
59
|
*/
|
|
61
60
|
export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
61
|
+
const rangoStart = performance.now();
|
|
62
62
|
const resolvedOptions: RangoOptions = options ?? { preset: "node" };
|
|
63
63
|
const preset = resolvedOptions.preset ?? "node";
|
|
64
64
|
const showBanner = resolvedOptions.banner ?? true;
|
|
65
|
+
debugConfig?.("rango(%s) setup start", preset);
|
|
65
66
|
|
|
66
67
|
const plugins: PluginOption[] = [];
|
|
67
68
|
|
|
68
|
-
// Get package resolution info (workspace vs npm install)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
69
|
+
// Get package resolution info (workspace vs npm install).
|
|
70
|
+
// Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
|
|
71
|
+
// itself injects into optimizeDeps.include) to absolute paths resolved from
|
|
72
|
+
// this package — so strict-pnpm consumers don't hit "Failed to resolve
|
|
73
|
+
// dependency" warnings when those deps aren't hoisted to their app root.
|
|
74
|
+
const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
|
|
75
|
+
const excludeDeps = [
|
|
76
|
+
...getExcludeDeps(),
|
|
77
|
+
// plugin-rsc itself injects these into the client env's
|
|
78
|
+
// optimizeDeps.include, which overrides exclude for the dep's own
|
|
79
|
+
// pre-bundle entry. What exclude still controls is how *other*
|
|
80
|
+
// pre-bundled deps treat imports of these specs (external vs inlined)
|
|
81
|
+
// via esbuildCjsExternalPlugin. The cjs-to-esm transform in
|
|
82
|
+
// plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
|
|
83
|
+
// where client.browser's bare include fails to resolve and Vite ends up
|
|
84
|
+
// serving the raw CJS file at dev-serve time.
|
|
85
|
+
"@vitejs/plugin-rsc/browser",
|
|
86
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
// Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
|
|
90
|
+
// B from A's location. We anchor transitive deps (rsc-html-stream,
|
|
91
|
+
// @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
|
|
92
|
+
// these aren't visible at the app root — can still pre-bundle them.
|
|
93
|
+
const pkg = getPublishedPackageName();
|
|
94
|
+
const nested = (spec: string) => `${pkg} > ${spec}`;
|
|
74
95
|
|
|
75
96
|
// Mutable ref for router path (node preset only).
|
|
76
97
|
// Set immediately when user-specified, or populated by the auto-discover
|
|
@@ -126,7 +147,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
126
147
|
// Pre-bundle rsc-html-stream to prevent discovery during first request
|
|
127
148
|
// Exclude rsc-router modules to ensure same Context instance
|
|
128
149
|
optimizeDeps: {
|
|
129
|
-
include: ["rsc-html-stream/client"],
|
|
150
|
+
include: [nested("rsc-html-stream/client")],
|
|
130
151
|
exclude: excludeDeps,
|
|
131
152
|
esbuildOptions: sharedEsbuildOptions,
|
|
132
153
|
},
|
|
@@ -151,8 +172,10 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
151
172
|
"react-dom/static.edge",
|
|
152
173
|
"react/jsx-runtime",
|
|
153
174
|
"react/jsx-dev-runtime",
|
|
154
|
-
"rsc-html-stream/server",
|
|
155
|
-
|
|
175
|
+
nested("rsc-html-stream/server"),
|
|
176
|
+
nested(
|
|
177
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
178
|
+
),
|
|
156
179
|
],
|
|
157
180
|
exclude: excludeDeps,
|
|
158
181
|
esbuildOptions: sharedEsbuildOptions,
|
|
@@ -167,7 +190,9 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
167
190
|
"react",
|
|
168
191
|
"react/jsx-runtime",
|
|
169
192
|
"react/jsx-dev-runtime",
|
|
170
|
-
|
|
193
|
+
nested(
|
|
194
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
195
|
+
),
|
|
171
196
|
],
|
|
172
197
|
exclude: excludeDeps,
|
|
173
198
|
esbuildOptions: sharedEsbuildOptions,
|
|
@@ -192,6 +217,9 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
192
217
|
|
|
193
218
|
plugins.push(createVirtualEntriesPlugin(finalEntries));
|
|
194
219
|
|
|
220
|
+
// Dev-only: RSDW client patch for React Performance Tracks
|
|
221
|
+
plugins.push(performanceTracksPlugin());
|
|
222
|
+
|
|
195
223
|
// Add RSC plugin with cloudflare-specific options
|
|
196
224
|
// Note: loadModuleDevProxy should NOT be used with childEnvironments
|
|
197
225
|
// since SSR runs in workerd alongside RSC
|
|
@@ -207,198 +235,155 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
207
235
|
// packages that are also imported directly by client components.
|
|
208
236
|
plugins.push(clientRefDedup());
|
|
209
237
|
} else {
|
|
210
|
-
//
|
|
211
|
-
|
|
238
|
+
// Auto-discover router using Vite's resolved root (not process.cwd())
|
|
239
|
+
plugins.push({
|
|
240
|
+
name: "@rangojs/router:auto-discover",
|
|
241
|
+
config(userConfig) {
|
|
242
|
+
if (routerRef.path) return;
|
|
243
|
+
const root = userConfig.root
|
|
244
|
+
? resolve(process.cwd(), userConfig.root)
|
|
245
|
+
: process.cwd();
|
|
246
|
+
const candidates = findRouterFiles(root);
|
|
247
|
+
if (candidates.length === 1) {
|
|
248
|
+
const abs = candidates[0];
|
|
249
|
+
routerRef.path = (
|
|
250
|
+
abs.startsWith(root) ? "./" + abs.slice(root.length + 1) : abs
|
|
251
|
+
).replaceAll("\\", "/");
|
|
252
|
+
} else if (candidates.length > 1) {
|
|
253
|
+
const list = candidates
|
|
254
|
+
.map(
|
|
255
|
+
(f) =>
|
|
256
|
+
" - " + (f.startsWith(root) ? f.slice(root.length + 1) : f),
|
|
257
|
+
)
|
|
258
|
+
.join("\n");
|
|
259
|
+
throw new Error(`[rsc-router] Multiple routers found:\n${list}`);
|
|
260
|
+
}
|
|
261
|
+
// 0 found: routerRef.path stays undefined, warn at startup via discovery plugin
|
|
262
|
+
},
|
|
263
|
+
});
|
|
212
264
|
|
|
213
|
-
|
|
265
|
+
// Always use virtual entries for client, ssr, and rsc
|
|
266
|
+
const finalEntries = {
|
|
267
|
+
client: VIRTUAL_IDS.browser,
|
|
268
|
+
ssr: VIRTUAL_IDS.ssr,
|
|
269
|
+
rsc: VIRTUAL_IDS.rsc,
|
|
270
|
+
};
|
|
214
271
|
|
|
215
|
-
//
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
`[rsc-router] Multiple routers found. Specify \`router\` to choose one:\n${list}`,
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
// 0 found: routerRef.path stays undefined, warn at startup via discovery plugin
|
|
246
|
-
},
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
const rscOption = nodeOptions.rsc ?? true;
|
|
251
|
-
|
|
252
|
-
// Add RSC plugin by default (can be disabled with rsc: false)
|
|
253
|
-
if (rscOption !== false) {
|
|
254
|
-
// Dynamically import @vitejs/plugin-rsc
|
|
255
|
-
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
256
|
-
|
|
257
|
-
// Resolve entry paths: use explicit config or virtual modules
|
|
258
|
-
const userEntries =
|
|
259
|
-
typeof rscOption === "boolean" ? {} : rscOption.entries || {};
|
|
260
|
-
const finalEntries = {
|
|
261
|
-
client: userEntries.client ?? VIRTUAL_IDS.browser,
|
|
262
|
-
ssr: userEntries.ssr ?? VIRTUAL_IDS.ssr,
|
|
263
|
-
rsc: userEntries.rsc ?? VIRTUAL_IDS.rsc,
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
// Track RSC entry for version injection (only if custom entry provided)
|
|
267
|
-
rscEntryPath = userEntries.rsc ?? null;
|
|
268
|
-
|
|
269
|
-
// Create wrapper plugin that checks for duplicates
|
|
270
|
-
let hasWarnedDuplicate = false;
|
|
271
|
-
|
|
272
|
-
plugins.push({
|
|
273
|
-
name: "@rangojs/router:rsc-integration",
|
|
274
|
-
enforce: "pre",
|
|
275
|
-
|
|
276
|
-
config() {
|
|
277
|
-
// Configure environments for RSC
|
|
278
|
-
// When using virtual entries, we need to explicitly configure optimizeDeps
|
|
279
|
-
// so Vite pre-bundles React before processing the virtual modules.
|
|
280
|
-
// Without this, the dep optimizer may run multiple times with different hashes,
|
|
281
|
-
// causing React instance mismatches.
|
|
282
|
-
const useVirtualClient = finalEntries.client === VIRTUAL_IDS.browser;
|
|
283
|
-
const useVirtualSSR = finalEntries.ssr === VIRTUAL_IDS.ssr;
|
|
284
|
-
const useVirtualRSC = finalEntries.rsc === VIRTUAL_IDS.rsc;
|
|
285
|
-
|
|
286
|
-
return {
|
|
287
|
-
// Exclude rsc-router modules from optimization to prevent module duplication
|
|
288
|
-
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
289
|
-
optimizeDeps: {
|
|
290
|
-
exclude: excludeDeps,
|
|
291
|
-
esbuildOptions: sharedEsbuildOptions,
|
|
292
|
-
},
|
|
293
|
-
build: {
|
|
294
|
-
rollupOptions: { onwarn },
|
|
295
|
-
},
|
|
296
|
-
resolve: {
|
|
297
|
-
alias: rangoAliases,
|
|
298
|
-
},
|
|
299
|
-
environments: {
|
|
300
|
-
client: {
|
|
301
|
-
build: {
|
|
302
|
-
rollupOptions: {
|
|
303
|
-
output: {
|
|
304
|
-
manualChunks: getManualChunks,
|
|
305
|
-
},
|
|
272
|
+
// Dynamically import @vitejs/plugin-rsc
|
|
273
|
+
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
274
|
+
|
|
275
|
+
let hasWarnedDuplicate = false;
|
|
276
|
+
|
|
277
|
+
plugins.push({
|
|
278
|
+
name: "@rangojs/router:rsc-integration",
|
|
279
|
+
enforce: "pre",
|
|
280
|
+
|
|
281
|
+
config() {
|
|
282
|
+
return {
|
|
283
|
+
optimizeDeps: {
|
|
284
|
+
exclude: excludeDeps,
|
|
285
|
+
esbuildOptions: sharedEsbuildOptions,
|
|
286
|
+
},
|
|
287
|
+
build: {
|
|
288
|
+
rollupOptions: { onwarn },
|
|
289
|
+
},
|
|
290
|
+
resolve: {
|
|
291
|
+
alias: rangoAliases,
|
|
292
|
+
},
|
|
293
|
+
environments: {
|
|
294
|
+
client: {
|
|
295
|
+
build: {
|
|
296
|
+
rollupOptions: {
|
|
297
|
+
output: {
|
|
298
|
+
manualChunks: getManualChunks,
|
|
306
299
|
},
|
|
307
300
|
},
|
|
308
|
-
// Always exclude rsc-router modules, conditionally add virtual entry
|
|
309
|
-
optimizeDeps: {
|
|
310
|
-
// Pre-bundle React and rsc-html-stream to prevent late discovery
|
|
311
|
-
// triggering ERR_OUTDATED_OPTIMIZED_DEP on cold starts
|
|
312
|
-
include: [
|
|
313
|
-
"react",
|
|
314
|
-
"react-dom",
|
|
315
|
-
"react/jsx-runtime",
|
|
316
|
-
"react/jsx-dev-runtime",
|
|
317
|
-
"rsc-html-stream/client",
|
|
318
|
-
],
|
|
319
|
-
exclude: excludeDeps,
|
|
320
|
-
esbuildOptions: sharedEsbuildOptions,
|
|
321
|
-
...(useVirtualClient && {
|
|
322
|
-
// Tell Vite to scan the virtual entry for dependencies
|
|
323
|
-
entries: [VIRTUAL_IDS.browser],
|
|
324
|
-
}),
|
|
325
|
-
},
|
|
326
301
|
},
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
340
|
-
],
|
|
341
|
-
exclude: excludeDeps,
|
|
342
|
-
esbuildOptions: sharedEsbuildOptions,
|
|
343
|
-
},
|
|
344
|
-
},
|
|
345
|
-
}),
|
|
346
|
-
...(useVirtualRSC && {
|
|
347
|
-
rsc: {
|
|
348
|
-
optimizeDeps: {
|
|
349
|
-
entries: [VIRTUAL_IDS.rsc],
|
|
350
|
-
// Pre-bundle all RSC deps to prevent late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
351
|
-
include: [
|
|
352
|
-
"react",
|
|
353
|
-
"react/jsx-runtime",
|
|
354
|
-
"react/jsx-dev-runtime",
|
|
355
|
-
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
356
|
-
],
|
|
357
|
-
esbuildOptions: sharedEsbuildOptions,
|
|
358
|
-
},
|
|
359
|
-
},
|
|
360
|
-
}),
|
|
302
|
+
optimizeDeps: {
|
|
303
|
+
include: [
|
|
304
|
+
"react",
|
|
305
|
+
"react-dom",
|
|
306
|
+
"react/jsx-runtime",
|
|
307
|
+
"react/jsx-dev-runtime",
|
|
308
|
+
nested("rsc-html-stream/client"),
|
|
309
|
+
],
|
|
310
|
+
exclude: excludeDeps,
|
|
311
|
+
esbuildOptions: sharedEsbuildOptions,
|
|
312
|
+
entries: [VIRTUAL_IDS.browser],
|
|
313
|
+
},
|
|
361
314
|
},
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
315
|
+
ssr: {
|
|
316
|
+
optimizeDeps: {
|
|
317
|
+
entries: [VIRTUAL_IDS.ssr],
|
|
318
|
+
include: [
|
|
319
|
+
"react",
|
|
320
|
+
"react-dom",
|
|
321
|
+
"react-dom/server.edge",
|
|
322
|
+
"react-dom/static.edge",
|
|
323
|
+
"react/jsx-runtime",
|
|
324
|
+
"react/jsx-dev-runtime",
|
|
325
|
+
nested(
|
|
326
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
327
|
+
),
|
|
328
|
+
],
|
|
329
|
+
exclude: excludeDeps,
|
|
330
|
+
esbuildOptions: sharedEsbuildOptions,
|
|
331
|
+
},
|
|
332
|
+
},
|
|
333
|
+
rsc: {
|
|
334
|
+
optimizeDeps: {
|
|
335
|
+
entries: [VIRTUAL_IDS.rsc],
|
|
336
|
+
include: [
|
|
337
|
+
"react",
|
|
338
|
+
"react/jsx-runtime",
|
|
339
|
+
"react/jsx-dev-runtime",
|
|
340
|
+
nested(
|
|
341
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
342
|
+
),
|
|
343
|
+
],
|
|
344
|
+
esbuildOptions: sharedEsbuildOptions,
|
|
345
|
+
},
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
};
|
|
349
|
+
},
|
|
350
|
+
|
|
351
|
+
configResolved(config) {
|
|
352
|
+
if (showBanner) {
|
|
353
|
+
const mode =
|
|
354
|
+
config.command === "serve"
|
|
355
|
+
? process.argv.includes("preview")
|
|
356
|
+
? "preview"
|
|
357
|
+
: "dev"
|
|
358
|
+
: "build";
|
|
359
|
+
printBanner(mode, "node", rangoVersion);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
const rscMinimalCount = config.plugins.filter(
|
|
363
|
+
(p) => p.name === "rsc:minimal",
|
|
364
|
+
).length;
|
|
365
|
+
|
|
366
|
+
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
367
|
+
hasWarnedDuplicate = true;
|
|
368
|
+
console.warn(
|
|
369
|
+
"[rsc-router] Duplicate @vitejs/plugin-rsc detected. " +
|
|
370
|
+
"Remove rsc() from your vite config — rango() includes it automatically.",
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
},
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
// Add virtual entries plugin (RSC entry generated lazily from routerRef)
|
|
377
|
+
plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
|
|
378
|
+
|
|
379
|
+
// Dev-only: RSDW client patch for React Performance Tracks
|
|
380
|
+
plugins.push(performanceTracksPlugin());
|
|
381
|
+
|
|
382
|
+
plugins.push(
|
|
383
|
+
rsc({
|
|
384
|
+
entries: finalEntries,
|
|
385
|
+
}) as PluginOption,
|
|
386
|
+
);
|
|
402
387
|
|
|
403
388
|
// Deduplicate client references from third-party packages in dev mode.
|
|
404
389
|
// Prevents module duplication when server components import "use client"
|
|
@@ -479,14 +464,11 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
479
464
|
// Ref for deferred auto-discovery (node preset only, undefined for cloudflare)
|
|
480
465
|
const discoveryRouterRef = preset !== "cloudflare" ? routerRef : undefined;
|
|
481
466
|
|
|
482
|
-
// Version injector: auto-injects VERSION and routes-manifest into
|
|
483
|
-
//
|
|
484
|
-
//
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
rscEntryPath ?? (preset === "cloudflare" ? undefined : null);
|
|
488
|
-
if (injectorEntryPath !== null) {
|
|
489
|
-
plugins.push(createVersionInjectorPlugin(injectorEntryPath));
|
|
467
|
+
// Version injector: auto-injects VERSION and routes-manifest into the RSC entry.
|
|
468
|
+
// For cloudflare preset, the entry is resolved lazily in configResolved.
|
|
469
|
+
// For node preset, the virtual entry already includes these imports.
|
|
470
|
+
if (preset === "cloudflare") {
|
|
471
|
+
plugins.push(createVersionInjectorPlugin(undefined));
|
|
490
472
|
}
|
|
491
473
|
|
|
492
474
|
// Transform CJS vendor files to ESM for browser compatibility
|
|
@@ -500,11 +482,16 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
500
482
|
createRouterDiscoveryPlugin(discoveryEntryPath, {
|
|
501
483
|
routerPathRef: discoveryRouterRef,
|
|
502
484
|
enableBuildPrerender: prerenderEnabled,
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
exclude: resolvedOptions.exclude,
|
|
485
|
+
buildEnv: options?.buildEnv,
|
|
486
|
+
preset,
|
|
506
487
|
}),
|
|
507
488
|
);
|
|
508
489
|
|
|
490
|
+
debugConfig?.(
|
|
491
|
+
"rango(%s) setup done: %d plugin(s) (%sms)",
|
|
492
|
+
preset,
|
|
493
|
+
plugins.length,
|
|
494
|
+
(performance.now() - rangoStart).toFixed(1),
|
|
495
|
+
);
|
|
509
496
|
return plugins;
|
|
510
497
|
}
|