@rangojs/router 0.0.0-experimental.79 → 0.0.0-experimental.7c7e4327
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 +8 -4
- package/README.md +301 -797
- package/dist/bin/rango.js +603 -145
- package/dist/testing/vitest.js +82 -0
- package/dist/vite/index.js +3750 -1160
- package/dist/vite/plugins/cloudflare-protocol-loader-hook.mjs +76 -0
- package/package.json +96 -24
- package/skills/api-client/SKILL.md +211 -0
- package/skills/breadcrumbs/SKILL.md +85 -6
- package/skills/bundle-analysis/SKILL.md +159 -0
- package/skills/cache-guide/SKILL.md +228 -33
- package/skills/caching/SKILL.md +336 -19
- package/skills/catalog.json +271 -0
- package/skills/comparison/SKILL.md +50 -0
- package/skills/comparison/agents/openai.yaml +4 -0
- package/skills/comparison/references/framework-comparison.md +837 -0
- package/skills/composability/SKILL.md +110 -4
- package/skills/css/SKILL.md +76 -0
- package/skills/debug-manifest/SKILL.md +5 -3
- package/skills/defer-hydration/SKILL.md +235 -0
- package/skills/document-cache/SKILL.md +87 -56
- package/skills/fonts/SKILL.md +1 -1
- package/skills/handler-use/SKILL.md +12 -10
- package/skills/hooks/SKILL.md +73 -691
- package/skills/hooks/data.md +273 -0
- package/skills/hooks/handle-and-actions.md +103 -0
- package/skills/hooks/navigation.md +110 -0
- package/skills/hooks/outlets.md +41 -0
- package/skills/hooks/state.md +228 -0
- package/skills/hooks/urls.md +135 -0
- package/skills/host-router/SKILL.md +129 -27
- package/skills/i18n/SKILL.md +276 -0
- package/skills/intercept/SKILL.md +75 -19
- package/skills/layout/SKILL.md +40 -19
- package/skills/links/SKILL.md +247 -17
- package/skills/loader/SKILL.md +248 -10
- package/skills/middleware/SKILL.md +25 -13
- package/skills/migrate-nextjs/SKILL.md +205 -20
- package/skills/migrate-react-router/SKILL.md +59 -670
- package/skills/migrate-react-router/cloudflare-workers.md +129 -0
- package/skills/migrate-react-router/component-migration.md +196 -0
- package/skills/migrate-react-router/data-and-actions.md +225 -0
- package/skills/migrate-react-router/route-mapping.md +271 -0
- package/skills/mime-routes/SKILL.md +29 -2
- package/skills/observability/SKILL.md +202 -0
- package/skills/parallel/SKILL.md +40 -10
- package/skills/ppr/SKILL.md +616 -0
- package/skills/prerender/SKILL.md +72 -60
- package/skills/rango/SKILL.md +318 -26
- package/skills/react-compiler/SKILL.md +168 -0
- package/skills/response-routes/SKILL.md +138 -49
- package/skills/route/SKILL.md +117 -9
- package/skills/router-setup/SKILL.md +44 -9
- package/skills/scripts/SKILL.md +179 -0
- package/skills/server-actions/SKILL.md +776 -0
- package/skills/shell-manifest/SKILL.md +185 -0
- package/skills/streams-and-websockets/SKILL.md +283 -0
- package/skills/tailwind/SKILL.md +28 -4
- package/skills/testing/SKILL.md +130 -0
- package/skills/testing/bindings.md +103 -0
- package/skills/testing/cache-prerender.md +127 -0
- package/skills/testing/client-components.md +124 -0
- package/skills/testing/e2e-parity.md +125 -0
- package/skills/testing/flight.md +91 -0
- package/skills/testing/handles.md +131 -0
- package/skills/testing/loader.md +128 -0
- package/skills/testing/middleware.md +99 -0
- package/skills/testing/render-handler.md +122 -0
- package/skills/testing/response-routes.md +95 -0
- package/skills/testing/reverse-and-types.md +85 -0
- package/skills/testing/server-actions.md +107 -0
- package/skills/testing/server-tree.md +128 -0
- package/skills/testing/setup.md +123 -0
- package/skills/theme/SKILL.md +1 -1
- package/skills/typesafety/SKILL.md +45 -626
- package/skills/typesafety/env-and-bindings.md +254 -0
- package/skills/typesafety/generated-files-and-cli.md +335 -0
- package/skills/typesafety/params-and-search.md +153 -0
- package/skills/typesafety/route-types.md +209 -0
- package/skills/use-cache/SKILL.md +74 -15
- package/skills/vercel/SKILL.md +128 -0
- package/skills/view-transitions/SKILL.md +337 -0
- package/src/__augment-tests__/augment.ts +81 -0
- package/src/__augment-tests__/augmented.check.ts +116 -0
- package/src/__internal.ts +0 -65
- 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/connection-warmup.ts +134 -0
- package/src/browser/cookie-name.ts +140 -0
- package/src/browser/event-controller.ts +252 -158
- 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/logging.ts +28 -0
- package/src/browser/merge-segment-loaders.ts +6 -4
- package/src/browser/navigation-bridge.ts +94 -25
- package/src/browser/navigation-client.ts +144 -79
- package/src/browser/navigation-store-handle.ts +38 -0
- package/src/browser/navigation-store.ts +161 -73
- package/src/browser/navigation-transaction.ts +9 -59
- package/src/browser/network-error-handler.ts +34 -7
- package/src/browser/partial-update.ts +183 -144
- package/src/browser/prefetch/cache.ts +242 -77
- package/src/browser/prefetch/fetch.ts +325 -69
- package/src/browser/prefetch/queue.ts +61 -12
- package/src/browser/rango-state.ts +158 -76
- package/src/browser/react/Link.tsx +58 -20
- package/src/browser/react/NavigationProvider.tsx +202 -120
- package/src/browser/react/ScrollRestoration.tsx +10 -6
- package/src/browser/react/filter-segment-order.ts +66 -7
- package/src/browser/react/index.ts +0 -48
- package/src/browser/react/location-state-shared.ts +178 -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 +17 -14
- package/src/browser/react/use-href.tsx +8 -1
- package/src/browser/react/use-link-status.ts +33 -8
- package/src/browser/react/use-navigation.ts +32 -7
- 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 +25 -3
- 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 +99 -8
- package/src/browser/rsc-router.tsx +145 -28
- package/src/browser/scroll-restoration.ts +37 -22
- package/src/browser/segment-reconciler.ts +31 -21
- package/src/browser/segment-structure-assert.ts +2 -2
- package/src/browser/server-action-bridge.ts +236 -65
- package/src/browser/types.ts +102 -9
- package/src/browser/validate-redirect-origin.ts +43 -16
- package/src/build/collect-fallback-refs.ts +107 -0
- package/src/build/generate-manifest.ts +203 -154
- package/src/build/generate-route-types.ts +3 -1
- package/src/build/index.ts +11 -3
- package/src/build/prefix-tree-utils.ts +123 -0
- package/src/build/route-trie.ts +152 -21
- package/src/build/route-types/ast-route-extraction.ts +15 -8
- package/src/build/route-types/codegen.ts +16 -5
- package/src/build/route-types/include-resolution.ts +456 -62
- package/src/build/route-types/param-extraction.ts +6 -3
- package/src/build/route-types/per-module-writer.ts +22 -6
- package/src/build/route-types/router-processing.ts +128 -51
- package/src/build/route-types/scan-filter.ts +1 -1
- package/src/build/route-types/source-scan.ts +216 -0
- package/src/build/runtime-discovery.ts +13 -21
- package/src/cache/cache-error.ts +104 -0
- package/src/cache/cache-key-utils.ts +58 -13
- package/src/cache/cache-policy.ts +108 -34
- package/src/cache/cache-runtime.ts +421 -58
- package/src/cache/cache-scope.ts +187 -96
- package/src/cache/cache-tag.ts +149 -0
- package/src/cache/cf/cf-base64.ts +33 -0
- package/src/cache/cf/cf-cache-constants.ts +127 -0
- package/src/cache/cf/cf-cache-store.ts +2202 -372
- package/src/cache/cf/cf-cache-types.ts +349 -0
- package/src/cache/cf/cf-kv-utils.ts +46 -0
- package/src/cache/cf/cf-tag-marker-memo.ts +105 -0
- package/src/cache/cf/index.ts +6 -16
- package/src/cache/document-cache.ts +126 -41
- package/src/cache/handle-snapshot.ts +70 -0
- package/src/cache/index.ts +23 -20
- package/src/cache/memory-segment-store.ts +243 -37
- package/src/cache/profile-registry.ts +46 -31
- package/src/cache/read-through-swr.ts +56 -12
- package/src/cache/segment-codec.ts +13 -21
- package/src/cache/shell-snapshot.ts +417 -0
- package/src/cache/tag-invalidation.ts +230 -0
- package/src/cache/types.ts +180 -99
- package/src/cache/vercel/index.ts +11 -0
- package/src/cache/vercel/vercel-cache-store.ts +1127 -0
- package/src/client.rsc.tsx +41 -21
- package/src/client.tsx +33 -61
- package/src/cloudflare/index.ts +11 -0
- package/src/cloudflare/tracing.ts +108 -0
- package/src/component-utils.ts +19 -0
- package/src/components/DefaultDocument.tsx +8 -2
- package/src/context-var.ts +18 -6
- package/src/decode-loader-results.ts +52 -0
- package/src/defer.ts +185 -0
- package/src/deps/ssr.ts +0 -1
- package/src/encode-kv.ts +49 -0
- package/src/errors.ts +30 -4
- package/src/escape-script.ts +52 -0
- package/src/handle.ts +67 -37
- package/src/handles/MetaTags.tsx +24 -53
- package/src/handles/Scripts.tsx +183 -0
- package/src/handles/breadcrumbs.ts +35 -8
- package/src/handles/deferred-resolution.ts +127 -0
- package/src/handles/is-thenable.ts +18 -0
- package/src/handles/meta.ts +14 -40
- package/src/handles/script.ts +244 -0
- package/src/host/cookie-handler.ts +9 -60
- package/src/host/errors.ts +13 -22
- package/src/host/index.ts +9 -2
- package/src/host/pattern-matcher.ts +23 -52
- 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 +97 -12
- package/src/index.ts +98 -14
- package/src/internal-debug.ts +11 -10
- 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/outlet-context.ts +1 -1
- package/src/outlet-provider.tsx +1 -5
- package/src/prerender/param-hash.ts +16 -16
- package/src/prerender/store.ts +32 -37
- package/src/prerender.ts +78 -10
- package/src/redirect-origin.ts +114 -0
- package/src/regex-escape.ts +8 -0
- package/src/render-error-thrower.tsx +20 -0
- package/src/response-utils.ts +62 -0
- package/src/reverse.ts +65 -39
- package/src/root-error-boundary.tsx +1 -19
- package/src/route-content-wrapper.tsx +19 -77
- package/src/route-definition/dsl-helpers.ts +304 -309
- package/src/route-definition/helper-factories.ts +28 -140
- package/src/route-definition/helpers-types.ts +87 -59
- package/src/route-definition/index.ts +1 -2
- package/src/route-definition/redirect.ts +44 -11
- package/src/route-definition/resolve-handler-use.ts +12 -1
- package/src/route-definition/use-item-types.ts +29 -0
- package/src/route-map-builder.ts +41 -20
- package/src/route-types.ts +19 -46
- package/src/router/basename.ts +14 -0
- package/src/router/content-negotiation.ts +73 -25
- package/src/router/error-handling.ts +45 -18
- package/src/router/find-match.ts +129 -30
- package/src/router/handler-context.ts +27 -42
- package/src/router/instrument.ts +355 -0
- package/src/router/intercept-resolution.ts +39 -20
- package/src/router/lazy-includes.ts +82 -59
- package/src/router/loader-resolution.ts +167 -72
- package/src/router/logging.ts +0 -6
- package/src/router/manifest.ts +74 -40
- package/src/router/match-api.ts +80 -55
- package/src/router/match-context.ts +0 -22
- package/src/router/match-handlers.ts +211 -165
- package/src/router/match-middleware/background-revalidation.ts +40 -24
- package/src/router/match-middleware/cache-lookup.ts +159 -285
- package/src/router/match-middleware/cache-store.ts +64 -52
- package/src/router/match-middleware/intercept-resolution.ts +0 -22
- package/src/router/match-middleware/segment-resolution.ts +0 -22
- package/src/router/match-pipelines.ts +1 -42
- package/src/router/match-result.ts +69 -79
- package/src/router/metrics.ts +0 -34
- package/src/router/middleware-types.ts +7 -134
- package/src/router/middleware.ts +298 -172
- package/src/router/navigation-snapshot.ts +7 -56
- package/src/router/params-util.ts +23 -0
- package/src/router/parse-pattern.ts +115 -0
- package/src/router/pattern-matching.ts +181 -150
- package/src/router/prefetch-cache-ttl.ts +51 -0
- package/src/router/prefetch-limits.ts +37 -0
- package/src/router/prerender-match.ts +112 -67
- package/src/router/preview-match.ts +6 -2
- package/src/router/request-classification.ts +50 -69
- package/src/router/revalidation.ts +123 -73
- package/src/router/route-snapshot.ts +14 -3
- package/src/router/router-context.ts +6 -29
- package/src/router/router-interfaces.ts +115 -36
- package/src/router/router-options.ts +166 -5
- package/src/router/router-registry.ts +2 -5
- package/src/router/segment-resolution/fresh.ts +131 -86
- package/src/router/segment-resolution/helpers.ts +86 -6
- package/src/router/segment-resolution/loader-cache.ts +139 -39
- package/src/router/segment-resolution/loader-mask.ts +67 -0
- package/src/router/segment-resolution/loader-snapshot.ts +251 -0
- package/src/router/segment-resolution/revalidation.ts +272 -320
- 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 +56 -0
- package/src/router/segment-resolution.ts +5 -1
- package/src/router/segment-wrappers.ts +6 -5
- package/src/router/state-cookie-name.ts +33 -0
- package/src/router/substitute-pattern-params.ts +75 -0
- package/src/router/telemetry-otel.ts +160 -200
- package/src/router/telemetry.ts +105 -20
- package/src/router/timeout.ts +0 -20
- package/src/router/tracing.ts +215 -0
- package/src/router/trie-matching.ts +171 -59
- package/src/router/types.ts +9 -63
- package/src/router/url-params.ts +57 -0
- package/src/router.ts +157 -71
- package/src/rsc/full-payload.ts +70 -0
- package/src/rsc/handler-context.ts +3 -2
- package/src/rsc/handler.ts +291 -217
- package/src/rsc/helpers.ts +168 -46
- package/src/rsc/index.ts +2 -5
- package/src/rsc/json-route-result.ts +38 -0
- package/src/rsc/loader-fetch.ts +114 -38
- package/src/rsc/manifest-init.ts +29 -42
- package/src/rsc/nonce.ts +10 -1
- package/src/rsc/origin-guard.ts +39 -25
- package/src/rsc/progressive-enhancement.ts +124 -13
- package/src/rsc/redirect-guard.ts +100 -0
- package/src/rsc/response-cache-serve.ts +238 -0
- package/src/rsc/response-error.ts +79 -12
- package/src/rsc/response-route-handler.ts +99 -189
- package/src/rsc/rsc-rendering.ts +421 -76
- package/src/rsc/runtime-warnings.ts +23 -10
- package/src/rsc/server-action.ts +282 -116
- package/src/rsc/shell-capture.ts +1158 -0
- package/src/rsc/shell-serve.ts +150 -0
- package/src/rsc/ssr-setup.ts +16 -0
- package/src/rsc/transition-gate.ts +89 -0
- package/src/rsc/types.ts +53 -5
- package/src/runtime-env.ts +18 -0
- package/src/search-params.ts +35 -30
- package/src/segment-loader-promise.ts +49 -4
- package/src/segment-system.tsx +350 -149
- package/src/serialize.ts +243 -0
- package/src/server/context.ts +208 -51
- package/src/server/cookie-parse.ts +32 -0
- package/src/server/cookie-store.ts +152 -5
- package/src/server/handle-store.ts +21 -38
- package/src/server/loader-registry.ts +33 -42
- package/src/server/request-context.ts +395 -176
- package/src/ssr/index.tsx +458 -178
- package/src/ssr/ssr-root.tsx +228 -0
- package/src/static-handler.ts +10 -13
- package/src/testing/cache-status.ts +162 -0
- package/src/testing/collect-handle.ts +46 -0
- package/src/testing/dispatch.ts +813 -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 +257 -0
- package/src/testing/generated-routes.ts +199 -0
- package/src/testing/index.ts +105 -0
- package/src/testing/internal/context.ts +371 -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 +357 -0
- package/src/testing/render-route.tsx +584 -0
- package/src/testing/run-loader.ts +385 -0
- package/src/testing/run-middleware.ts +205 -0
- package/src/testing/run-transition-when.ts +164 -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 +56 -84
- package/src/theme/ThemeScript.tsx +7 -9
- package/src/theme/constants.ts +52 -13
- package/src/theme/index.ts +0 -7
- package/src/theme/theme-context.ts +1 -5
- package/src/theme/theme-script.ts +22 -21
- package/src/theme/use-theme.ts +0 -3
- package/src/types/boundaries.ts +0 -35
- package/src/types/cache-types.ts +13 -4
- package/src/types/error-types.ts +30 -90
- package/src/types/global-namespace.ts +54 -41
- package/src/types/handler-context.ts +110 -62
- package/src/types/index.ts +3 -10
- package/src/types/loader-types.ts +11 -9
- package/src/types/request-scope.ts +112 -0
- package/src/types/route-config.ts +20 -52
- package/src/types/route-entry.ts +0 -6
- package/src/types/segments.ts +135 -14
- package/src/urls/include-helper.ts +19 -64
- package/src/urls/include-provider.ts +71 -0
- package/src/urls/index.ts +2 -11
- package/src/urls/path-helper-types.ts +63 -17
- package/src/urls/path-helper.ts +22 -106
- package/src/urls/pattern-types.ts +72 -19
- package/src/urls/response-types.ts +22 -29
- package/src/urls/type-extraction.ts +98 -154
- package/src/urls/urls-function.ts +1 -19
- package/src/use-loader.tsx +292 -107
- package/src/vercel/index.ts +11 -0
- package/src/vercel/tracing.ts +88 -0
- package/src/vite/debug.ts +185 -0
- package/src/vite/discovery/bundle-postprocess.ts +8 -7
- package/src/vite/discovery/dev-prerender-cache.ts +117 -0
- package/src/vite/discovery/discover-routers.ts +127 -86
- package/src/vite/discovery/discovery-errors.ts +255 -0
- package/src/vite/discovery/gate-state.ts +171 -0
- package/src/vite/discovery/prerender-collection.ts +96 -68
- 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 +45 -1
- package/src/vite/discovery/virtual-module-codegen.ts +14 -34
- package/src/vite/index.ts +4 -0
- package/src/vite/inject-client-debug.ts +88 -0
- package/src/vite/plugin-types.ts +210 -10
- package/src/vite/plugins/cjs-to-esm.ts +16 -19
- 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 +48 -95
- package/src/vite/plugins/expose-id-utils.ts +88 -55
- package/src/vite/plugins/expose-ids/export-analysis.ts +101 -34
- package/src/vite/plugins/expose-ids/handler-transform.ts +11 -90
- package/src/vite/plugins/expose-ids/loader-transform.ts +14 -24
- package/src/vite/plugins/expose-ids/router-transform.ts +118 -29
- package/src/vite/plugins/expose-internal-ids.ts +505 -486
- package/src/vite/plugins/performance-tracks.ts +26 -25
- package/src/vite/plugins/refresh-cmd.ts +1 -1
- package/src/vite/plugins/use-cache-transform.ts +73 -83
- package/src/vite/plugins/vercel-output.ts +384 -0
- package/src/vite/plugins/version-injector.ts +40 -29
- package/src/vite/plugins/version-plugin.ts +37 -40
- package/src/vite/plugins/virtual-entries.ts +138 -27
- package/src/vite/rango.ts +236 -138
- package/src/vite/router-discovery.ts +927 -136
- package/src/vite/utils/ast-handler-extract.ts +26 -35
- package/src/vite/utils/banner.ts +1 -1
- package/src/vite/utils/bundle-analysis.ts +10 -15
- package/src/vite/utils/client-chunks.ts +184 -0
- package/src/vite/utils/directive-prologue.ts +40 -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 +71 -43
- package/src/vite/utils/shared-utils.ts +142 -43
- 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/network-error-thrower.tsx +0 -23
- package/src/router/middleware-cookies.ts +0 -55
package/src/vite/rango.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import { readFileSync } from "node:fs";
|
|
1
|
+
import { type PluginOption } from "vite";
|
|
2
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
3
3
|
import { resolve } from "node:path";
|
|
4
4
|
import { exposeActionId } from "./plugins/expose-action-id.js";
|
|
5
5
|
import {
|
|
@@ -12,21 +12,46 @@ 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 {
|
|
18
|
+
import {
|
|
19
|
+
findRouterFiles,
|
|
20
|
+
findHostRouterFiles,
|
|
21
|
+
} from "../build/generate-route-types.js";
|
|
17
22
|
import { createVersionPlugin } from "./plugins/version-plugin.js";
|
|
18
23
|
import {
|
|
19
|
-
|
|
24
|
+
sharedRolldownOptions,
|
|
20
25
|
createVirtualEntriesPlugin,
|
|
26
|
+
normalizeHostRouterEntry,
|
|
21
27
|
onwarn,
|
|
22
28
|
getManualChunks,
|
|
23
29
|
} from "./utils/shared-utils.js";
|
|
24
|
-
import
|
|
30
|
+
import {
|
|
31
|
+
resolveClientChunks,
|
|
32
|
+
type ClientChunkContext,
|
|
33
|
+
} from "./utils/client-chunks.js";
|
|
34
|
+
import type {
|
|
35
|
+
RangoOptions,
|
|
36
|
+
RangoNodeOptions,
|
|
37
|
+
RangoVercelOptions,
|
|
38
|
+
} from "./plugin-types.js";
|
|
39
|
+
import { createVercelOutputPlugin } from "./plugins/vercel-output.js";
|
|
25
40
|
import { printBanner, rangoVersion } from "./utils/banner.js";
|
|
26
41
|
import { createVersionInjectorPlugin } from "./plugins/version-injector.js";
|
|
27
42
|
import { createCjsToEsmPlugin } from "./plugins/cjs-to-esm.js";
|
|
28
43
|
import { createRouterDiscoveryPlugin } from "./router-discovery.js";
|
|
29
44
|
import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
45
|
+
import { createRangoDebugger, NS } from "./debug.js";
|
|
46
|
+
|
|
47
|
+
const debugConfig = createRangoDebugger(NS.config);
|
|
48
|
+
|
|
49
|
+
// The leading-directive 'use client' sniff is shared with version-plugin's
|
|
50
|
+
// getClientModuleSignature so the two cannot drift. Imported for local use by the
|
|
51
|
+
// HMR transform below and re-exported because the E8 sniff test imports it from
|
|
52
|
+
// this module.
|
|
53
|
+
import { hasUseClientDirective } from "./utils/directive-prologue.js";
|
|
54
|
+
export { hasUseClientDirective };
|
|
30
55
|
|
|
31
56
|
/**
|
|
32
57
|
* Vite plugin for @rangojs/router.
|
|
@@ -53,43 +78,69 @@ import { performanceTracksPlugin } from "./plugins/performance-tracks.js";
|
|
|
53
78
|
* ```
|
|
54
79
|
*/
|
|
55
80
|
export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
81
|
+
const rangoStart = performance.now();
|
|
56
82
|
const resolvedOptions: RangoOptions = options ?? { preset: "node" };
|
|
57
83
|
const preset = resolvedOptions.preset ?? "node";
|
|
58
84
|
const showBanner = resolvedOptions.banner ?? true;
|
|
85
|
+
const clientChunksOption = resolvedOptions.clientChunks ?? true;
|
|
86
|
+
const useBuiltInClientChunks = clientChunksOption === true;
|
|
87
|
+
const clientChunkCtx: ClientChunkContext | undefined = useBuiltInClientChunks
|
|
88
|
+
? { fallbackRefs: new Set<string>() }
|
|
89
|
+
: undefined;
|
|
90
|
+
const clientChunks = resolveClientChunks(clientChunksOption, clientChunkCtx);
|
|
91
|
+
debugConfig?.("rango(%s) setup start", preset);
|
|
59
92
|
|
|
60
93
|
const plugins: PluginOption[] = [];
|
|
61
94
|
|
|
62
|
-
// Get package resolution info (workspace vs npm install)
|
|
63
|
-
|
|
95
|
+
// Get package resolution info (workspace vs npm install).
|
|
96
|
+
// Vendor aliases redirect the bare plugin-rsc vendor specs (which plugin-rsc
|
|
97
|
+
// itself injects into optimizeDeps.include) to absolute paths resolved from
|
|
98
|
+
// this package — so strict-pnpm consumers don't hit "Failed to resolve
|
|
99
|
+
// dependency" warnings when those deps aren't hoisted to their app root.
|
|
100
|
+
const rangoAliases = { ...getPackageAliases(), ...getVendorAliases() };
|
|
64
101
|
const excludeDeps = [
|
|
65
102
|
...getExcludeDeps(),
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
// .
|
|
103
|
+
// plugin-rsc itself injects these into the client env's
|
|
104
|
+
// optimizeDeps.include, which overrides exclude for the dep's own
|
|
105
|
+
// pre-bundle entry. What exclude still controls is how *other*
|
|
106
|
+
// pre-bundled deps treat imports of these specs (external vs inlined)
|
|
107
|
+
// via esbuildCjsExternalPlugin. The cjs-to-esm transform in
|
|
108
|
+
// plugins/cjs-to-esm.ts is the fallback for strict-pnpm consumers,
|
|
109
|
+
// where client.browser's bare include fails to resolve and Vite ends up
|
|
110
|
+
// serving the raw CJS file at dev-serve time.
|
|
69
111
|
"@vitejs/plugin-rsc/browser",
|
|
70
|
-
// Keep the browser RSDW client out of Vite's dep optimizer so our
|
|
71
|
-
// cjs-to-esm transform can patch the real file.
|
|
72
112
|
"@vitejs/plugin-rsc/vendor/react-server-dom/client.browser",
|
|
73
113
|
];
|
|
74
114
|
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
115
|
+
// Vite supports a nested `A > B` syntax in optimizeDeps.include that resolves
|
|
116
|
+
// B from A's location. We anchor transitive deps (rsc-html-stream,
|
|
117
|
+
// @vitejs/plugin-rsc/vendor/*) to @rangojs/router so pnpm consumers — where
|
|
118
|
+
// these aren't visible at the app root — can still pre-bundle them.
|
|
119
|
+
const pkg = getPublishedPackageName();
|
|
120
|
+
const nested = (spec: string) => `${pkg} > ${spec}`;
|
|
121
|
+
|
|
122
|
+
// Mutable ref for the served entry path (node/vercel presets only). Populated
|
|
123
|
+
// by the auto-discover config() hook using Vite's resolved root. `kind` selects
|
|
124
|
+
// the RSC entry template: "router" wraps a single createRouter() app in
|
|
125
|
+
// createRSCHandler; "host" wraps a createHostRouter() instance and serves it
|
|
126
|
+
// via hostRouter.match().
|
|
127
|
+
const routerRef: { path: string | undefined; kind: "router" | "host" } = {
|
|
128
|
+
path: undefined,
|
|
129
|
+
kind: "router",
|
|
130
|
+
};
|
|
131
|
+
// Explicit host-router entry (node/vercel `hostRouter` option), root-relative.
|
|
132
|
+
const explicitHostRouter =
|
|
133
|
+
preset !== "cloudflare"
|
|
134
|
+
? (resolvedOptions as RangoNodeOptions | RangoVercelOptions).hostRouter
|
|
135
|
+
: undefined;
|
|
79
136
|
|
|
80
137
|
// Build-time prerendering is enabled for both presets.
|
|
81
138
|
// Collection runs in-process via the RSC dev environment runner during discoverRouters().
|
|
82
139
|
const prerenderEnabled = true;
|
|
83
140
|
|
|
84
141
|
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
142
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
90
143
|
|
|
91
|
-
// Only client and ssr entries - rsc entry is handled by cloudflare plugin
|
|
92
|
-
// Always use virtual modules for cloudflare preset
|
|
93
144
|
const finalEntries: { client: string; ssr: string } = {
|
|
94
145
|
client: VIRTUAL_IDS.browser,
|
|
95
146
|
ssr: VIRTUAL_IDS.ssr,
|
|
@@ -100,16 +151,21 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
100
151
|
enforce: "pre",
|
|
101
152
|
|
|
102
153
|
config() {
|
|
103
|
-
// Configure environments for cloudflare deployment
|
|
104
154
|
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
155
|
optimizeDeps: {
|
|
108
156
|
exclude: excludeDeps,
|
|
109
|
-
|
|
157
|
+
rolldownOptions: sharedRolldownOptions,
|
|
110
158
|
},
|
|
111
159
|
resolve: {
|
|
112
160
|
alias: rangoAliases,
|
|
161
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
162
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
163
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
164
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
165
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
166
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
167
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
168
|
+
dedupe: ["react", "react-dom"],
|
|
113
169
|
},
|
|
114
170
|
build: {
|
|
115
171
|
rollupOptions: { onwarn },
|
|
@@ -118,30 +174,22 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
118
174
|
client: {
|
|
119
175
|
build: {
|
|
120
176
|
rollupOptions: {
|
|
177
|
+
onwarn,
|
|
121
178
|
output: {
|
|
122
179
|
manualChunks: getManualChunks,
|
|
123
180
|
},
|
|
124
181
|
},
|
|
125
182
|
},
|
|
126
|
-
// Pre-bundle rsc-html-stream to prevent discovery during first request
|
|
127
|
-
// Exclude rsc-router modules to ensure same Context instance
|
|
128
183
|
optimizeDeps: {
|
|
129
|
-
include: ["rsc-html-stream/client"],
|
|
184
|
+
include: [nested("rsc-html-stream/client")],
|
|
130
185
|
exclude: excludeDeps,
|
|
131
|
-
|
|
186
|
+
rolldownOptions: sharedRolldownOptions,
|
|
132
187
|
},
|
|
133
188
|
},
|
|
134
189
|
ssr: {
|
|
135
|
-
// Build SSR inside RSC directory so wrangler can deploy self-contained dist/rsc
|
|
136
190
|
build: {
|
|
137
191
|
outDir: "./dist/rsc/ssr",
|
|
138
192
|
},
|
|
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
193
|
optimizeDeps: {
|
|
146
194
|
entries: [finalEntries.ssr],
|
|
147
195
|
include: [
|
|
@@ -151,26 +199,27 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
151
199
|
"react-dom/static.edge",
|
|
152
200
|
"react/jsx-runtime",
|
|
153
201
|
"react/jsx-dev-runtime",
|
|
154
|
-
"rsc-html-stream/server",
|
|
155
|
-
|
|
202
|
+
nested("rsc-html-stream/server"),
|
|
203
|
+
nested(
|
|
204
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
205
|
+
),
|
|
156
206
|
],
|
|
157
207
|
exclude: excludeDeps,
|
|
158
|
-
|
|
208
|
+
rolldownOptions: sharedRolldownOptions,
|
|
159
209
|
},
|
|
160
210
|
},
|
|
161
211
|
rsc: {
|
|
162
|
-
// RSC environment needs exclude list and esbuild options
|
|
163
|
-
// Exclude rsc-router modules to prevent createContext in RSC environment
|
|
164
212
|
optimizeDeps: {
|
|
165
|
-
// Pre-bundle all RSC deps to prevent late discovery triggering ERR_OUTDATED_OPTIMIZED_DEP
|
|
166
213
|
include: [
|
|
167
214
|
"react",
|
|
168
215
|
"react/jsx-runtime",
|
|
169
216
|
"react/jsx-dev-runtime",
|
|
170
|
-
|
|
217
|
+
nested(
|
|
218
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
219
|
+
),
|
|
171
220
|
],
|
|
172
221
|
exclude: excludeDeps,
|
|
173
|
-
|
|
222
|
+
rolldownOptions: sharedRolldownOptions,
|
|
174
223
|
},
|
|
175
224
|
},
|
|
176
225
|
},
|
|
@@ -191,26 +240,16 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
191
240
|
});
|
|
192
241
|
|
|
193
242
|
plugins.push(createVirtualEntriesPlugin(finalEntries));
|
|
194
|
-
|
|
195
|
-
// Dev-only: RSDW client patch for React Performance Tracks
|
|
196
243
|
plugins.push(performanceTracksPlugin());
|
|
197
|
-
|
|
198
|
-
// Add RSC plugin with cloudflare-specific options
|
|
199
|
-
// Note: loadModuleDevProxy should NOT be used with childEnvironments
|
|
200
|
-
// since SSR runs in workerd alongside RSC
|
|
201
244
|
plugins.push(
|
|
202
245
|
rsc({
|
|
203
246
|
entries: finalEntries,
|
|
204
247
|
serverHandler: false,
|
|
248
|
+
clientChunks,
|
|
205
249
|
}) as PluginOption,
|
|
206
250
|
);
|
|
207
|
-
|
|
208
|
-
// Deduplicate client references from third-party packages in dev mode.
|
|
209
|
-
// Prevents module duplication when server components import "use client"
|
|
210
|
-
// packages that are also imported directly by client components.
|
|
211
251
|
plugins.push(clientRefDedup());
|
|
212
252
|
} else {
|
|
213
|
-
// Auto-discover router using Vite's resolved root (not process.cwd())
|
|
214
253
|
plugins.push({
|
|
215
254
|
name: "@rangojs/router:auto-discover",
|
|
216
255
|
config(userConfig) {
|
|
@@ -218,33 +257,75 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
218
257
|
const root = userConfig.root
|
|
219
258
|
? resolve(process.cwd(), userConfig.root)
|
|
220
259
|
: process.cwd();
|
|
260
|
+
const toRootRelative = (abs: string) =>
|
|
261
|
+
(abs.startsWith(root)
|
|
262
|
+
? "./" + abs.slice(root.length + 1)
|
|
263
|
+
: abs
|
|
264
|
+
).replaceAll("\\", "/");
|
|
265
|
+
const bulletList = (files: string[]) =>
|
|
266
|
+
files.map((f) => " - " + toRootRelative(f)).join("\n");
|
|
267
|
+
|
|
268
|
+
// 1. Explicit host entry wins: serve the createHostRouter() instance.
|
|
269
|
+
if (explicitHostRouter) {
|
|
270
|
+
routerRef.path = normalizeHostRouterEntry(
|
|
271
|
+
explicitHostRouter,
|
|
272
|
+
root,
|
|
273
|
+
existsSync,
|
|
274
|
+
);
|
|
275
|
+
routerRef.kind = "host";
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// 2. A createHostRouter() file means this is a multi-app host deploy:
|
|
280
|
+
// serve it via the host entry. Checked BEFORE single-router discovery,
|
|
281
|
+
// because a host app may compose just one createRouter() sub-app plus
|
|
282
|
+
// host middleware / domain rules / inline .map() routes -- and a lone
|
|
283
|
+
// sub-app must not shadow the host entry (it would bypass
|
|
284
|
+
// hostRouter.match()).
|
|
285
|
+
const hostCandidates = findHostRouterFiles(root);
|
|
286
|
+
if (hostCandidates.length === 1) {
|
|
287
|
+
const hostPath = toRootRelative(hostCandidates[0]);
|
|
288
|
+
// Auto-detection preempts single-router discovery, so name the winning
|
|
289
|
+
// file: a stale prototype still containing `createHostRouter(` would
|
|
290
|
+
// otherwise silently become the served entry in place of the app.
|
|
291
|
+
// eslint-disable-next-line no-console
|
|
292
|
+
console.info(
|
|
293
|
+
`[rango] Serving host router entry ${hostPath} (auto-detected). ` +
|
|
294
|
+
`Set the \`hostRouter\` option to override.`,
|
|
295
|
+
);
|
|
296
|
+
routerRef.path = hostPath;
|
|
297
|
+
routerRef.kind = "host";
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
if (hostCandidates.length > 1) {
|
|
301
|
+
throw new Error(
|
|
302
|
+
`[rango] Multiple host routers found:\n${bulletList(hostCandidates)}\n\n` +
|
|
303
|
+
`Set the \`hostRouter\` option to the entry to serve, e.g. rango({ preset: "${preset}", hostRouter: "./src/worker.rsc.tsx" }).`,
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// 3. No host entry: single createRouter() app.
|
|
221
308
|
const candidates = findRouterFiles(root);
|
|
222
309
|
if (candidates.length === 1) {
|
|
223
|
-
|
|
224
|
-
routerRef.
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
(
|
|
231
|
-
|
|
232
|
-
)
|
|
233
|
-
.join("\n");
|
|
234
|
-
throw new Error(`[rsc-router] Multiple routers found:\n${list}`);
|
|
310
|
+
routerRef.path = toRootRelative(candidates[0]);
|
|
311
|
+
routerRef.kind = "router";
|
|
312
|
+
return;
|
|
313
|
+
}
|
|
314
|
+
if (candidates.length > 1) {
|
|
315
|
+
throw new Error(
|
|
316
|
+
`[rango] Multiple routers found:\n${bulletList(candidates)}\n\n` +
|
|
317
|
+
`If this is a multi-app host router, export a createHostRouter() instance and set the \`hostRouter\` option (e.g. rango({ preset: "${preset}", hostRouter: "./src/worker.rsc.tsx" })), or use preset: "cloudflare" where you own the worker entry.`,
|
|
318
|
+
);
|
|
235
319
|
}
|
|
236
|
-
// 0 found: routerRef.path stays undefined, warn at startup via discovery plugin
|
|
237
320
|
},
|
|
238
321
|
});
|
|
239
322
|
|
|
240
|
-
// Always use virtual entries for client, ssr, and rsc
|
|
241
323
|
const finalEntries = {
|
|
242
324
|
client: VIRTUAL_IDS.browser,
|
|
243
325
|
ssr: VIRTUAL_IDS.ssr,
|
|
244
326
|
rsc: VIRTUAL_IDS.rsc,
|
|
245
327
|
};
|
|
246
328
|
|
|
247
|
-
// Dynamically import @vitejs/plugin-rsc
|
|
248
329
|
const { default: rsc } = await import("@vitejs/plugin-rsc");
|
|
249
330
|
|
|
250
331
|
let hasWarnedDuplicate = false;
|
|
@@ -253,22 +334,57 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
253
334
|
name: "@rangojs/router:rsc-integration",
|
|
254
335
|
enforce: "pre",
|
|
255
336
|
|
|
256
|
-
config() {
|
|
337
|
+
config(_userConfig, configEnv) {
|
|
338
|
+
// Fold NODE_ENV for the vercel preset's build. The cloudflare plugin
|
|
339
|
+
// does this automatically and node apps do it themselves; vercel has no
|
|
340
|
+
// platform plugin, so without this React's CJS dev branch survives and
|
|
341
|
+
// doubles the SSR/RSC bundle (Bundle Hygiene rule #2). Only the exact
|
|
342
|
+
// `process.env.NODE_ENV` token is replaced.
|
|
343
|
+
const vercelDefine =
|
|
344
|
+
preset === "vercel" && configEnv.command === "build"
|
|
345
|
+
? { "process.env.NODE_ENV": JSON.stringify("production") }
|
|
346
|
+
: undefined;
|
|
347
|
+
// The vercel preset's deployed function has no node_modules, so the
|
|
348
|
+
// server bundles must be fully self-contained. Bundle every dependency
|
|
349
|
+
// into the rsc + ssr builds instead of externalizing them (the node
|
|
350
|
+
// default, which only works because `vite preview` runs where
|
|
351
|
+
// node_modules exists). node: builtins stay external automatically.
|
|
352
|
+
//
|
|
353
|
+
// BUILD ONLY. In `vite dev` this must NOT apply: noExternal forces every
|
|
354
|
+
// server dependency through the RSC/SSR dev module runners, which cannot
|
|
355
|
+
// load many CJS packages (pg, mysql2, most SDKs, @vercel/functions) and
|
|
356
|
+
// crashes the dev server -- while the same app runs fine under
|
|
357
|
+
// preset: "node" and in the production build. Gating on `build` restores
|
|
358
|
+
// node-preset dev semantics (deps externalized to Node's require).
|
|
359
|
+
const vercelServerEnv =
|
|
360
|
+
preset === "vercel" && configEnv.command === "build"
|
|
361
|
+
? { resolve: { noExternal: true as const } }
|
|
362
|
+
: undefined;
|
|
257
363
|
return {
|
|
364
|
+
...(vercelDefine ? { define: vercelDefine } : {}),
|
|
258
365
|
optimizeDeps: {
|
|
259
366
|
exclude: excludeDeps,
|
|
260
|
-
|
|
367
|
+
rolldownOptions: sharedRolldownOptions,
|
|
261
368
|
},
|
|
262
369
|
build: {
|
|
263
370
|
rollupOptions: { onwarn },
|
|
264
371
|
},
|
|
265
372
|
resolve: {
|
|
266
373
|
alias: rangoAliases,
|
|
374
|
+
// Force a single React/React-DOM copy across all three RSC
|
|
375
|
+
// environments. RSC requires exactly one react/react-dom instance
|
|
376
|
+
// per environment runtime; consumer install topologies (pnpm
|
|
377
|
+
// strict layout, experimental React pins, third-party "use client"
|
|
378
|
+
// packages) can otherwise resolve duplicate copies, causing
|
|
379
|
+
// "Invalid hook call" / lost context. Child environments inherit
|
|
380
|
+
// this root dedupe, and Vite merges it with any consumer dedupe.
|
|
381
|
+
dedupe: ["react", "react-dom"],
|
|
267
382
|
},
|
|
268
383
|
environments: {
|
|
269
384
|
client: {
|
|
270
385
|
build: {
|
|
271
386
|
rollupOptions: {
|
|
387
|
+
onwarn,
|
|
272
388
|
output: {
|
|
273
389
|
manualChunks: getManualChunks,
|
|
274
390
|
},
|
|
@@ -280,14 +396,15 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
280
396
|
"react-dom",
|
|
281
397
|
"react/jsx-runtime",
|
|
282
398
|
"react/jsx-dev-runtime",
|
|
283
|
-
"rsc-html-stream/client",
|
|
399
|
+
nested("rsc-html-stream/client"),
|
|
284
400
|
],
|
|
285
401
|
exclude: excludeDeps,
|
|
286
|
-
|
|
402
|
+
rolldownOptions: sharedRolldownOptions,
|
|
287
403
|
entries: [VIRTUAL_IDS.browser],
|
|
288
404
|
},
|
|
289
405
|
},
|
|
290
406
|
ssr: {
|
|
407
|
+
...(vercelServerEnv ?? {}),
|
|
291
408
|
optimizeDeps: {
|
|
292
409
|
entries: [VIRTUAL_IDS.ssr],
|
|
293
410
|
include: [
|
|
@@ -297,22 +414,33 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
297
414
|
"react-dom/static.edge",
|
|
298
415
|
"react/jsx-runtime",
|
|
299
416
|
"react/jsx-dev-runtime",
|
|
300
|
-
|
|
417
|
+
nested(
|
|
418
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/client.edge",
|
|
419
|
+
),
|
|
301
420
|
],
|
|
302
421
|
exclude: excludeDeps,
|
|
303
|
-
|
|
422
|
+
rolldownOptions: sharedRolldownOptions,
|
|
304
423
|
},
|
|
305
424
|
},
|
|
306
425
|
rsc: {
|
|
426
|
+
...(vercelServerEnv ?? {}),
|
|
307
427
|
optimizeDeps: {
|
|
308
428
|
entries: [VIRTUAL_IDS.rsc],
|
|
309
429
|
include: [
|
|
310
430
|
"react",
|
|
311
431
|
"react/jsx-runtime",
|
|
312
432
|
"react/jsx-dev-runtime",
|
|
313
|
-
|
|
433
|
+
nested(
|
|
434
|
+
"@vitejs/plugin-rsc/vendor/react-server-dom/server.edge",
|
|
435
|
+
),
|
|
314
436
|
],
|
|
315
|
-
|
|
437
|
+
// Vite 8 does not propagate the top-level optimizeDeps.exclude
|
|
438
|
+
// (set in config()) to non-client envs, so the rsc env must set
|
|
439
|
+
// it explicitly — mirroring the node ssr env and the cloudflare
|
|
440
|
+
// rsc env. Without it a strict-pnpm npm-installed app can try to
|
|
441
|
+
// pre-bundle the router's own subpath entries and fail.
|
|
442
|
+
exclude: excludeDeps,
|
|
443
|
+
rolldownOptions: sharedRolldownOptions,
|
|
316
444
|
},
|
|
317
445
|
},
|
|
318
446
|
},
|
|
@@ -327,7 +455,11 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
327
455
|
? "preview"
|
|
328
456
|
: "dev"
|
|
329
457
|
: "build";
|
|
330
|
-
printBanner(
|
|
458
|
+
printBanner(
|
|
459
|
+
mode,
|
|
460
|
+
preset === "vercel" ? "vercel" : "node",
|
|
461
|
+
rangoVersion,
|
|
462
|
+
);
|
|
331
463
|
}
|
|
332
464
|
|
|
333
465
|
const rscMinimalCount = config.plugins.filter(
|
|
@@ -337,42 +469,24 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
337
469
|
if (rscMinimalCount > 1 && !hasWarnedDuplicate) {
|
|
338
470
|
hasWarnedDuplicate = true;
|
|
339
471
|
console.warn(
|
|
340
|
-
"[
|
|
472
|
+
"[rango] Duplicate @vitejs/plugin-rsc detected. " +
|
|
341
473
|
"Remove rsc() from your vite config — rango() includes it automatically.",
|
|
342
474
|
);
|
|
343
475
|
}
|
|
344
476
|
},
|
|
345
477
|
});
|
|
346
478
|
|
|
347
|
-
// Add virtual entries plugin (RSC entry generated lazily from routerRef)
|
|
348
479
|
plugins.push(createVirtualEntriesPlugin(finalEntries, routerRef));
|
|
349
|
-
|
|
350
|
-
// Dev-only: RSDW client patch for React Performance Tracks
|
|
351
480
|
plugins.push(performanceTracksPlugin());
|
|
352
|
-
|
|
353
481
|
plugins.push(
|
|
354
482
|
rsc({
|
|
355
483
|
entries: finalEntries,
|
|
484
|
+
clientChunks,
|
|
356
485
|
}) as PluginOption,
|
|
357
486
|
);
|
|
358
|
-
|
|
359
|
-
// Deduplicate client references from third-party packages in dev mode.
|
|
360
|
-
// Prevents module duplication when server components import "use client"
|
|
361
|
-
// packages that are also imported directly by client components.
|
|
362
487
|
plugins.push(clientRefDedup());
|
|
363
488
|
}
|
|
364
489
|
|
|
365
|
-
// Fix HMR for "use client" components.
|
|
366
|
-
//
|
|
367
|
-
// @vitejs/plugin-rsc's hotUpdate returns undefined for "use client" files
|
|
368
|
-
// in the RSC environment. Vite then tries to propagate through the RSC
|
|
369
|
-
// module graph, but the proxy module has no import.meta.hot.accept()
|
|
370
|
-
// boundary, causing a full page reload. The client env would handle it
|
|
371
|
-
// fine via React Refresh, but the RSC env's full-reload arrives first.
|
|
372
|
-
//
|
|
373
|
-
// Fix: in the RSC env, return [] for "use client" files to signal
|
|
374
|
-
// "handled, nothing to propagate". The client env is left alone so
|
|
375
|
-
// React Refresh processes the update normally.
|
|
376
490
|
plugins.push({
|
|
377
491
|
name: "@rangojs/router:client-component-hmr",
|
|
378
492
|
hotUpdate(ctx) {
|
|
@@ -391,72 +505,56 @@ export async function rango(options?: RangoOptions): Promise<PluginOption[]> {
|
|
|
391
505
|
|
|
392
506
|
try {
|
|
393
507
|
const source = readFileSync(file, "utf-8");
|
|
394
|
-
|
|
395
|
-
if (
|
|
396
|
-
trimmed.startsWith('"use client"') ||
|
|
397
|
-
trimmed.startsWith("'use client'")
|
|
398
|
-
) {
|
|
399
|
-
// Consume the update in RSC/SSR envs. The proxy module was already
|
|
400
|
-
// re-transformed by the RSC plugin's hotUpdate. Without this, Vite
|
|
401
|
-
// tries to propagate through the RSC/SSR module graph where the proxy
|
|
402
|
-
// has no import.meta.hot.accept() boundary, triggering a full reload.
|
|
403
|
-
// The actual component update is handled by React Refresh in the
|
|
404
|
-
// client environment.
|
|
508
|
+
if (hasUseClientDirective(source)) {
|
|
405
509
|
return [];
|
|
406
510
|
}
|
|
407
|
-
} catch {
|
|
408
|
-
// File deleted/moved during HMR, let default handling proceed
|
|
409
|
-
}
|
|
511
|
+
} catch {}
|
|
410
512
|
},
|
|
411
513
|
});
|
|
412
514
|
|
|
413
515
|
plugins.push(exposeActionId());
|
|
414
|
-
|
|
415
|
-
// "use cache" directive transform (enforce: "post"):
|
|
416
|
-
// Wraps exports with registerCachedFunction() for function-level caching.
|
|
417
516
|
plugins.push(useCacheTransform());
|
|
418
|
-
|
|
419
|
-
// Consolidated plugin for create* ID injection (enforce: "post"):
|
|
420
|
-
// loaders, handles, location state, and prerender handlers.
|
|
421
517
|
plugins.push(exposeInternalIds());
|
|
422
|
-
|
|
423
|
-
// Router ID injection runs at normal priority (no enforce) to avoid
|
|
424
|
-
// changing Vite's dep optimization timing.
|
|
425
518
|
plugins.push(exposeRouterId());
|
|
426
|
-
|
|
427
|
-
// Add version virtual module plugin for cache invalidation
|
|
428
519
|
plugins.push(createVersionPlugin());
|
|
429
520
|
|
|
430
|
-
// Entry path for discovery: user-specified value (if any) or undefined.
|
|
431
|
-
// Auto-discovered path is passed separately via routerRef.
|
|
432
|
-
// Cloudflare preset: deferred to configResolved (read from resolved Vite env config).
|
|
433
521
|
const discoveryEntryPath =
|
|
434
522
|
preset !== "cloudflare" ? routerRef.path : undefined;
|
|
435
|
-
// Ref for deferred auto-discovery (node preset only, undefined for cloudflare)
|
|
436
523
|
const discoveryRouterRef = preset !== "cloudflare" ? routerRef : undefined;
|
|
437
524
|
|
|
438
|
-
// Version injector: auto-injects VERSION and routes-manifest into the RSC entry.
|
|
439
|
-
// For cloudflare preset, the entry is resolved lazily in configResolved.
|
|
440
|
-
// For node preset, the virtual entry already includes these imports.
|
|
441
525
|
if (preset === "cloudflare") {
|
|
442
526
|
plugins.push(createVersionInjectorPlugin(undefined));
|
|
443
527
|
}
|
|
444
528
|
|
|
445
|
-
// Transform CJS vendor files to ESM for browser compatibility
|
|
446
|
-
// optimizeDeps.include doesn't work because the file is loaded after initial optimization
|
|
447
529
|
plugins.push(createCjsToEsmPlugin());
|
|
448
|
-
|
|
449
|
-
// Router discovery plugin for build-time manifest generation.
|
|
450
|
-
// For cloudflare, the entry is resolved lazily in configResolved from the RSC environment.
|
|
451
|
-
// For node, discoveryRouterRef provides the auto-discovered path when not user-specified.
|
|
452
530
|
plugins.push(
|
|
453
531
|
createRouterDiscoveryPlugin(discoveryEntryPath, {
|
|
454
532
|
routerPathRef: discoveryRouterRef,
|
|
455
533
|
enableBuildPrerender: prerenderEnabled,
|
|
456
534
|
buildEnv: options?.buildEnv,
|
|
457
535
|
preset,
|
|
536
|
+
prerenderOnError: options?.prerender?.onError,
|
|
537
|
+
discovery: options?.discovery,
|
|
538
|
+
clientChunkCtx,
|
|
458
539
|
}),
|
|
459
540
|
);
|
|
460
541
|
|
|
542
|
+
// Vercel preset: assemble .vercel/output from dist/ after the build. Pushed
|
|
543
|
+
// last so its buildApp (order "post") hook runs after the discovery plugin's
|
|
544
|
+
// rsc-env postprocess. buildApp fires once after the whole multi-environment
|
|
545
|
+
// build, so dist/ is complete (closeBundle is unusable here -- it fires per
|
|
546
|
+
// environment, twice for ssr; see the plugin's own note).
|
|
547
|
+
if (preset === "vercel") {
|
|
548
|
+
plugins.push(
|
|
549
|
+
createVercelOutputPlugin(resolvedOptions as RangoVercelOptions),
|
|
550
|
+
);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
debugConfig?.(
|
|
554
|
+
"rango(%s) setup done: %d plugin(s) (%sms)",
|
|
555
|
+
preset,
|
|
556
|
+
plugins.length,
|
|
557
|
+
(performance.now() - rangoStart).toFixed(1),
|
|
558
|
+
);
|
|
461
559
|
return plugins;
|
|
462
560
|
}
|