@rangojs/router 0.0.0-experimental.31 → 0.0.0-experimental.3232cd17
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 +198 -44
- package/dist/bin/rango.js +287 -105
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3248 -1117
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +73 -21
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +107 -1
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +245 -21
- package/skills/caching/SKILL.md +302 -6
- package/skills/composability/SKILL.md +27 -2
- package/skills/css/SKILL.md +76 -0
- package/skills/document-cache/SKILL.md +78 -55
- package/skills/handler-use/SKILL.md +364 -0
- package/skills/hooks/SKILL.md +270 -30
- package/skills/host-router/SKILL.md +82 -22
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +49 -5
- package/skills/layout/SKILL.md +35 -9
- package/skills/links/SKILL.md +249 -17
- package/skills/loader/SKILL.md +294 -30
- package/skills/middleware/SKILL.md +52 -13
- package/skills/migrate-nextjs/SKILL.md +584 -0
- package/skills/migrate-react-router/SKILL.md +769 -0
- package/skills/mime-routes/SKILL.md +27 -0
- package/skills/observability/SKILL.md +137 -0
- package/skills/parallel/SKILL.md +203 -7
- package/skills/prerender/SKILL.md +123 -100
- package/skills/rango/SKILL.md +250 -22
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +122 -47
- package/skills/route/SKILL.md +97 -5
- package/skills/router-setup/SKILL.md +90 -5
- package/skills/server-actions/SKILL.md +775 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +27 -3
- package/skills/testing/SKILL.md +129 -0
- package/skills/testing/bindings.md +89 -0
- package/skills/testing/cache-prerender.md +124 -0
- package/skills/testing/client-components.md +122 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +92 -0
- package/skills/testing/handles.md +129 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +121 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +84 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +120 -0
- package/skills/typesafety/SKILL.md +329 -27
- package/skills/use-cache/SKILL.md +36 -5
- package/skills/view-transitions/SKILL.md +294 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +67 -40
- package/src/browser/action-coordinator.ts +53 -36
- package/src/browser/action-fence.ts +47 -0
- package/src/browser/app-shell.ts +39 -0
- package/src/browser/app-version.ts +14 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +86 -147
- package/src/browser/history-state.ts +21 -0
- package/src/browser/index.ts +3 -3
- package/src/browser/invalidate-client-cache.ts +52 -0
- package/src/browser/link-interceptor.ts +4 -0
- package/src/browser/navigation-bridge.ts +148 -19
- package/src/browser/navigation-client.ts +187 -67
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +76 -67
- package/src/browser/navigation-transaction.ts +18 -66
- package/src/browser/partial-update.ts +123 -94
- package/src/browser/prefetch/cache.ts +214 -36
- package/src/browser/prefetch/fetch.ts +260 -38
- package/src/browser/prefetch/policy.ts +6 -0
- package/src/browser/prefetch/queue.ts +126 -20
- package/src/browser/prefetch/resource-ready.ts +77 -0
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +93 -11
- package/src/browser/react/NavigationProvider.tsx +115 -34
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/context.ts +7 -2
- package/src/browser/react/filter-segment-order.ts +49 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +166 -8
- package/src/browser/react/location-state.ts +39 -14
- package/src/browser/react/use-action.ts +6 -15
- package/src/browser/react/use-handle.ts +23 -69
- package/src/browser/react/use-link-status.ts +0 -4
- package/src/browser/react/use-navigation.ts +22 -5
- package/src/browser/react/use-params.ts +20 -10
- package/src/browser/react/use-reverse.ts +106 -0
- package/src/browser/react/use-router.ts +46 -11
- package/src/browser/react/use-search-params.ts +0 -5
- package/src/browser/react/use-segments.ts +11 -21
- package/src/browser/response-adapter.ts +52 -1
- package/src/browser/rsc-router.tsx +215 -76
- package/src/browser/scroll-restoration.ts +46 -39
- package/src/browser/segment-reconciler.ts +36 -9
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +176 -50
- package/src/browser/types.ts +95 -11
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +65 -40
- package/src/build/generate-route-types.ts +5 -0
- package/src/build/index.ts +8 -2
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +137 -32
- package/src/build/route-types/codegen.ts +4 -4
- package/src/build/route-types/include-resolution.ts +9 -2
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +7 -4
- package/src/build/route-types/router-processing.ts +278 -96
- package/src/build/route-types/scan-filter.ts +9 -2
- package/src/build/route-types/source-scan.ts +118 -0
- package/src/build/runtime-discovery.ts +9 -20
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-policy.ts +68 -28
- package/src/cache/cache-runtime.ts +149 -43
- package/src/cache/cache-scope.ts +148 -81
- package/src/cache/cache-tag.ts +98 -0
- package/src/cache/cf/cf-cache-store.ts +2550 -93
- package/src/cache/cf/index.ts +11 -17
- package/src/cache/document-cache.ts +78 -27
- package/src/cache/handle-snapshot.ts +63 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +136 -37
- package/src/cache/profile-registry.ts +6 -30
- package/src/cache/read-through-swr.ts +41 -11
- package/src/cache/segment-codec.ts +0 -16
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/taint.ts +55 -0
- package/src/cache/types.ts +33 -100
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +799 -0
- package/src/client.rsc.tsx +6 -21
- package/src/client.tsx +108 -290
- package/src/component-utils.ts +19 -0
- package/src/context-var.ts +84 -2
- package/src/debug.ts +2 -2
- package/src/decode-loader-results.ts +36 -0
- package/src/defer.ts +196 -0
- package/src/deps/ssr.ts +0 -1
- package/src/errors.ts +30 -4
- package/src/handle.ts +70 -22
- package/src/handles/MetaTags.tsx +0 -14
- package/src/handles/breadcrumbs.ts +16 -5
- package/src/handles/meta.ts +0 -39
- package/src/host/cookie-handler.ts +0 -36
- package/src/host/errors.ts +0 -24
- package/src/host/index.ts +8 -2
- package/src/host/pattern-matcher.ts +7 -50
- package/src/host/router.ts +107 -99
- package/src/host/testing.ts +40 -27
- package/src/host/types.ts +37 -4
- package/src/host/utils.ts +1 -1
- package/src/href-client.ts +137 -22
- package/src/index.rsc.ts +52 -26
- package/src/index.ts +100 -38
- package/src/internal-debug.ts +2 -4
- package/src/loader-store.ts +500 -0
- package/src/loader.rsc.ts +20 -13
- package/src/loader.ts +12 -11
- package/src/missing-id-error.ts +68 -0
- package/src/network-error-thrower.tsx +1 -6
- package/src/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +10 -11
- package/src/prerender/store.ts +37 -41
- package/src/prerender.ts +198 -82
- package/src/redirect-origin.ts +100 -0
- package/src/response-utils.ts +37 -0
- package/src/reverse.ts +65 -15
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +7 -72
- package/src/route-definition/dsl-helpers.ts +437 -274
- package/src/route-definition/helper-factories.ts +29 -139
- package/src/route-definition/helpers-types.ts +113 -37
- package/src/route-definition/index.ts +3 -0
- package/src/route-definition/redirect.ts +52 -10
- package/src/route-definition/resolve-handler-use.ts +161 -0
- package/src/route-definition/use-item-types.ts +32 -0
- package/src/route-map-builder.ts +7 -17
- package/src/route-types.ts +37 -41
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +108 -9
- package/src/router/error-handling.ts +13 -17
- package/src/router/find-match.ts +45 -22
- package/src/router/handler-context.ts +83 -41
- package/src/router/intercept-resolution.ts +25 -23
- package/src/router/lazy-includes.ts +19 -53
- package/src/router/loader-resolution.ts +213 -30
- package/src/router/logging.ts +5 -8
- package/src/router/manifest.ts +49 -45
- package/src/router/match-api.ts +121 -205
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +58 -58
- package/src/router/match-middleware/background-revalidation.ts +27 -6
- package/src/router/match-middleware/cache-lookup.ts +205 -249
- package/src/router/match-middleware/cache-store.ts +45 -32
- package/src/router/match-middleware/intercept-resolution.ts +8 -28
- package/src/router/match-middleware/segment-resolution.ts +52 -18
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +104 -40
- package/src/router/metrics.ts +5 -34
- package/src/router/middleware-types.ts +13 -142
- package/src/router/middleware.ts +173 -143
- package/src/router/navigation-snapshot.ts +131 -0
- package/src/router/params-util.ts +23 -0
- package/src/router/pattern-matching.ts +109 -63
- package/src/router/prerender-match.ts +192 -54
- package/src/router/preview-match.ts +32 -102
- package/src/router/request-classification.ts +276 -0
- package/src/router/revalidation.ts +63 -55
- package/src/router/route-snapshot.ts +244 -0
- package/src/router/router-context.ts +6 -28
- package/src/router/router-interfaces.ts +100 -35
- package/src/router/router-options.ts +91 -11
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +242 -75
- package/src/router/segment-resolution/helpers.ts +64 -25
- package/src/router/segment-resolution/loader-cache.ts +41 -37
- package/src/router/segment-resolution/revalidation.ts +456 -372
- package/src/router/segment-resolution/static-store.ts +19 -5
- package/src/router/segment-resolution/streamed-handler-telemetry.ts +52 -0
- package/src/router/segment-resolution/view-transition-default.ts +36 -0
- package/src/router/segment-resolution.ts +4 -1
- package/src/router/segment-wrappers.ts +2 -3
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +56 -0
- package/src/router/telemetry-otel.ts +0 -20
- package/src/router/telemetry.ts +96 -19
- package/src/router/timeout.ts +0 -20
- package/src/router/trie-matching.ts +91 -46
- package/src/router/types.ts +10 -63
- package/src/router/url-params.ts +44 -0
- package/src/router.ts +134 -43
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +492 -383
- package/src/rsc/helpers.ts +162 -46
- package/src/rsc/index.ts +1 -1
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +23 -3
- package/src/rsc/manifest-init.ts +33 -42
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +30 -3
- package/src/rsc/redirect-guard.ts +99 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +90 -63
- package/src/rsc/rsc-rendering.ts +56 -54
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +74 -67
- package/src/rsc/ssr-setup.ts +18 -2
- package/src/rsc/types.ts +25 -6
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +4 -20
- package/src/segment-content-promise.ts +67 -0
- package/src/segment-loader-promise.ts +134 -0
- package/src/segment-system.tsx +272 -129
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +309 -61
- package/src/server/cookie-store.ts +80 -5
- package/src/server/handle-store.ts +26 -24
- package/src/server/loader-registry.ts +10 -28
- package/src/server/request-context.ts +348 -128
- package/src/ssr/index.tsx +23 -15
- package/src/static-handler.ts +27 -18
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +40 -0
- package/src/testing/dispatch.ts +618 -0
- package/src/testing/dom.entry.ts +22 -0
- package/src/testing/e2e/fixture.ts +188 -0
- package/src/testing/e2e/index.ts +128 -0
- package/src/testing/e2e/matchers.ts +35 -0
- package/src/testing/e2e/page-helpers.ts +272 -0
- package/src/testing/e2e/parity.ts +387 -0
- package/src/testing/e2e/server.ts +195 -0
- package/src/testing/flight-matchers.ts +97 -0
- package/src/testing/flight-normalize.ts +11 -0
- package/src/testing/flight-runtime.d.ts +57 -0
- package/src/testing/flight-tree.ts +682 -0
- package/src/testing/flight.entry.ts +52 -0
- package/src/testing/flight.ts +232 -0
- package/src/testing/generated-routes.ts +183 -0
- package/src/testing/index.ts +99 -0
- package/src/testing/internal/context.ts +348 -0
- package/src/testing/internal/flight-client-globals.ts +30 -0
- package/src/testing/internal/seed-vars.ts +54 -0
- package/src/testing/render-handler.ts +330 -0
- package/src/testing/render-route.tsx +566 -0
- package/src/testing/run-loader.ts +378 -0
- package/src/testing/run-middleware.ts +205 -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 +305 -0
- package/src/theme/ThemeProvider.tsx +0 -52
- package/src/theme/ThemeScript.tsx +0 -6
- package/src/theme/constants.ts +0 -12
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +0 -14
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +17 -8
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +233 -81
- package/src/types/index.ts +1 -10
- package/src/types/loader-types.ts +44 -15
- package/src/types/request-scope.ts +107 -0
- package/src/types/route-config.ts +6 -50
- package/src/types/route-entry.ts +19 -7
- package/src/types/segments.ts +37 -14
- package/src/urls/include-helper.ts +33 -70
- package/src/urls/index.ts +1 -11
- package/src/urls/path-helper-types.ts +58 -11
- package/src/urls/path-helper.ts +57 -111
- package/src/urls/pattern-types.ts +48 -19
- package/src/urls/response-types.ts +25 -22
- package/src/urls/type-extraction.ts +58 -139
- package/src/urls/urls-function.ts +1 -18
- package/src/use-loader.tsx +346 -89
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +36 -38
- package/src/vite/discovery/discover-routers.ts +130 -85
- package/src/vite/discovery/discovery-errors.ts +194 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +192 -99
- package/src/vite/discovery/route-types-writer.ts +40 -84
- package/src/vite/discovery/self-gen-tracking.ts +27 -1
- package/src/vite/discovery/state.ts +51 -6
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +8 -0
- package/src/vite/plugin-types.ts +187 -69
- package/src/vite/plugins/cjs-to-esm.ts +8 -18
- package/src/vite/plugins/client-ref-dedup.ts +16 -11
- package/src/vite/plugins/client-ref-hashing.ts +28 -15
- 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 +194 -0
- package/src/vite/plugins/expose-action-id.ts +49 -98
- package/src/vite/plugins/expose-id-utils.ts +11 -50
- package/src/vite/plugins/expose-ids/export-analysis.ts +76 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +10 -48
- package/src/vite/plugins/expose-ids/loader-transform.ts +3 -20
- package/src/vite/plugins/expose-ids/router-transform.ts +20 -16
- package/src/vite/plugins/expose-internal-ids.ts +554 -317
- package/src/vite/plugins/performance-tracks.ts +89 -0
- package/src/vite/plugins/refresh-cmd.ts +89 -27
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +258 -0
- package/src/vite/plugins/version-injector.ts +21 -25
- package/src/vite/plugins/version-plugin.ts +41 -20
- package/src/vite/plugins/virtual-entries.ts +2 -17
- package/src/vite/rango.ts +257 -289
- package/src/vite/router-discovery.ts +930 -140
- package/src/vite/utils/ast-handler-extract.ts +15 -31
- package/src/vite/utils/banner.ts +4 -4
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/forward-user-plugins.ts +171 -0
- package/src/vite/utils/manifest-utils.ts +4 -59
- package/src/vite/utils/package-resolution.ts +20 -52
- package/src/vite/utils/prerender-utils.ts +27 -29
- package/src/vite/utils/shared-utils.ts +92 -42
- package/src/browser/action-response-classifier.ts +0 -99
- package/src/browser/react/use-client-cache.ts +0 -58
- package/src/browser/shallow.ts +0 -40
- package/src/handles/index.ts +0 -7
- package/src/router/middleware-cookies.ts +0 -55
package/src/vite/rango.ts
CHANGED
|
@@ -12,27 +12,31 @@ 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
|
+
sharedRolldownOptions,
|
|
23
22
|
createVirtualEntriesPlugin,
|
|
24
23
|
onwarn,
|
|
25
24
|
getManualChunks,
|
|
26
25
|
} from "./utils/shared-utils.js";
|
|
27
|
-
import
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
} from "./plugin-types.js";
|
|
26
|
+
import {
|
|
27
|
+
resolveClientChunks,
|
|
28
|
+
type ClientChunkContext,
|
|
29
|
+
} from "./utils/client-chunks.js";
|
|
30
|
+
import type { RangoOptions, RangoVercelOptions } from "./plugin-types.js";
|
|
31
|
+
import { createVercelOutputPlugin } from "./plugins/vercel-output.js";
|
|
32
32
|
import { printBanner, rangoVersion } from "./utils/banner.js";
|
|
33
33
|
import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
34
34
|
import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
|
|
35
35
|
import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
36
|
+
import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
37
|
+
import { createRangoDebugger, NS } from "./debug.js";
|
|
38
|
+
|
|
39
|
+
const debugConfig = createRangoDebugger(NS.config);
|
|
36
40
|
|
|
37
41
|
/**
|
|
38
42
|
* Vite plugin for @rangojs/router.
|
|
@@ -43,7 +47,7 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
|
43
47
|
* @example Node.js (default)
|
|
44
48
|
* ```ts
|
|
45
49
|
* export default defineConfig({
|
|
46
|
-
* plugins: [react(), rango(
|
|
50
|
+
* plugins: [react(), rango()],
|
|
47
51
|
* });
|
|
48
52
|
* ```
|
|
49
53
|
*
|
|
@@ -59,18 +63,46 @@ import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
|
59
63
|
* ```
|
|
60
64
|
*/
|
|
61
65
|
export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
66
|
+
const rangoStart = performance.now();
|
|
62
67
|
const resolvedOptions: RangoOptions = options ?? { preset: "node" };
|
|
63
68
|
const preset = resolvedOptions.preset ?? "node";
|
|
64
69
|
const showBanner = resolvedOptions.banner ?? true;
|
|
70
|
+
const clientChunksOption = resolvedOptions.clientChunks ?? true;
|
|
71
|
+
const useBuiltInClientChunks = clientChunksOption === true;
|
|
72
|
+
const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
|
|
73
|
+
? { fallbackRefs: new Set<string>() }
|
|
74
|
+
: undefined;
|
|
75
|
+
const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
|
|
76
|
+
debugConfig?.("rango(%s) setup start", preset);
|
|
65
77
|
|
|
66
78
|
const plugins: PluginOption[] = [];
|
|
67
79
|
|
|
68
|
-
// Get package resolution info (workspace vs npm install)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
//
|
|
73
|
-
|
|
80
|
+
// Get package resolution info (workspace vs npm install).
|
|
81
|
+
// Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
|
|
82
|
+
// itself injects into optimizeDeps.include) to absolute paths resolved from
|
|
83
|
+
// this package — so strict-pnpm consumers don't hit "Failed to resolve
|
|
84
|
+
// dependency" warnings when those deps aren't hoisted to their app root.
|
|
85
|
+
const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
|
|
86
|
+
const excludeDeps = [
|
|
87
|
+
...getExcludeDeps(),
|
|
88
|
+
// plugin-rsc itself injects these into the client env's
|
|
89
|
+
// optimizeDeps.include, which overrides exclude for the dep's own
|
|
90
|
+
// pre-bundle entry. What exclude still controls is how *other*
|
|
91
|
+
// pre-bundled deps treat imports of these specs (external vs inlined)
|
|
92
|
+
// via esbuildCjsExternalPlugin. The cjs-to-esm transform in
|
|
93
|
+
// plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
|
|
94
|
+
// where client.browser's bare include fails to resolve and Vite ends up
|
|
95
|
+
// serving the raw CJS file at dev-serve time.
|
|
96
|
+
"@vitejs/plugin-rsc/browser",
|
|
97
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
|
|
101
|
+
// B from A's location. We anchor transitive deps (rsc-html-stream,
|
|
102
|
+
// @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
|
|
103
|
+
// these aren't visible at the app root — can still pre-bundle them.
|
|
104
|
+
const pkg = getPublishedPackageName();
|
|
105
|
+
const nested = (spec: string) => `${pkg} > ${spec}`;
|
|
74
106
|
|
|
75
107
|
// Mutable ref for router path (node preset only).
|
|
76
108
|
// Set immediately when user-specified, or populated by the auto-discover
|
|
@@ -82,14 +114,8 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
82
114
|
const prerenderEnabled = true;
|
|
83
115
|
|
|
84
116
|
if (preset === "cloudflare") {
|
|
85
|
-
// Cloudflare preset: configure entries for cloudflare worker setup
|
|
86
|
-
// Router is not needed here - worker.rsc.tsx imports it directly
|
|
87
|
-
|
|
88
|
-
// Dynamically import @vitejs/plugin-rsc
|
|
89
117
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
90
118
|
|
|
91
|
-
// Only client and ssr entries - rsc entry is handled by cloudflare plugin
|
|
92
|
-
// Always use virtual modules for cloudflare preset
|
|
93
119
|
const finalEntries: { client: string; ssr: string } = {
|
|
94
120
|
client: VIRTUAL_IDS.browser,
|
|
95
121
|
ssr: VIRTUAL_IDS.ssr,
|
|
@@ -100,16 +126,21 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
100
126
|
enforce: "pre",
|
|
101
127
|
|
|
102
128
|
config() {
|
|
103
|
-
// Configure environments for cloudflare deployment
|
|
104
129
|
return {
|
|
105
|
-
// Exclude rsc-router modules from optimization to prevent module duplication
|
|
106
|
-
// This ensures the same Context instance is used by both browser entry and RSC proxy modules
|
|
107
130
|
optimizeDeps: {
|
|
108
131
|
exclude: excludeDeps,
|
|
109
|
-
|
|
132
|
+
rolldownOptions: sharedRolldownOptions,
|
|
110
133
|
},
|
|
111
134
|
resolve: {
|
|
112
135
|
alias: rangoAliases,
|
|
136
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
137
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
138
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
139
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
140
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
141
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
142
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
143
|
+
dedupe: ["react", "react-dom"],
|
|
113
144
|
},
|
|
114
145
|
build: {
|
|
115
146
|
rollupOptions: { onwarn },
|
|
@@ -118,30 +149,22 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
118
149
|
client: {
|
|
119
150
|
build: {
|
|
120
151
|
rollupOptions: {
|
|
152
|
+
onwarn,
|
|
121
153
|
output: {
|
|
122
154
|
manualChunks: getManualChunks,
|
|
123
155
|
},
|
|
124
156
|
},
|
|
125
157
|
},
|
|
126
|
-
// Pre-bundle rsc-html-stream to prevent discovery during first request
|
|
127
|
-
// Exclude rsc-router modules to ensure same Context instance
|
|
128
158
|
optimizeDeps: {
|
|
129
|
-
include: ["rsc-html-stream/client"],
|
|
159
|
+
include: [nested("rsc-html-stream/client")],
|
|
130
160
|
exclude: excludeDeps,
|
|
131
|
-
|
|
161
|
+
rolldownOptions: sharedRolldownOptions,
|
|
132
162
|
},
|
|
133
163
|
},
|
|
134
164
|
ssr: {
|
|
135
|
-
// Build SSR inside RSC directory so wrangler can deploy self-contained dist/rsc
|
|
136
165
|
build: {
|
|
137
166
|
outDir: "./dist/rsc/ssr",
|
|
138
167
|
},
|
|
139
|
-
resolve: {
|
|
140
|
-
// Ensure single React instance in SSR child environment
|
|
141
|
-
dedupe: ["react", "react-dom"],
|
|
142
|
-
},
|
|
143
|
-
// Pre-bundle SSR entry and React for proper module linking with childEnvironments
|
|
144
|
-
// All deps must be listed to avoid late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
145
168
|
optimizeDeps: {
|
|
146
169
|
entries: [finalEntries.ssr],
|
|
147
170
|
include: [
|
|
@@ -151,26 +174,27 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
151
174
|
"react-dom/static.edge",
|
|
152
175
|
"react/jsx-runtime",
|
|
153
176
|
"react/jsx-dev-runtime",
|
|
154
|
-
"rsc-html-stream/server",
|
|
155
|
-
|
|
177
|
+
nested("rsc-html-stream/server"),
|
|
178
|
+
nested(
|
|
179
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
180
|
+
),
|
|
156
181
|
],
|
|
157
182
|
exclude: excludeDeps,
|
|
158
|
-
|
|
183
|
+
rolldownOptions: sharedRolldownOptions,
|
|
159
184
|
},
|
|
160
185
|
},
|
|
161
186
|
rsc: {
|
|
162
|
-
// RSC environment needs exclude list and esbuild options
|
|
163
|
-
// Exclude rsc-router modules to prevent createContext in RSC environment
|
|
164
187
|
optimizeDeps: {
|
|
165
|
-
// Pre-bundle all RSC deps to prevent late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
166
188
|
include: [
|
|
167
189
|
"react",
|
|
168
190
|
"react/jsx-runtime",
|
|
169
191
|
"react/jsx-dev-runtime",
|
|
170
|
-
|
|
192
|
+
nested(
|
|
193
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
194
|
+
),
|
|
171
195
|
],
|
|
172
196
|
exclude: excludeDeps,
|
|
173
|
-
|
|
197
|
+
rolldownOptions: sharedRolldownOptions,
|
|
174
198
|
},
|
|
175
199
|
},
|
|
176
200
|
},
|
|
@@ -191,232 +215,195 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
191
215
|
});
|
|
192
216
|
|
|
193
217
|
plugins.push(createVirtualEntriesPlugin(finalEntries));
|
|
194
|
-
|
|
195
|
-
// Add RSC plugin with cloudflare-specific options
|
|
196
|
-
// Note: loadModuleDevProxy should NOT be used with childEnvironments
|
|
197
|
-
// since SSR runs in workerd alongside RSC
|
|
218
|
+
plugins.push(performanceTracksPlugin());
|
|
198
219
|
plugins.push(
|
|
199
220
|
rsc({
|
|
200
221
|
entries: finalEntries,
|
|
201
222
|
serverHandler: false,
|
|
223
|
+
clientChunks,
|
|
202
224
|
}) as PluginOption,
|
|
203
225
|
);
|
|
204
|
-
|
|
205
|
-
// Deduplicate client references from third-party packages in dev mode.
|
|
206
|
-
// Prevents module duplication when server components import "use client"
|
|
207
|
-
// packages that are also imported directly by client components.
|
|
208
226
|
plugins.push(clientRefDedup());
|
|
209
227
|
} else {
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
} else if (candidates.length > 1) {
|
|
235
|
-
const list = candidates
|
|
236
|
-
.map(
|
|
237
|
-
(f) =>
|
|
238
|
-
" - " + (f.startsWith(root) ? f.slice(root.length + 1) : f),
|
|
239
|
-
)
|
|
240
|
-
.join("\n");
|
|
241
|
-
throw new Error(
|
|
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
|
-
};
|
|
228
|
+
plugins.push({
|
|
229
|
+
name: "@rangojs/router:auto-discover",
|
|
230
|
+
config(userConfig) {
|
|
231
|
+
if (routerRef.path) return;
|
|
232
|
+
const root = userConfig.root
|
|
233
|
+
? resolve(process.cwd(), userConfig.root)
|
|
234
|
+
: process.cwd();
|
|
235
|
+
const candidates = findRouterFiles(root);
|
|
236
|
+
if (candidates.length === 1) {
|
|
237
|
+
const abs = candidates[0];
|
|
238
|
+
routerRef.path = (
|
|
239
|
+
abs.startsWith(root) ? "./" + abs.slice(root.length + 1) : abs
|
|
240
|
+
).replaceAll("\\", "/");
|
|
241
|
+
} else if (candidates.length > 1) {
|
|
242
|
+
const list = candidates
|
|
243
|
+
.map(
|
|
244
|
+
(f) =>
|
|
245
|
+
" - " + (f.startsWith(root) ? f.slice(root.length + 1) : f),
|
|
246
|
+
)
|
|
247
|
+
.join("\n");
|
|
248
|
+
throw new Error(`[rango] Multiple routers found:\n${list}`);
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
});
|
|
265
252
|
|
|
266
|
-
|
|
267
|
-
|
|
253
|
+
const finalEntries = {
|
|
254
|
+
client: VIRTUAL_IDS.browser,
|
|
255
|
+
ssr: VIRTUAL_IDS.ssr,
|
|
256
|
+
rsc: VIRTUAL_IDS.rsc,
|
|
257
|
+
};
|
|
268
258
|
|
|
269
|
-
|
|
270
|
-
let hasWarnedDuplicate = false;
|
|
259
|
+
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
271
260
|
|
|
272
|
-
|
|
273
|
-
name: "@rangojs/router:rsc-integration",
|
|
274
|
-
enforce: "pre",
|
|
261
|
+
let hasWarnedDuplicate = false;
|
|
275
262
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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;
|
|
263
|
+
plugins.push({
|
|
264
|
+
name: "@rangojs/router:rsc-integration",
|
|
265
|
+
enforce: "pre",
|
|
285
266
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
267
|
+
config(_userConfig, configEnv) {
|
|
268
|
+
// Fold NODE_ENV for the vercel preset's build. The cloudflare plugin
|
|
269
|
+
// does this automatically and node apps do it themselves; vercel has no
|
|
270
|
+
// platform plugin, so without this React's CJS dev branch survives and
|
|
271
|
+
// doubles the SSR/RSC bundle (Bundle Hygiene rule #2). Only the exact
|
|
272
|
+
// `process.env.NODE_ENV` token is replaced.
|
|
273
|
+
const vercelDefine =
|
|
274
|
+
preset === "vercel" && configEnv.command === "build"
|
|
275
|
+
? { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
276
|
+
: undefined;
|
|
277
|
+
// The vercel preset's deployed function has no node_modules, so the
|
|
278
|
+
// server bundles must be fully self-contained. Bundle every dependency
|
|
279
|
+
// into the rsc + ssr builds instead of externalizing them (the node
|
|
280
|
+
// default, which only works because `vite preview` runs where
|
|
281
|
+
// node_modules exists). node: builtins stay external automatically.
|
|
282
|
+
const vercelServerEnv =
|
|
283
|
+
preset === "vercel"
|
|
284
|
+
? { resolve: { noExternal: true as const } }
|
|
285
|
+
: undefined;
|
|
286
|
+
return {
|
|
287
|
+
...(vercelDefine ? { define: vercelDefine } : {}),
|
|
288
|
+
optimizeDeps: {
|
|
289
|
+
exclude: excludeDeps,
|
|
290
|
+
rolldownOptions: sharedRolldownOptions,
|
|
291
|
+
},
|
|
292
|
+
build: {
|
|
293
|
+
rollupOptions: { onwarn },
|
|
294
|
+
},
|
|
295
|
+
resolve: {
|
|
296
|
+
alias: rangoAliases,
|
|
297
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
298
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
299
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
300
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
301
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
302
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
303
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
304
|
+
dedupe: ["react", "react-dom"],
|
|
305
|
+
},
|
|
306
|
+
environments: {
|
|
307
|
+
client: {
|
|
308
|
+
build: {
|
|
309
|
+
rollupOptions: {
|
|
310
|
+
onwarn,
|
|
311
|
+
output: {
|
|
312
|
+
manualChunks: getManualChunks,
|
|
306
313
|
},
|
|
307
314
|
},
|
|
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
315
|
},
|
|
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
|
-
}),
|
|
316
|
+
optimizeDeps: {
|
|
317
|
+
include: [
|
|
318
|
+
"react",
|
|
319
|
+
"react-dom",
|
|
320
|
+
"react/jsx-runtime",
|
|
321
|
+
"react/jsx-dev-runtime",
|
|
322
|
+
nested("rsc-html-stream/client"),
|
|
323
|
+
],
|
|
324
|
+
exclude: excludeDeps,
|
|
325
|
+
rolldownOptions: sharedRolldownOptions,
|
|
326
|
+
entries: [VIRTUAL_IDS.browser],
|
|
327
|
+
},
|
|
361
328
|
},
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
329
|
+
ssr: {
|
|
330
|
+
...(vercelServerEnv ?? {}),
|
|
331
|
+
optimizeDeps: {
|
|
332
|
+
entries: [VIRTUAL_IDS.ssr],
|
|
333
|
+
include: [
|
|
334
|
+
"react",
|
|
335
|
+
"react-dom",
|
|
336
|
+
"react-dom/server.edge",
|
|
337
|
+
"react-dom/static.edge",
|
|
338
|
+
"react/jsx-runtime",
|
|
339
|
+
"react/jsx-dev-runtime",
|
|
340
|
+
nested(
|
|
341
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
342
|
+
),
|
|
343
|
+
],
|
|
344
|
+
exclude: excludeDeps,
|
|
345
|
+
rolldownOptions: sharedRolldownOptions,
|
|
346
|
+
},
|
|
347
|
+
},
|
|
348
|
+
rsc: {
|
|
349
|
+
...(vercelServerEnv ?? {}),
|
|
350
|
+
optimizeDeps: {
|
|
351
|
+
entries: [VIRTUAL_IDS.rsc],
|
|
352
|
+
include: [
|
|
353
|
+
"react",
|
|
354
|
+
"react/jsx-runtime",
|
|
355
|
+
"react/jsx-dev-runtime",
|
|
356
|
+
nested(
|
|
357
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
358
|
+
),
|
|
359
|
+
],
|
|
360
|
+
rolldownOptions: sharedRolldownOptions,
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
},
|
|
380
366
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
367
|
+
configResolved(config) {
|
|
368
|
+
if (showBanner) {
|
|
369
|
+
const mode =
|
|
370
|
+
config.command === "serve"
|
|
371
|
+
? process.argv.includes("preview")
|
|
372
|
+
? "preview"
|
|
373
|
+
: "dev"
|
|
374
|
+
: "build";
|
|
375
|
+
printBanner(
|
|
376
|
+
mode,
|
|
377
|
+
preset === "vercel" ? "vercel" : "node",
|
|
378
|
+
rangoVersion,
|
|
379
|
+
);
|
|
380
|
+
}
|
|
390
381
|
|
|
391
|
-
|
|
392
|
-
|
|
382
|
+
const rscMinimalCount = config.plugins.filter(
|
|
383
|
+
(p) => p.name === "rsc:minimal",
|
|
384
|
+
).length;
|
|
393
385
|
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
386
|
+
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
387
|
+
hasWarnedDuplicate = true;
|
|
388
|
+
console.warn(
|
|
389
|
+
"[rango] Duplicate @vitejs/plugin-rsc detected. " +
|
|
390
|
+
"Remove rsc() from your vite config — rango() includes it automatically.",
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
});
|
|
402
395
|
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
396
|
+
plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
|
|
397
|
+
plugins.push(performanceTracksPlugin());
|
|
398
|
+
plugins.push(
|
|
399
|
+
rsc({
|
|
400
|
+
entries: finalEntries,
|
|
401
|
+
clientChunks,
|
|
402
|
+
}) as PluginOption,
|
|
403
|
+
);
|
|
406
404
|
plugins.push(clientRefDedup());
|
|
407
405
|
}
|
|
408
406
|
|
|
409
|
-
// Fix HMR for "use client" components.
|
|
410
|
-
//
|
|
411
|
-
// @vitejs/plugin-rsc's hotUpdate returns undefined for "use client" files
|
|
412
|
-
// in the RSC environment. Vite then tries to propagate through the RSC
|
|
413
|
-
// module graph, but the proxy module has no import.meta.hot.accept()
|
|
414
|
-
// boundary, causing a full page reload. The client env would handle it
|
|
415
|
-
// fine via React Refresh, but the RSC env's full-reload arrives first.
|
|
416
|
-
//
|
|
417
|
-
// Fix: in the RSC env, return [] for "use client" files to signal
|
|
418
|
-
// "handled, nothing to propagate". The client env is left alone so
|
|
419
|
-
// React Refresh processes the update normally.
|
|
420
407
|
plugins.push({
|
|
421
408
|
name: "@rangojs/router:client-component-hmr",
|
|
422
409
|
hotUpdate(ctx) {
|
|
@@ -440,71 +427,52 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
440
427
|
trimmed.startsWith('"use client"') ||
|
|
441
428
|
trimmed.startsWith("'use client'")
|
|
442
429
|
) {
|
|
443
|
-
// Consume the update in RSC/SSR envs. The proxy module was already
|
|
444
|
-
// re-transformed by the RSC plugin's hotUpdate. Without this, Vite
|
|
445
|
-
// tries to propagate through the RSC/SSR module graph where the proxy
|
|
446
|
-
// has no import.meta.hot.accept() boundary, triggering a full reload.
|
|
447
|
-
// The actual component update is handled by React Refresh in the
|
|
448
|
-
// client environment.
|
|
449
430
|
return [];
|
|
450
431
|
}
|
|
451
|
-
} catch {
|
|
452
|
-
// File deleted/moved during HMR, let default handling proceed
|
|
453
|
-
}
|
|
432
|
+
} catch {}
|
|
454
433
|
},
|
|
455
434
|
});
|
|
456
435
|
|
|
457
436
|
plugins.push(exposeActionId());
|
|
458
|
-
|
|
459
|
-
// "use cache" directive transform (enforce: "post"):
|
|
460
|
-
// Wraps exports with registerCachedFunction() for function-level caching.
|
|
461
437
|
plugins.push(useCacheTransform());
|
|
462
|
-
|
|
463
|
-
// Consolidated plugin for create* ID injection (enforce: "post"):
|
|
464
|
-
// loaders, handles, location state, and prerender handlers.
|
|
465
438
|
plugins.push(exposeInternalIds());
|
|
466
|
-
|
|
467
|
-
// Router ID injection runs at normal priority (no enforce) to avoid
|
|
468
|
-
// changing Vite's dep optimization timing.
|
|
469
439
|
plugins.push(exposeRouterId());
|
|
470
|
-
|
|
471
|
-
// Add version virtual module plugin for cache invalidation
|
|
472
440
|
plugins.push(createVersionPlugin());
|
|
473
441
|
|
|
474
|
-
// Entry path for discovery: user-specified value (if any) or undefined.
|
|
475
|
-
// Auto-discovered path is passed separately via routerRef.
|
|
476
|
-
// Cloudflare preset: deferred to configResolved (read from resolved Vite env config).
|
|
477
442
|
const discoveryEntryPath =
|
|
478
443
|
preset !== "cloudflare" ? routerRef.path : undefined;
|
|
479
|
-
// Ref for deferred auto-discovery (node preset only, undefined for cloudflare)
|
|
480
444
|
const discoveryRouterRef = preset !== "cloudflare" ? routerRef : undefined;
|
|
481
445
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
// lazily in configResolved). For node preset without a custom entry, the router file
|
|
485
|
-
// must NOT be transformed — injecting routes-manifest there creates a circular dependency.
|
|
486
|
-
const injectorEntryPath =
|
|
487
|
-
rscEntryPath ?? (preset === "cloudflare" ? undefined : null);
|
|
488
|
-
if (injectorEntryPath !== null) {
|
|
489
|
-
plugins.push(createVersionInjectorPlugin(injectorEntryPath));
|
|
446
|
+
if (preset === "cloudflare") {
|
|
447
|
+
plugins.push(createVersionInjectorPlugin(undefined));
|
|
490
448
|
}
|
|
491
449
|
|
|
492
|
-
// Transform CJS vendor files to ESM for browser compatibility
|
|
493
|
-
// optimizeDeps.include doesn't work because the file is loaded after initial optimization
|
|
494
450
|
plugins.push(createCjsToEsmPlugin());
|
|
495
|
-
|
|
496
|
-
// Router discovery plugin for build-time manifest generation.
|
|
497
|
-
// For cloudflare, the entry is resolved lazily in configResolved from the RSC environment.
|
|
498
|
-
// For node, discoveryRouterRef provides the auto-discovered path when not user-specified.
|
|
499
451
|
plugins.push(
|
|
500
452
|
createRouterDiscoveryPlugin(discoveryEntryPath, {
|
|
501
453
|
routerPathRef: discoveryRouterRef,
|
|
502
454
|
enableBuildPrerender: prerenderEnabled,
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
455
|
+
buildEnv: options?.buildEnv,
|
|
456
|
+
preset,
|
|
457
|
+
discovery: options?.discovery,
|
|
458
|
+
clientChunkCtx,
|
|
506
459
|
}),
|
|
507
460
|
);
|
|
508
461
|
|
|
462
|
+
// Vercel preset: assemble .vercel/output from dist/ after the build. Pushed
|
|
463
|
+
// last so its (ssr-gated) closeBundle runs after the discovery plugin's
|
|
464
|
+
// rsc-env postprocess and after every environment has been written.
|
|
465
|
+
if (preset === "vercel") {
|
|
466
|
+
plugins.push(
|
|
467
|
+
createVercelOutputPlugin(resolvedOptions as RangoVercelOptions),
|
|
468
|
+
);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
debugConfig?.(
|
|
472
|
+
"rango(%s) setup done: %d plugin(s) (%sms)",
|
|
473
|
+
preset,
|
|
474
|
+
plugins.length,
|
|
475
|
+
(performance.now() - rangoStart).toFixed(1),
|
|
476
|
+
);
|
|
509
477
|
return plugins;
|
|
510
478
|
}
|