rsbuild-plugin-react-router 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +72 -240
  2. package/dist/{451.js → 511.js} +461 -331
  3. package/dist/build-output-transforms.d.ts +32 -7
  4. package/dist/classic-mode.d.ts +56 -0
  5. package/dist/config-imports.d.ts +8 -2
  6. package/dist/constants.d.ts +3 -0
  7. package/dist/dev-background-resources.d.ts +3 -3
  8. package/dist/dev-generation.d.ts +2 -3
  9. package/dist/dev-hmr.d.ts +8 -2
  10. package/dist/dev-runtime-controller.d.ts +6 -1
  11. package/dist/dev-source-maps.d.ts +4 -0
  12. package/dist/effect-runtime.d.ts +17 -5
  13. package/dist/entry-paths.d.ts +16 -0
  14. package/dist/environment-output.d.ts +6 -0
  15. package/dist/export-utils.d.ts +2 -1
  16. package/dist/federation.d.ts +2 -0
  17. package/dist/index.cjs +3675 -2107
  18. package/dist/index.d.ts +3 -1
  19. package/dist/index.js +3614 -2214
  20. package/dist/lazy-compilation-prewarm.d.ts +8 -5
  21. package/dist/manifest.d.ts +16 -4
  22. package/dist/mode-plan.d.ts +82 -0
  23. package/dist/modify-browser-manifest.d.ts +8 -4
  24. package/dist/performance.d.ts +4 -1
  25. package/dist/plugin-utils.d.ts +27 -1
  26. package/dist/prerender-build.d.ts +5 -5
  27. package/dist/prerender.d.ts +1 -5
  28. package/dist/react-router-config.d.ts +11 -3
  29. package/dist/route-artifacts.d.ts +4 -2
  30. package/dist/route-chunks.d.ts +2 -1
  31. package/dist/route-component-transform.d.ts +0 -2
  32. package/dist/route-export-pruning.d.ts +4 -1
  33. package/dist/route-imports.d.ts +18 -0
  34. package/dist/route-module-transform-loader.d.ts +14 -0
  35. package/dist/route-module-transform-loader.js +44 -0
  36. package/dist/route-module-transform-rules.d.ts +14 -0
  37. package/dist/route-transform-tasks.d.ts +6 -0
  38. package/dist/route-watch.d.ts +11 -6
  39. package/dist/rsc-dev-server.d.ts +26 -0
  40. package/dist/rsc-prerender.d.ts +54 -0
  41. package/dist/rsc-route-config.d.ts +6 -0
  42. package/dist/rsc-route-exports.d.ts +15 -0
  43. package/dist/rsc-route-transform-loader.cjs +43 -0
  44. package/dist/rsc-route-transform-loader.d.ts +30 -0
  45. package/dist/rsc-route-transform-loader.js +16 -0
  46. package/dist/rsc-route-transform-registration.d.ts +12 -0
  47. package/dist/rsc-route-transforms.d.ts +21 -0
  48. package/dist/rsc-support.d.ts +23 -0
  49. package/dist/rsc-virtual-modules.d.ts +19 -0
  50. package/dist/server-build-plan.d.ts +2 -1
  51. package/dist/server-build-resolution.d.ts +1 -2
  52. package/dist/server-utils.d.ts +4 -5
  53. package/dist/ssr-asset-relocation.d.ts +98 -0
  54. package/dist/templates/entry.rsc.client.d.ts +1 -0
  55. package/dist/templates/entry.rsc.client.js +61 -0
  56. package/dist/templates/entry.rsc.d.ts +9 -0
  57. package/dist/templates/entry.rsc.js +38 -0
  58. package/dist/templates/entry.rsc.ssr.d.ts +4 -0
  59. package/dist/templates/entry.rsc.ssr.js +24 -0
  60. package/dist/typegen.d.ts +4 -2
  61. package/dist/types.d.ts +34 -6
  62. package/package.json +76 -22
  63. package/src/build-output-transforms.ts +181 -43
  64. package/src/classic-mode.ts +253 -0
  65. package/src/config-imports.ts +153 -6
  66. package/src/constants.ts +6 -2
  67. package/src/dev-background-resources.ts +46 -100
  68. package/src/dev-generation.ts +52 -33
  69. package/src/dev-hmr.ts +112 -80
  70. package/src/dev-runtime-artifacts.ts +11 -12
  71. package/src/dev-runtime-controller.ts +75 -85
  72. package/src/dev-runtime-session.ts +14 -18
  73. package/src/dev-server.ts +2 -0
  74. package/src/dev-source-maps.ts +257 -0
  75. package/src/effect-runtime.ts +105 -57
  76. package/src/entry-paths.ts +80 -0
  77. package/src/environment-output.ts +55 -0
  78. package/src/export-utils.ts +15 -11
  79. package/src/federation.ts +38 -0
  80. package/src/index.ts +666 -519
  81. package/src/lazy-compilation-prewarm.ts +20 -4
  82. package/src/manifest.ts +157 -82
  83. package/src/mode-plan.ts +367 -0
  84. package/src/modify-browser-manifest.ts +130 -124
  85. package/src/performance.ts +11 -2
  86. package/src/plugin-utils.ts +103 -39
  87. package/src/prerender-build.ts +82 -104
  88. package/src/prerender.ts +23 -24
  89. package/src/react-router-config.ts +72 -26
  90. package/src/route-artifacts.ts +96 -66
  91. package/src/route-chunks.ts +167 -51
  92. package/src/route-component-transform.ts +14 -21
  93. package/src/route-export-pruning.ts +4 -3
  94. package/src/route-imports.ts +100 -0
  95. package/src/route-module-transform-loader.ts +149 -0
  96. package/src/route-module-transform-rules.ts +115 -0
  97. package/src/route-transform-tasks.ts +44 -29
  98. package/src/route-watch.ts +166 -188
  99. package/src/rsc-dev-server.ts +112 -0
  100. package/src/rsc-prerender.ts +362 -0
  101. package/src/rsc-route-config.ts +175 -0
  102. package/src/rsc-route-exports.ts +67 -0
  103. package/src/rsc-route-transform-loader.ts +65 -0
  104. package/src/rsc-route-transform-registration.ts +145 -0
  105. package/src/rsc-route-transforms.ts +995 -0
  106. package/src/rsc-runtime.d.ts +143 -0
  107. package/src/rsc-support.ts +116 -0
  108. package/src/rsc-virtual-modules.ts +113 -0
  109. package/src/server-build-plan.ts +14 -3
  110. package/src/server-build-resolution.ts +37 -47
  111. package/src/server-utils.ts +21 -35
  112. package/src/ssr-asset-relocation.ts +183 -0
  113. package/src/ssr-externals.ts +8 -26
  114. package/src/templates/entry.rsc.client.tsx +168 -0
  115. package/src/templates/entry.rsc.ssr.tsx +45 -0
  116. package/src/templates/entry.rsc.tsx +80 -0
  117. package/src/typegen.ts +40 -23
  118. package/src/types.ts +43 -6
  119. package/src/warnings/warn-on-client-source-maps.ts +6 -10
  120. package/dist/parallel-route-transform-protocol.d.ts +0 -25
  121. package/dist/parallel-route-transform-worker.d.ts +0 -1
  122. package/dist/parallel-route-transform-worker.js +0 -38
  123. package/dist/parallel-route-transforms.d.ts +0 -29
  124. package/src/parallel-route-transform-protocol.ts +0 -35
  125. package/src/parallel-route-transform-worker.ts +0 -82
  126. package/src/parallel-route-transforms.ts +0 -458
