@rangojs/router 0.0.0-experimental.d20dd405 → 0.0.0-experimental.dacec167
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/README.md +8 -8
- package/dist/bin/rango.js +147 -57
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +914 -485
- package/package.json +55 -11
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +220 -30
- package/skills/caching/SKILL.md +116 -8
- package/skills/composability/SKILL.md +27 -2
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +1 -1
- package/skills/hooks/SKILL.md +196 -21
- package/skills/host-router/SKILL.md +45 -20
- package/skills/intercept/SKILL.md +1 -4
- package/skills/layout/SKILL.md +4 -7
- package/skills/links/SKILL.md +22 -10
- package/skills/loader/SKILL.md +149 -6
- package/skills/middleware/SKILL.md +13 -9
- package/skills/migrate-nextjs/SKILL.md +1 -1
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +3 -6
- package/skills/prerender/SKILL.md +14 -33
- package/skills/rango/SKILL.md +242 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +58 -9
- package/skills/route/SKILL.md +9 -4
- package/skills/router-setup/SKILL.md +3 -3
- package/skills/server-actions/SKILL.md +53 -41
- package/skills/testing/SKILL.md +778 -0
- package/skills/typesafety/SKILL.md +310 -26
- package/skills/use-cache/SKILL.md +34 -5
- package/skills/view-transitions/SKILL.md +85 -3
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +117 -0
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/event-controller.ts +42 -66
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/navigation-bridge.ts +9 -67
- package/src/browser/navigation-client.ts +12 -15
- package/src/browser/navigation-store.ts +7 -8
- package/src/browser/navigation-transaction.ts +10 -28
- package/src/browser/partial-update.ts +8 -16
- package/src/browser/react/NavigationProvider.tsx +55 -65
- package/src/browser/react/location-state-shared.ts +175 -4
- package/src/browser/react/location-state.ts +39 -13
- package/src/browser/react/use-handle.ts +17 -9
- package/src/browser/react/use-params.ts +3 -4
- package/src/browser/react/use-reverse.ts +19 -12
- package/src/browser/react/use-router.ts +14 -1
- package/src/browser/response-adapter.ts +25 -0
- package/src/browser/rsc-router.tsx +30 -16
- package/src/browser/scroll-restoration.ts +30 -25
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +23 -30
- package/src/browser/types.ts +2 -0
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +60 -35
- package/src/build/generate-route-types.ts +2 -0
- package/src/build/index.ts +2 -0
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +1 -1
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +55 -14
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-scope.ts +28 -42
- package/src/cache/cf/cf-cache-store.ts +49 -6
- package/src/client.tsx +5 -7
- package/src/context-var.ts +5 -5
- package/src/decode-loader-results.ts +36 -0
- package/src/errors.ts +30 -1
- package/src/handle.ts +26 -13
- package/src/host/index.ts +2 -2
- package/src/host/router.ts +129 -57
- package/src/host/types.ts +31 -2
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +136 -19
- package/src/index.rsc.ts +6 -4
- package/src/index.ts +13 -6
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +21 -6
- package/src/loader.ts +3 -10
- package/src/missing-id-error.ts +68 -0
- package/src/prerender.ts +4 -4
- package/src/response-utils.ts +9 -0
- package/src/reverse.ts +16 -13
- package/src/route-content-wrapper.tsx +6 -28
- package/src/route-definition/dsl-helpers.ts +238 -263
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +37 -14
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-types.ts +19 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +15 -2
- package/src/router/error-handling.ts +1 -1
- package/src/router/intercept-resolution.ts +4 -18
- package/src/router/lazy-includes.ts +2 -2
- package/src/router/loader-resolution.ts +16 -2
- package/src/router/match-handlers.ts +62 -20
- package/src/router/match-middleware/cache-lookup.ts +44 -91
- package/src/router/match-middleware/cache-store.ts +3 -2
- package/src/router/match-result.ts +32 -30
- package/src/router/metrics.ts +1 -1
- package/src/router/middleware-types.ts +1 -1
- package/src/router/middleware.ts +46 -78
- package/src/router/prerender-match.ts +1 -1
- package/src/router/preview-match.ts +3 -1
- package/src/router/request-classification.ts +4 -28
- package/src/router/revalidation.ts +43 -1
- package/src/router/router-interfaces.ts +45 -28
- package/src/router/router-options.ts +40 -1
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +19 -6
- package/src/router/segment-resolution/revalidation.ts +19 -6
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/telemetry.ts +99 -0
- package/src/router/types.ts +8 -0
- package/src/router.ts +37 -21
- package/src/rsc/handler-context.ts +2 -2
- package/src/rsc/handler.ts +20 -65
- package/src/rsc/helpers.ts +22 -2
- package/src/rsc/index.ts +1 -1
- package/src/rsc/origin-guard.ts +28 -10
- package/src/rsc/response-route-handler.ts +32 -52
- package/src/rsc/rsc-rendering.ts +27 -53
- package/src/rsc/runtime-warnings.ts +9 -10
- package/src/rsc/server-action.ts +13 -37
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/types.ts +2 -2
- package/src/search-params.ts +4 -4
- package/src/segment-system.tsx +64 -49
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +118 -51
- package/src/server/cookie-store.ts +28 -4
- package/src/server/request-context.ts +10 -0
- package/src/static-handler.ts +1 -1
- package/src/testing/cache-status.ts +166 -0
- package/src/testing/collect-handle.ts +63 -0
- package/src/testing/dispatch.ts +440 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +154 -0
- package/src/testing/e2e/index.ts +149 -0
- package/src/testing/e2e/matchers.ts +51 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +306 -0
- package/src/testing/e2e/server.ts +183 -0
- package/src/testing/flight-matchers.ts +104 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +320 -0
- package/src/testing/flight.entry.ts +39 -0
- package/src/testing/flight.ts +197 -0
- package/src/testing/generated-routes.ts +223 -0
- package/src/testing/index.ts +106 -0
- package/src/testing/internal/context.ts +331 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/render-route.tsx +565 -0
- package/src/testing/run-loader.ts +341 -0
- package/src/testing/run-middleware.ts +188 -0
- package/src/testing/vitest-stubs/cloudflare-email.ts +9 -0
- package/src/testing/vitest-stubs/cloudflare-workers.ts +21 -0
- package/src/testing/vitest-stubs/plugin-rsc.ts +16 -0
- package/src/testing/vitest-stubs/version.ts +5 -0
- package/src/testing/vitest.ts +270 -0
- package/src/types/global-namespace.ts +39 -26
- package/src/types/handler-context.ts +56 -11
- package/src/types/index.ts +1 -0
- package/src/types/segments.ts +18 -1
- package/src/urls/include-helper.ts +10 -53
- package/src/urls/index.ts +0 -3
- package/src/urls/path-helper-types.ts +11 -3
- package/src/urls/path-helper.ts +17 -52
- package/src/urls/pattern-types.ts +36 -19
- package/src/urls/response-types.ts +20 -19
- package/src/urls/type-extraction.ts +26 -116
- package/src/urls/urls-function.ts +1 -5
- package/src/use-loader.tsx +413 -42
- package/src/vite/debug.ts +1 -0
- package/src/vite/discovery/bundle-postprocess.ts +6 -6
- package/src/vite/discovery/discover-routers.ts +70 -48
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/prerender-collection.ts +19 -25
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/state.ts +33 -0
- package/src/vite/discovery/virtual-module-codegen.ts +13 -23
- package/src/vite/index.ts +2 -0
- package/src/vite/plugin-types.ts +67 -0
- package/src/vite/plugins/cjs-to-esm.ts +3 -7
- package/src/vite/plugins/client-ref-hashing.ts +12 -1
- package/src/vite/plugins/cloudflare-protocol-stub.ts +1 -1
- package/src/vite/plugins/expose-action-id.ts +2 -2
- package/src/vite/plugins/expose-id-utils.ts +12 -8
- package/src/vite/plugins/expose-ids/export-analysis.ts +100 -20
- package/src/vite/plugins/expose-ids/handler-transform.ts +8 -61
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -5
- package/src/vite/plugins/expose-internal-ids.ts +47 -67
- package/src/vite/plugins/performance-tracks.ts +12 -16
- package/src/vite/plugins/use-cache-transform.ts +13 -11
- package/src/vite/plugins/version-injector.ts +2 -12
- package/src/vite/plugins/version-plugin.ts +59 -2
- package/src/vite/plugins/virtual-entries.ts +2 -2
- package/src/vite/rango.ts +67 -15
- package/src/vite/router-discovery.ts +208 -63
- package/src/vite/utils/ast-handler-extract.ts +15 -15
- package/src/vite/utils/bundle-analysis.ts +4 -2
- package/src/vite/utils/client-chunks.ts +190 -0
- package/src/vite/utils/forward-user-plugins.ts +193 -0
- package/src/vite/utils/manifest-utils.ts +21 -5
- package/src/vite/utils/shared-utils.ts +107 -26
- package/src/browser/action-response-classifier.ts +0 -99
|
@@ -18,7 +18,7 @@ function getClientModuleSignature(
|
|
|
18
18
|
): ClientModuleSignature | undefined {
|
|
19
19
|
let program: any;
|
|
20
20
|
try {
|
|
21
|
-
program = parseAst(source, {
|
|
21
|
+
program = parseAst(source, { lang: "tsx" });
|
|
22
22
|
} catch {
|
|
23
23
|
return undefined;
|
|
24
24
|
}
|
|
@@ -133,6 +133,7 @@ export function createVersionPlugin(): Plugin {
|
|
|
133
133
|
let currentVersion = buildVersion;
|
|
134
134
|
let isDev = false;
|
|
135
135
|
let server: any = null;
|
|
136
|
+
let resolvedCacheDir: string | undefined;
|
|
136
137
|
const clientModuleSignatures = new Map<string, ClientModuleSignature>();
|
|
137
138
|
|
|
138
139
|
let versionCounter = 0;
|
|
@@ -140,7 +141,7 @@ export function createVersionPlugin(): Plugin {
|
|
|
140
141
|
// Use timestamp + counter to guarantee uniqueness even when multiple
|
|
141
142
|
// bumps happen within the same millisecond (e.g. cascading HMR events).
|
|
142
143
|
currentVersion = Date.now().toString(16) + String(++versionCounter);
|
|
143
|
-
console.log(`[
|
|
144
|
+
console.log(`[rango] ${reason}, version updated: ${currentVersion}`);
|
|
144
145
|
|
|
145
146
|
const rscEnv = server?.environments?.rsc;
|
|
146
147
|
const versionMod = rscEnv?.moduleGraph?.getModuleById(
|
|
@@ -157,6 +158,12 @@ export function createVersionPlugin(): Plugin {
|
|
|
157
158
|
|
|
158
159
|
configResolved(config) {
|
|
159
160
|
isDev = config.command === "serve";
|
|
161
|
+
// Capture the resolved cacheDir so we can ignore optimizer-output
|
|
162
|
+
// writes inside it. Vite resolves cacheDir against the project root,
|
|
163
|
+
// so this is a stable absolute path for the lifetime of the server.
|
|
164
|
+
resolvedCacheDir = config.cacheDir
|
|
165
|
+
? String(config.cacheDir).replace(/\\/g, "/")
|
|
166
|
+
: undefined;
|
|
160
167
|
},
|
|
161
168
|
|
|
162
169
|
configureServer(devServer) {
|
|
@@ -214,6 +221,14 @@ export function createVersionPlugin(): Plugin {
|
|
|
214
221
|
|
|
215
222
|
if (!isRscModule) return;
|
|
216
223
|
|
|
224
|
+
// Skip Vite's own pre-bundled dep cache writes. The optimizer rewrites
|
|
225
|
+
// files inside the configured `cacheDir` on every discovery cycle
|
|
226
|
+
// (and when other dev servers under the same cwd populate their own
|
|
227
|
+
// isolated cache dirs). These are not user-source changes, so bumping
|
|
228
|
+
// the app version on them produces spurious version mismatches that
|
|
229
|
+
// surface as forced reloads on in-flight actions.
|
|
230
|
+
if (isViteDepCachePath(ctx.file, resolvedCacheDir)) return;
|
|
231
|
+
|
|
217
232
|
// Skip re-bumping when the version virtual module itself is invalidated
|
|
218
233
|
// (our own bumpVersion() invalidates it, which re-triggers hotUpdate).
|
|
219
234
|
if (
|
|
@@ -264,3 +279,45 @@ export function createVersionPlugin(): Plugin {
|
|
|
264
279
|
},
|
|
265
280
|
};
|
|
266
281
|
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* Match Vite's pre-bundled dep cache directories. These paths are rewritten
|
|
285
|
+
* by the dep optimizer (and by isolated test fixtures sharing the same cwd),
|
|
286
|
+
* not by user source changes, so they should not bump the app version (which
|
|
287
|
+
* would force a client reload mid-request).
|
|
288
|
+
*
|
|
289
|
+
* Two checks:
|
|
290
|
+
* 1. Anything inside the resolved `cacheDir` (precise — covers custom paths
|
|
291
|
+
* like the `RANGO_E2E_VITE_CACHE_DIR` overrides in the test fixtures).
|
|
292
|
+
* 2. Heuristic match for any `node_modules/.vite*` directory or a
|
|
293
|
+
* `.vite-isolated/` segment anywhere in the path. This catches the
|
|
294
|
+
* *other* dev servers in the same cwd whose cacheDir we cannot read
|
|
295
|
+
* (we only see config of the server we're attached to).
|
|
296
|
+
*/
|
|
297
|
+
export function isViteDepCachePath(
|
|
298
|
+
filePath: string | undefined,
|
|
299
|
+
cacheDir?: string,
|
|
300
|
+
): boolean {
|
|
301
|
+
if (!filePath) return false;
|
|
302
|
+
const normalized = filePath.replace(/\\/g, "/");
|
|
303
|
+
|
|
304
|
+
if (cacheDir) {
|
|
305
|
+
const normalizedCacheDir = cacheDir.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
306
|
+
if (
|
|
307
|
+
normalized === normalizedCacheDir ||
|
|
308
|
+
normalized.startsWith(normalizedCacheDir + "/")
|
|
309
|
+
) {
|
|
310
|
+
return true;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Vite/optimizer convention: cache dirs always sit directly under
|
|
315
|
+
// `node_modules/` and start with `.vite` (e.g. `.vite`, `.vite-temp`,
|
|
316
|
+
// `.vite_rango_generate`, `.vite-e2e-test-app`). The `/.vite-isolated/`
|
|
317
|
+
// segment covers the test-fixture pattern that places the cache outside
|
|
318
|
+
// node_modules.
|
|
319
|
+
return (
|
|
320
|
+
/\/node_modules\/\.vite[^/]*\//.test(normalized) ||
|
|
321
|
+
normalized.includes("/.vite-isolated/")
|
|
322
|
+
);
|
|
323
|
+
}
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
import { createElement, StrictMode } from "react";
|
|
15
15
|
import { hydrateRoot } from "react-dom/client";
|
|
16
16
|
import { rscStream } from "@rangojs/router/internal/deps/html-stream-client";
|
|
17
|
-
import { initBrowserApp,
|
|
17
|
+
import { initBrowserApp, Rango } from "@rangojs/router/browser";
|
|
18
18
|
|
|
19
19
|
async function initializeApp() {
|
|
20
20
|
const deps = {
|
|
@@ -29,7 +29,7 @@ async function initializeApp() {
|
|
|
29
29
|
|
|
30
30
|
hydrateRoot(
|
|
31
31
|
document,
|
|
32
|
-
createElement(StrictMode, null, createElement(
|
|
32
|
+
createElement(StrictMode, null, createElement(Rango))
|
|
33
33
|
);
|
|
34
34
|
}
|
|
35
35
|
|
package/src/vite/rango.ts
CHANGED
|
@@ -18,11 +18,15 @@ import {
|
|
|
18
18
|
import { findRouterFiles } from "../build/generate-route-types.js";
|
|
19
19
|
import { createVersionPlugin } from "./plugins/version-plugin.js";
|
|
20
20
|
import {
|
|
21
|
-
|
|
21
|
+
sharedRolldownOptions,
|
|
22
22
|
createVirtualEntriesPlugin,
|
|
23
23
|
onwarn,
|
|
24
24
|
getManualChunks,
|
|
25
25
|
} from "./utils/shared-utils.js";
|
|
26
|
+
import {
|
|
27
|
+
resolveClientChunks,
|
|
28
|
+
type ClientChunkContext,
|
|
29
|
+
} from "./utils/client-chunks.js";
|
|
26
30
|
import type { RangoOptions } from "./plugin-types.js";
|
|
27
31
|
import { printBanner, rangoVersion } from "./utils/banner.js";
|
|
28
32
|
import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
@@ -62,6 +66,23 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
62
66
|
const resolvedOptions: RangoOptions = options ?? { preset: "node" };
|
|
63
67
|
const preset = resolvedOptions.preset ?? "node";
|
|
64
68
|
const showBanner = resolvedOptions.banner ?? true;
|
|
69
|
+
// Client-chunking strategy (per-route/per-feature splitting of the browser
|
|
70
|
+
// bundle). Defaults to the built-in directory strategy (`true`) pre-1.0; pass
|
|
71
|
+
// `clientChunks: false` to opt out. Resolved once and forwarded to
|
|
72
|
+
// @vitejs/plugin-rsc in both presets. The built-in strategy only splits where it
|
|
73
|
+
// recognizes a route structure, so this default is a no-op for flat / host-split
|
|
74
|
+
// apps and never duplicates the shared runtime.
|
|
75
|
+
const clientChunksOption = resolvedOptions.clientChunks ?? true;
|
|
76
|
+
// Shared context the built-in strategy reads at build time: the production
|
|
77
|
+
// hashes of registered error/notFound fallback modules (-> app-fallback).
|
|
78
|
+
// Populated by the discovery plugin in buildStart, before the client build
|
|
79
|
+
// invokes the strategy. Only wired when the built-in strategy is active; a
|
|
80
|
+
// custom function owns its own grouping.
|
|
81
|
+
const useBuiltInClientChunks = clientChunksOption === true;
|
|
82
|
+
const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
|
|
83
|
+
? { fallbackRefs: new Set<string>() }
|
|
84
|
+
: undefined;
|
|
85
|
+
const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
|
|
65
86
|
debugConfig?.("rango(%s) setup start", preset);
|
|
66
87
|
|
|
67
88
|
const plugins: PluginOption[] = [];
|
|
@@ -127,10 +148,18 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
127
148
|
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
128
149
|
optimizeDeps: {
|
|
129
150
|
exclude: excludeDeps,
|
|
130
|
-
|
|
151
|
+
rolldownOptions: sharedRolldownOptions,
|
|
131
152
|
},
|
|
132
153
|
resolve: {
|
|
133
154
|
alias: rangoAliases,
|
|
155
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
156
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
157
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
158
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
159
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
160
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
161
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
162
|
+
dedupe: ["react", "react-dom"],
|
|
134
163
|
},
|
|
135
164
|
build: {
|
|
136
165
|
rollupOptions: { onwarn },
|
|
@@ -139,6 +168,14 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
139
168
|
client: {
|
|
140
169
|
build: {
|
|
141
170
|
rollupOptions: {
|
|
171
|
+
// FILE_NAME_CONFLICT (and any other client-build warning) is
|
|
172
|
+
// emitted by the CLIENT environment build, which consults THIS
|
|
173
|
+
// env's onwarn -- Vite 8's environment builds do NOT propagate
|
|
174
|
+
// the top-level build.rollupOptions.onwarn into the client env.
|
|
175
|
+
// Wire it here so the suppression runs where the conflicts
|
|
176
|
+
// originate (the top-level handler is invoked 0x for these; the
|
|
177
|
+
// client-env handler is invoked for all of them).
|
|
178
|
+
onwarn,
|
|
142
179
|
output: {
|
|
143
180
|
manualChunks: getManualChunks,
|
|
144
181
|
},
|
|
@@ -149,7 +186,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
149
186
|
optimizeDeps: {
|
|
150
187
|
include: [nested("rsc-html-stream/client")],
|
|
151
188
|
exclude: excludeDeps,
|
|
152
|
-
|
|
189
|
+
rolldownOptions: sharedRolldownOptions,
|
|
153
190
|
},
|
|
154
191
|
},
|
|
155
192
|
ssr: {
|
|
@@ -157,10 +194,6 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
157
194
|
build: {
|
|
158
195
|
outDir: "./dist/rsc/ssr",
|
|
159
196
|
},
|
|
160
|
-
resolve: {
|
|
161
|
-
// Ensure single React instance in SSR child environment
|
|
162
|
-
dedupe: ["react", "react-dom"],
|
|
163
|
-
},
|
|
164
197
|
// Pre-bundle SSR entry and React for proper module linking with childEnvironments
|
|
165
198
|
// All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
166
199
|
optimizeDeps: {
|
|
@@ -178,7 +211,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
178
211
|
),
|
|
179
212
|
],
|
|
180
213
|
exclude: excludeDeps,
|
|
181
|
-
|
|
214
|
+
rolldownOptions: sharedRolldownOptions,
|
|
182
215
|
},
|
|
183
216
|
},
|
|
184
217
|
rsc: {
|
|
@@ -195,7 +228,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
195
228
|
),
|
|
196
229
|
],
|
|
197
230
|
exclude: excludeDeps,
|
|
198
|
-
|
|
231
|
+
rolldownOptions: sharedRolldownOptions,
|
|
199
232
|
},
|
|
200
233
|
},
|
|
201
234
|
},
|
|
@@ -227,6 +260,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
227
260
|
rsc({
|
|
228
261
|
entries: finalEntries,
|
|
229
262
|
serverHandler: false,
|
|
263
|
+
clientChunks,
|
|
230
264
|
}) as PluginOption,
|
|
231
265
|
);
|
|
232
266
|
|
|
@@ -256,7 +290,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
256
290
|
" - " + (f.startsWith(root) ? f.slice(root.length + 1) : f),
|
|
257
291
|
)
|
|
258
292
|
.join("\n");
|
|
259
|
-
throw new Error(`[
|
|
293
|
+
throw new Error(`[rango] Multiple routers found:\n${list}`);
|
|
260
294
|
}
|
|
261
295
|
// 0 found: routerRef.path stays undefined, warn at startup via discovery plugin
|
|
262
296
|
},
|
|
@@ -282,18 +316,34 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
282
316
|
return {
|
|
283
317
|
optimizeDeps: {
|
|
284
318
|
exclude: excludeDeps,
|
|
285
|
-
|
|
319
|
+
rolldownOptions: sharedRolldownOptions,
|
|
286
320
|
},
|
|
287
321
|
build: {
|
|
288
322
|
rollupOptions: { onwarn },
|
|
289
323
|
},
|
|
290
324
|
resolve: {
|
|
291
325
|
alias: rangoAliases,
|
|
326
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
327
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
328
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
329
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
330
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
331
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
332
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
333
|
+
dedupe: ["react", "react-dom"],
|
|
292
334
|
},
|
|
293
335
|
environments: {
|
|
294
336
|
client: {
|
|
295
337
|
build: {
|
|
296
338
|
rollupOptions: {
|
|
339
|
+
// FILE_NAME_CONFLICT (and any other client-build warning) is
|
|
340
|
+
// emitted by the CLIENT environment build, which consults THIS
|
|
341
|
+
// env's onwarn -- Vite 8's environment builds do NOT propagate
|
|
342
|
+
// the top-level build.rollupOptions.onwarn into the client env.
|
|
343
|
+
// Wire it here so the suppression runs where the conflicts
|
|
344
|
+
// originate (the top-level handler is invoked 0x for these; the
|
|
345
|
+
// client-env handler is invoked for all of them).
|
|
346
|
+
onwarn,
|
|
297
347
|
output: {
|
|
298
348
|
manualChunks: getManualChunks,
|
|
299
349
|
},
|
|
@@ -308,7 +358,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
308
358
|
nested("rsc-html-stream/client"),
|
|
309
359
|
],
|
|
310
360
|
exclude: excludeDeps,
|
|
311
|
-
|
|
361
|
+
rolldownOptions: sharedRolldownOptions,
|
|
312
362
|
entries: [VIRTUAL_IDS.browser],
|
|
313
363
|
},
|
|
314
364
|
},
|
|
@@ -327,7 +377,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
327
377
|
),
|
|
328
378
|
],
|
|
329
379
|
exclude: excludeDeps,
|
|
330
|
-
|
|
380
|
+
rolldownOptions: sharedRolldownOptions,
|
|
331
381
|
},
|
|
332
382
|
},
|
|
333
383
|
rsc: {
|
|
@@ -341,7 +391,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
341
391
|
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
342
392
|
),
|
|
343
393
|
],
|
|
344
|
-
|
|
394
|
+
rolldownOptions: sharedRolldownOptions,
|
|
345
395
|
},
|
|
346
396
|
},
|
|
347
397
|
},
|
|
@@ -366,7 +416,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
366
416
|
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
367
417
|
hasWarnedDuplicate = true;
|
|
368
418
|
console.warn(
|
|
369
|
-
"[
|
|
419
|
+
"[rango] Duplicate @vitejs/plugin-rsc detected. " +
|
|
370
420
|
"Remove rsc() from your vite config — rango() includes it automatically.",
|
|
371
421
|
);
|
|
372
422
|
}
|
|
@@ -382,6 +432,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
382
432
|
plugins.push(
|
|
383
433
|
rsc({
|
|
384
434
|
entries: finalEntries,
|
|
435
|
+
clientChunks,
|
|
385
436
|
}) as PluginOption,
|
|
386
437
|
);
|
|
387
438
|
|
|
@@ -484,6 +535,7 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
484
535
|
enableBuildPrerender: prerenderEnabled,
|
|
485
536
|
buildEnv: options?.buildEnv,
|
|
486
537
|
preset,
|
|
538
|
+
clientChunkCtx,
|
|
487
539
|
}),
|
|
488
540
|
);
|
|
489
541
|
|