@@ -0,0 +1,15 @@
1
+ export type RscRouteComponentExport = {
2
+ readonly routeProperty: 'Component' | 'Layout' | 'ErrorBoundary' | 'HydrateFallback';
3
+ readonly clientExport: 'default' | 'Layout' | 'ErrorBoundary' | 'HydrateFallback';
4
+ readonly serverExport: 'ServerComponent' | 'ServerLayout' | 'ServerErrorBoundary' | 'ServerHydrateFallback';
5
+ };
6
+ export type RscClientComponentExport = RscRouteComponentExport['clientExport'];
7
+ export type RscServerComponentExport = RscRouteComponentExport['serverExport'];
8
+ export declare const RSC_ROUTE_COMPONENT_EXPORTS: readonly RscRouteComponentExport[];
9
+ export declare const RSC_MUTUALLY_EXCLUSIVE_ROUTE_EXPORTS: readonly (readonly [
10
+ RscClientComponentExport,
11
+ RscServerComponentExport
12
+ ])[];
13
+ export declare const RSC_CLIENT_COMPONENT_EXPORTS: readonly RscClientComponentExport[];
14
+ export declare const RSC_SERVER_COMPONENT_EXPORTS: readonly RscServerComponentExport[];
15
+ export declare const describeRscRouteExportConflict: (clientExport: string, serverExport: string) => string;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ const __rslib_import_meta_url__ = "u" < typeof document ? new (require('url'.replace('', ''))).URL('file:' + __filename).href : document.currentScript && document.currentScript.src || new URL('main.js', document.baseURI).href;
3
+ var __webpack_require__ = {};
4
+ __webpack_require__.d = (exports1, getters, values)=>{
5
+ var define = (defs, kind)=>{
6
+ for(var key in defs)__webpack_require__.o(defs, key) && !__webpack_require__.o(exports1, key) && Object.defineProperty(exports1, key, {
7
+ enumerable: !0,
8
+ [kind]: defs[key]
9
+ });
10
+ };
11
+ define(getters, "get"), define(values, "value");
12
+ }, __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop), __webpack_require__.r = (exports1)=>{
13
+ "u" > typeof Symbol && Symbol.toStringTag && Object.defineProperty(exports1, Symbol.toStringTag, {
14
+ value: 'Module'
15
+ }), Object.defineProperty(exports1, '__esModule', {
16
+ value: !0
17
+ });
18
+ };
19
+ var __webpack_exports__ = {};
20
+ function rscRouteTransformLoader(source, map) {
21
+ let callback = this.async(), transform = this._compiler?.__reactRouterRscRouteTransform;
22
+ transform ? transform({
23
+ code: source.toString(),
24
+ resource: this.resource,
25
+ resourcePath: this.resourcePath,
26
+ resourceQuery: this.resourceQuery,
27
+ environment: {
28
+ name: this.getOptions().environmentName
29
+ }
30
+ }).then((result)=>{
31
+ callback(null, result.code, result.map ?? map);
32
+ }).catch((error)=>{
33
+ callback(error instanceof Error ? error : Error(String(error)));
34
+ }) : callback(null, source, map);
35
+ }
36
+ for(var __rspack_i in __webpack_require__.r(__webpack_exports__), __webpack_require__.d(__webpack_exports__, {
37
+ default: ()=>rscRouteTransformLoader
38
+ }), exports.default = __webpack_exports__.default, __webpack_exports__)-1 === [
39
+ "default"
40
+ ].indexOf(__rspack_i) && (exports[__rspack_i] = __webpack_exports__[__rspack_i]);
41
+ Object.defineProperty(exports, '__esModule', {
42
+ value: !0
43
+ });
@@ -0,0 +1,30 @@
1
+ type LoaderCallback = (error: Error | null, code?: string | Buffer, map?: unknown) => void;
2
+ type TransformArgs = {
3
+ code: string;
4
+ resource: string;
5
+ resourcePath: string;
6
+ resourceQuery?: string;
7
+ environment: {
8
+ name: string;
9
+ };
10
+ };
11
+ type TransformResult = {
12
+ code: string;
13
+ map?: unknown;
14
+ };
15
+ type ReactRouterRscTransform = (args: TransformArgs) => Promise<TransformResult>;
16
+ type LoaderCompiler = {
17
+ __reactRouterRscRouteTransform?: ReactRouterRscTransform;
18
+ };
19
+ type RscRouteTransformLoaderContext = {
20
+ _compiler?: LoaderCompiler;
21
+ async(): LoaderCallback;
22
+ getOptions(): {
23
+ environmentName: string;
24
+ };
25
+ resource: string;
26
+ resourcePath: string;
27
+ resourceQuery?: string;
28
+ };
29
+ export default function rscRouteTransformLoader(this: RscRouteTransformLoaderContext, source: string | Buffer, map: unknown): void;
30
+ export {};
@@ -0,0 +1,16 @@
1
+ export default function(source, map) {
2
+ let callback = this.async(), transform = this._compiler?.__reactRouterRscRouteTransform;
3
+ transform ? transform({
4
+ code: source.toString(),
5
+ resource: this.resource,
6
+ resourcePath: this.resourcePath,
7
+ resourceQuery: this.resourceQuery,
8
+ environment: {
9
+ name: this.getOptions().environmentName
10
+ }
11
+ }).then((result)=>{
12
+ callback(null, result.code, result.map ?? map);
13
+ }).catch((error)=>{
14
+ callback(error instanceof Error ? error : Error(String(error)));
15
+ }) : callback(null, source, map);
16
+ };
@@ -0,0 +1,12 @@
1
+ import type { RsbuildPlugin } from '@rsbuild/core';
2
+ import type { RouteChunkCache, RouteChunkConfig } from './route-chunks.js';
3
+ import type { Route } from './types.js';
4
+ import type { ReactRouterPerformanceProfiler } from './performance.js';
5
+ export declare const registerReactRouterRscRouteTransforms: ({ api, isBuild, performanceProfiler, routeByFilePath, routeChunkCache, routeChunkConfig, }: {
6
+ api: Parameters<RsbuildPlugin["setup"]>[0];
7
+ isBuild: boolean;
8
+ performanceProfiler: Pick<ReactRouterPerformanceProfiler, "record">;
9
+ routeByFilePath: Map<string, Route>;
10
+ routeChunkCache: RouteChunkCache;
11
+ routeChunkConfig: RouteChunkConfig;
12
+ }) => void;
@@ -0,0 +1,21 @@
1
+ import { generate } from './yuku.js';
2
+ import { type RouteChunkCache, type RouteChunkConfig } from './route-chunks.js';
3
+ import type { Route } from './types.js';
4
+ type RscRouteTransformOptions = {
5
+ code: string;
6
+ resourcePath: string;
7
+ resourceQuery?: string;
8
+ isRootRoute: boolean;
9
+ routeId: string;
10
+ routeByFilePath?: ReadonlyMap<string, Route>;
11
+ routeChunkCache: RouteChunkCache;
12
+ routeChunkConfig: RouteChunkConfig;
13
+ isServerEnvironment: boolean;
14
+ isDev: boolean;
15
+ };
16
+ type RscRouteTransformResult = {
17
+ code: string;
18
+ map: null | ReturnType<typeof generate>['map'];
19
+ };
20
+ export declare const transformRscRouteModule: (options: RscRouteTransformOptions) => Promise<RscRouteTransformResult>;
21
+ export {};
@@ -0,0 +1,23 @@
1
+ import type { RsbuildPlugin } from '@rsbuild/core';
2
+ import type { Config } from './react-router-config.js';
3
+ import type { PluginOptions } from './types.js';
4
+ type RscPluginOptions = Exclude<NonNullable<PluginOptions['rsc']>, boolean>;
5
+ type RscUnsupportedConfig = Pick<Config, 'buildEnd' | 'future' | 'presets' | 'serverBundles' | 'subResourceIntegrity'>;
6
+ export declare const assertReactRouterRscConfigSupport: ({ pluginName, userConfig, }: {
7
+ pluginName: string;
8
+ userConfig: RscUnsupportedConfig;
9
+ }) => void;
10
+ export declare const assertReactRouterRscSupport: ({ pluginName, resolvePackagePath, }: {
11
+ pluginName: string;
12
+ resolvePackagePath: (specifier: string) => string | undefined;
13
+ }) => void;
14
+ export declare const setupReactRouterRscPlugin: ({ api, entryRscPath, entrySsrPath, pluginName, rsc, }: {
15
+ api: Parameters<RsbuildPlugin["setup"]>[0];
16
+ entryRscPath: string;
17
+ entrySsrPath: string;
18
+ pluginName: string;
19
+ rsc: RscPluginOptions;
20
+ }) => Promise<void>;
21
+ export { createReactRouterRscDevServerSetup } from './rsc-dev-server.js';
22
+ export { registerReactRouterRscRouteTransforms } from './rsc-route-transform-registration.js';
23
+ export { createReactRouterRscResolveAliases, createReactRouterRscVirtualModules, } from './rsc-virtual-modules.js';
@@ -0,0 +1,19 @@
1
+ import type { Config } from './react-router-config.js';
2
+ import type { Route } from './types.js';
3
+ type RscVirtualModulesOptions = {
4
+ allowedActionOrigins: string[] | undefined;
5
+ appDirectory: string;
6
+ basename: string;
7
+ buildDirectory: string;
8
+ isBuild: boolean;
9
+ /** Resolved web `output.distPath.js` segment, e.g. `static/js`. */
10
+ jsDistPath: string;
11
+ outputClientPath: string;
12
+ publicPath: string;
13
+ routeDiscovery: Config['routeDiscovery'];
14
+ routes: Record<string, Route>;
15
+ ssr: boolean;
16
+ };
17
+ export declare const createReactRouterRscResolveAliases: (rootPath: string) => Record<string, string>;
18
+ export declare const createReactRouterRscVirtualModules: ({ allowedActionOrigins, appDirectory, basename, buildDirectory, isBuild, jsDistPath, outputClientPath, publicPath, routeDiscovery, routes, ssr, }: RscVirtualModulesOptions) => Record<string, string>;
19
+ export {};
@@ -12,11 +12,12 @@ export declare const createReactRouterServerBuildPlan: ({ routesByServerBundleId
12
12
  serverBuildFile: string | undefined;
13
13
  defaultEntryName: string;
14
14
  }) => ReactRouterServerBuildPlan;
15
- export declare const createReactRouterNodeEntries: ({ hasServerApp, isBuild, serverAppPath, entryServerPath, defaultEntryName, serverBundleEntries, }: {
15
+ export declare const createReactRouterNodeEntries: ({ hasServerApp, isBuild, serverAppPath, entryServerPath, serverBuildFile, defaultEntryName, serverBundleEntries, }: {
16
16
  hasServerApp: boolean;
17
17
  isBuild: boolean;
18
18
  serverAppPath: string;
19
19
  entryServerPath: string;
20
+ serverBuildFile: string | undefined;
20
21
  defaultEntryName: string;
21
22
  serverBundleEntries: readonly ReactRouterServerBundleEntry[];
22
23
  }) => Record<string, string>;
@@ -1,3 +1,2 @@
1
- import * as Effect from 'effect/Effect';
2
1
  import type { ServerBuild } from 'react-router';
3
- export declare function resolveServerBuildModuleEffect(buildModule: unknown, source: string): Effect.Effect<ServerBuild, Error, never>;
2
+ export declare function resolveServerBuildModule(buildModule: unknown, source: string): Promise<ServerBuild>;
@@ -1,4 +1,5 @@
1
1
  import type { ServerBuild } from 'react-router';
2
+ import { resolveServerBuildModule } from './server-build-resolution.js';
2
3
  import type { Route } from './types.js';
3
4
  /**
4
5
  * Generates the server build template string.
@@ -13,6 +14,7 @@ interface ServerBuildOptions {
13
14
  basename: string;
14
15
  appDirectory: string;
15
16
  ssr: boolean;
17
+ isSpaMode: boolean;
16
18
  future?: unknown;
17
19
  allowedActionOrigins?: string[];
18
20
  prerender?: string[];
@@ -31,9 +33,6 @@ interface ServerBuildOptions {
31
33
  * @param options Build options
32
34
  * @returns The generated module content as a string
33
35
  */
34
- declare function generateServerBuild(routes: Record<string, Route>, options: ServerBuildOptions & {
35
- federation?: boolean;
36
- }): string;
37
- export declare function resolveServerBuildModule(buildModule: unknown, source: string): Promise<ServerBuild>;
36
+ export declare function generateServerBuild(routes: Record<string, Route>, options: ServerBuildOptions): string;
37
+ export { resolveServerBuildModule };
38
38
  export declare function resolveReactRouterServerBuild(buildModule: unknown): Promise<ServerBuild>;
39
- export { generateServerBuild };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Relocation of server-only static assets to the client build.
3
+ *
4
+ * In React Router framework mode a route's server-only code (a loader or a
5
+ * `.server` module) can import an asset — for example
6
+ * `import txtUrl from "./file.txt?url"` or a `.css?url` file. The imported URL
7
+ * is returned to the client (e.g. as loader data) and fetched from the client
8
+ * build directory at runtime, so the asset file must exist under
9
+ * `build/client` even though only the node/server compilation referenced it.
10
+ *
11
+ * Rspack emits these assets into the server output (`build/server/static/...`)
12
+ * and never into the client output. This module mirrors upstream React
13
+ * Router's Vite plugin, which internally enables `ssrEmitAssets` and then, in
14
+ * the SSR `writeBundle` hook, moves server-emitted static assets into the
15
+ * client assets directory and strips them from the server build
16
+ * (`react-router-dev/vite/plugin.ts`). Here the equivalent runs inside the
17
+ * node compilation's `processAssets` hook: static assets are written into the
18
+ * client output at the same public path and deleted from the server
19
+ * compilation so the server build never ships duplicate static files.
20
+ */
21
+ /**
22
+ * The subset of an Rspack asset info that identifies static assets emitted by
23
+ * asset modules (`asset/resource`) and the CSS pipeline.
24
+ */
25
+ export interface RelocatableAssetInfo {
26
+ /**
27
+ * Set by Rspack for assets produced from a source module (asset modules and
28
+ * extracted CSS). JavaScript chunks and generated files such as
29
+ * `package.json` do not carry a `sourceFilename`.
30
+ */
31
+ sourceFilename?: string;
32
+ /**
33
+ * Set for JavaScript chunk assets. Static assets never set this, so it is
34
+ * used to keep code-split JS in the server build.
35
+ */
36
+ javascriptModule?: boolean;
37
+ }
38
+ /**
39
+ * The minimal compilation surface needed to collect and relocate assets. Kept
40
+ * narrow so the logic can be unit-tested without a real Rspack compilation.
41
+ */
42
+ export interface RelocatableAssetCompilation {
43
+ assets: Record<string, unknown>;
44
+ getAsset(name: string): {
45
+ name: string;
46
+ source: {
47
+ buffer(): Buffer;
48
+ };
49
+ info: RelocatableAssetInfo;
50
+ } | undefined | void;
51
+ deleteAsset(name: string): void;
52
+ }
53
+ export interface CollectedServerAsset {
54
+ /** The public path of the asset, relative to the compilation output root. */
55
+ name: string;
56
+ source: {
57
+ buffer(): Buffer;
58
+ };
59
+ }
60
+ /**
61
+ * Determine whether an emitted asset is a static asset that must live in the
62
+ * client build. Static assets (asset modules and CSS) carry a `sourceFilename`
63
+ * and are not JavaScript chunks. Code-split JavaScript is intentionally
64
+ * excluded so it remains in the server build.
65
+ */
66
+ export declare const isRelocatableServerAsset: (info: RelocatableAssetInfo | undefined) => boolean;
67
+ /**
68
+ * Collect the server-only static assets from a node compilation. Returns them
69
+ * in stable (sorted) order so callers and tests see deterministic output.
70
+ */
71
+ export declare const collectRelocatableServerAssets: (compilation: RelocatableAssetCompilation) => CollectedServerAsset[];
72
+ export interface RelocateServerAssetsResult {
73
+ /** Assets written into the client output because they were missing or stale. */
74
+ written: string[];
75
+ /**
76
+ * Assets that already existed in the client output. They are still removed
77
+ * from the server build but not rewritten.
78
+ */
79
+ skipped: string[];
80
+ }
81
+ export declare const relocateServerAssetsToClient: ({ compilation, outputClientPath, relocatedDestinations, existsSyncFn, mkdirFn, readFileFn, renameFn, rmFn, writeFileFn, }: {
82
+ compilation: RelocatableAssetCompilation;
83
+ outputClientPath: string;
84
+ /**
85
+ * Destination content digests already handled by a previous compilation
86
+ * (dev rebuilds, serverBundles). Stable dev filenames can carry changed
87
+ * bytes, so the cache is keyed by path and digest rather than path alone.
88
+ */
89
+ relocatedDestinations?: Map<string, string>;
90
+ existsSyncFn?: (path: string) => boolean;
91
+ mkdirFn?: (dir: string) => Promise<unknown>;
92
+ readFileFn?: (path: string) => Promise<Buffer>;
93
+ renameFn?: (oldPath: string, newPath: string) => Promise<void>;
94
+ rmFn?: (path: string, options: {
95
+ force: true;
96
+ }) => Promise<void>;
97
+ writeFileFn?: (path: string, data: Buffer) => Promise<void>;
98
+ }) => Promise<RelocateServerAssetsResult>;
@@ -0,0 +1 @@
1
+ import 'virtual/react-router/unstable_rsc/inject-hmr-runtime';
@@ -0,0 +1,61 @@
1
+ import "virtual/react-router/unstable_rsc/inject-hmr-runtime";
2
+ import { hydrateRoot } from "react-dom/client";
3
+ import { unstable_RSCHydratedRouter, unstable_createCallServer, unstable_getRSCStream } from "react-router/dom";
4
+ import { createFromReadableStream, createTemporaryReferenceSet, encodeReply, setServerCallback } from "react-server-dom-rspack/client.browser";
5
+ import * as __rspack_external_react from "react";
6
+ let hydrationWindow = window, InitialRscDataLoadGuard = ({ active, children })=>(__rspack_external_react.useEffect(()=>{
7
+ let frame;
8
+ if (!active) return;
9
+ let clearGuardOnceDataLoadStarts = ()=>{
10
+ let router = hydrationWindow.__reactRouterDataRouter;
11
+ if (router && (router.state.initialized || 'idle' !== router.state.navigation.state)) {
12
+ hydrationWindow.__reactRouterHdrActive = !1;
13
+ return;
14
+ }
15
+ frame = requestAnimationFrame(clearGuardOnceDataLoadStarts);
16
+ };
17
+ return frame = requestAnimationFrame(clearGuardOnceDataLoadStarts), ()=>cancelAnimationFrame(frame);
18
+ }, [
19
+ active
20
+ ]), children);
21
+ setServerCallback(unstable_createCallServer({
22
+ createFromReadableStream: createFromReadableStream,
23
+ createTemporaryReferenceSet: createTemporaryReferenceSet,
24
+ encodeReply: encodeReply
25
+ }));
26
+ let hydrate = ()=>{
27
+ createFromReadableStream(unstable_getRSCStream()).then((payload)=>{
28
+ (0, __rspack_external_react.startTransition)(async ()=>{
29
+ let formState = 'render' === payload.type ? await payload.formState : void 0, needsInitialDataLoadGuard = 'render' === payload.type && payload.matches.some((match)=>null != match.clientLoader && !match.hasLoader && null != match.hydrateFallbackElement);
30
+ needsInitialDataLoadGuard && (hydrationWindow.__reactRouterHdrActive = !0), hydrateRoot(document, __rspack_external_react.createElement(__rspack_external_react.StrictMode, null, __rspack_external_react.createElement(InitialRscDataLoadGuard, {
31
+ active: needsInitialDataLoadGuard
32
+ }, __rspack_external_react.createElement(unstable_RSCHydratedRouter, {
33
+ createFromReadableStream: createFromReadableStream,
34
+ payload
35
+ }))), {
36
+ formState
37
+ });
38
+ });
39
+ }, (error)=>{
40
+ setTimeout(()=>{
41
+ throw error;
42
+ });
43
+ });
44
+ };
45
+ 'loading' === document.readyState ? document.addEventListener('DOMContentLoaded', hydrate, {
46
+ once: !0
47
+ }) : hydrate();
48
+ let hot = import.meta.webpackHot;
49
+ hot?.on('rsc:update', (data)=>{
50
+ requestAnimationFrame(()=>{
51
+ let router = window.__reactRouterDataRouter;
52
+ if (data?.revalidate) return void router?.revalidate();
53
+ if (router?.navigate) {
54
+ let basename = router.basename || '/', pathname = window.location.pathname;
55
+ '/' !== basename && pathname.startsWith(basename) && '/' !== (pathname = pathname.slice(basename.length) || '/')[0] && (pathname = '/' + pathname), router.navigate(pathname + window.location.search + window.location.hash, {
56
+ replace: !0,
57
+ preventScrollReset: !0
58
+ });
59
+ }
60
+ });
61
+ });
@@ -0,0 +1,9 @@
1
+ import { RouterContextProvider } from 'react-router';
2
+ import unstable_reactRouterServeConfig from 'virtual/react-router/unstable_rsc/react-router-serve-config';
3
+ export { unstable_reactRouterServeConfig };
4
+ type RscRequestHandler = {
5
+ fetch(request: Request, requestContext?: RouterContextProvider): Promise<Response>;
6
+ };
7
+ export declare function fetchServer(request: Request, requestContext?: RouterContextProvider): Promise<Response>;
8
+ declare const handler: RscRequestHandler;
9
+ export default handler;
@@ -0,0 +1,38 @@
1
+ import { createTemporaryReferenceSet, decodeAction, decodeFormState, decodeReply, loadServerAction, renderToReadableStream } from "react-server-dom-rspack/server.node";
2
+ import { RouterContextProvider, unstable_matchRSCServerRequest } from "react-router";
3
+ import routes from "virtual/react-router/unstable_rsc/routes";
4
+ import route_discovery from "virtual/react-router/unstable_rsc/route-discovery";
5
+ import basename from "virtual/react-router/unstable_rsc/basename";
6
+ import allowed_action_origins from "virtual/react-router/unstable_rsc/allowed-action-origins";
7
+ import client_version from "virtual/react-router/unstable_rsc/client-version";
8
+ import server_manifest from "virtual/react-router/unstable_rsc/server-manifest";
9
+ import bootstrap_scripts from "virtual/react-router/unstable_rsc/bootstrap-scripts";
10
+ import { generateHTML } from "./entry.rsc.ssr.js";
11
+ function fetchServer(request, requestContext) {
12
+ return unstable_matchRSCServerRequest({
13
+ allowedActionOrigins: allowed_action_origins,
14
+ basename: basename,
15
+ clientVersion: client_version,
16
+ createTemporaryReferenceSet: createTemporaryReferenceSet,
17
+ decodeAction: (body)=>decodeAction(body, server_manifest()),
18
+ decodeFormState: async (actionResult, body)=>await decodeFormState(actionResult, body, server_manifest()) ?? void 0,
19
+ decodeReply: decodeReply,
20
+ loadServerAction: (id)=>Promise.resolve(loadServerAction(id)),
21
+ request,
22
+ requestContext,
23
+ routes: routes,
24
+ routeDiscovery: route_discovery,
25
+ generateResponse: (match, options)=>new Response(renderToReadableStream(match.payload, options), {
26
+ status: match.statusCode,
27
+ headers: match.headers
28
+ })
29
+ });
30
+ }
31
+ import.meta.webpackHot?.accept();
32
+ export { default as unstable_reactRouterServeConfig } from "virtual/react-router/unstable_rsc/react-router-serve-config";
33
+ export default {
34
+ fetch: async (request, requestContext)=>(!requestContext || requestContext instanceof RouterContextProvider || (requestContext = void 0), generateHTML(request, await fetchServer(request, requestContext), {
35
+ bootstrapScripts: bootstrap_scripts
36
+ }))
37
+ };
38
+ export { fetchServer };
@@ -0,0 +1,4 @@
1
+ export declare function generateHTML(request: Request, serverResponse: Response, options?: {
2
+ bootstrapScripts?: string[];
3
+ bootstrapModules?: string[];
4
+ }): Promise<Response>;
@@ -0,0 +1,24 @@
1
+ import { renderToReadableStream } from "react-dom/server";
2
+ import { unstable_RSCStaticRouter, unstable_routeRSCServerRequest } from "react-router";
3
+ import { createFromReadableStream } from "react-server-dom-rspack/client.node";
4
+ import * as __rspack_external_react from "react";
5
+ async function generateHTML(request, serverResponse, options = {}) {
6
+ return unstable_routeRSCServerRequest({
7
+ request,
8
+ serverResponse,
9
+ createFromReadableStream: createFromReadableStream,
10
+ async renderHTML (getPayload, renderOptions) {
11
+ let payloadPromise = getPayload();
12
+ return payloadPromise.formState ??= payloadPromise.then((payload)=>'render' === payload.type ? payload.formState : void 0), renderToReadableStream(__rspack_external_react.createElement(unstable_RSCStaticRouter, {
13
+ getPayload: getPayload
14
+ }), {
15
+ ...renderOptions,
16
+ bootstrapModules: options.bootstrapModules,
17
+ bootstrapScripts: options.bootstrapScripts,
18
+ formState: await payloadPromise.formState,
19
+ signal: request.signal
20
+ });
21
+ }
22
+ });
23
+ }
24
+ export { generateHTML };
package/dist/typegen.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { RsbuildPluginAPI } from '@rsbuild/core';
2
+ import { type PluginEffectRuntime } from './effect-runtime.js';
2
3
  type Execa = typeof import('execa').execa;
3
4
  type LoadExeca = () => Promise<Execa>;
4
5
  export type ReactRouterTypegenRunner = {
@@ -7,9 +8,10 @@ export type ReactRouterTypegenRunner = {
7
8
  runBuild(): Promise<void>;
8
9
  };
9
10
  export declare const createReactRouterTypegenRunner: (loadExeca?: LoadExeca, appDirectory?: string) => ReactRouterTypegenRunner;
10
- export declare const registerReactRouterTypegen: (api: RsbuildPluginAPI, { runner, devWatchDelayMs, appDirectory, }?: {
11
+ export declare const registerReactRouterTypegen: (api: RsbuildPluginAPI, { runtime, runner, devWatchDelayMs, appDirectory, }: {
12
+ runtime: PluginEffectRuntime;
11
13
  runner?: ReactRouterTypegenRunner;
12
14
  devWatchDelayMs?: number;
13
15
  appDirectory?: string;
14
- }) => void;
16
+ }) => Promise<void>;
15
17
  export {};
package/dist/types.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { RsbuildConfig } from '@rsbuild/core';
1
+ import type { RsbuildConfig, Rspack } from '@rsbuild/core';
2
2
  export type Route = {
3
3
  id: string;
4
4
  parentId?: string;
@@ -25,6 +25,20 @@ export type PluginOptions = {
25
25
  * Federation mode configuration
26
26
  */
27
27
  federation?: boolean;
28
+ /**
29
+ * Enable experimental React Router RSC framework mode.
30
+ * This composes `rsbuild-plugin-rsc` with React Router's Rsbuild
31
+ * environments. Environment names are managed by this plugin.
32
+ * Requires `react-router >=7.18.0 || >=8.0.0`, `rsbuild-plugin-rsc`,
33
+ * and `react-server-dom-rspack`.
34
+ * @default false
35
+ */
36
+ rsc?: boolean | {
37
+ layers?: {
38
+ rsc?: Rspack.RuleSetCondition;
39
+ ssr?: Rspack.RuleSetCondition;
40
+ };
41
+ };
28
42
  /**
29
43
  * Rsbuild dev-only lazy compilation behavior.
30
44
  *
@@ -49,11 +63,10 @@ export type PluginOptions = {
49
63
  */
50
64
  logPerformance?: boolean;
51
65
  /**
52
- * Run route transforms in a worker-thread pool.
53
- * Pass `true` to force the default worker count, a positive integer to set
54
- * the worker count, or `false` to disable.
55
- * @default Automatically enabled for 256+ resolved routes. The automatic
56
- * pool uses available CPU cores minus 2.
66
+ * Run route module transforms with Rspack's parallel loader workers.
67
+ * Pass `true` to use Rspack's default worker count, a positive integer to set
68
+ * the maximum worker count, or `false` to disable.
69
+ * @default false
57
70
  */
58
71
  parallelRouteTransform?: boolean | number;
59
72
  /**
@@ -64,6 +77,21 @@ export type PluginOptions = {
64
77
  */
65
78
  onRouteTopologyChange?: () => void | Promise<void>;
66
79
  };
80
+ export type ReactRouterRSCPluginOptions = Omit<PluginOptions, 'rsc'> & {
81
+ /**
82
+ * Optional overrides forwarded to `rsbuild-plugin-rsc`.
83
+ * Environment names are managed by this plugin.
84
+ */
85
+ rsc?: Exclude<NonNullable<PluginOptions['rsc']>, boolean>;
86
+ };
87
+ export type PrerenderPathsConfig = boolean | string[] | ((args: {
88
+ getStaticPaths: () => string[];
89
+ }) => boolean | string[] | Promise<boolean | string[]>);
90
+ export type PrerenderConfigObject = {
91
+ paths: PrerenderPathsConfig;
92
+ concurrency?: number;
93
+ unstable_concurrency?: number;
94
+ };
67
95
  export type RouteManifestItem = Omit<Route, 'file' | 'children'> & {
68
96
  module: string;
69
97
  clientActionModule?: string;