rsbuild-plugin-react-router 0.6.6 → 0.7.1

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.
@@ -1,7 +1,7 @@
1
1
  import { relative, resolve } from 'pathe';
2
2
  import type { Config } from './react-router-config.js';
3
3
  import type { Route } from './types.js';
4
- import { combineURLs, normalizeAssetPrefix } from './plugin-utils.js';
4
+ import { normalizeAssetPrefix } from './plugin-utils.js';
5
5
  import { getVirtualModuleFilePath } from './virtual-modules.js';
6
6
  import {
7
7
  createRscInternalClientModule,
@@ -19,6 +19,7 @@ const RSC_VIRTUAL_ALIAS_IDS = [
19
19
  'allowed-action-origins',
20
20
  'client-version',
21
21
  'react-router-serve-config',
22
+ 'manifest-prefix',
22
23
  'bootstrap-scripts',
23
24
  'server-manifest',
24
25
  ] as const;
@@ -29,8 +30,6 @@ type RscVirtualModulesOptions = {
29
30
  basename: string;
30
31
  buildDirectory: string;
31
32
  isBuild: boolean;
32
- /** Resolved web `output.distPath.js` segment, e.g. `static/js`. */
33
- jsDistPath: string;
34
33
  outputClientPath: string;
35
34
  publicPath: string;
36
35
  routeDiscovery: Config['routeDiscovery'];
@@ -73,7 +72,6 @@ export const createReactRouterRscVirtualModules = ({
73
72
  basename,
74
73
  buildDirectory,
75
74
  isBuild,
76
- jsDistPath,
77
75
  outputClientPath,
78
76
  publicPath,
79
77
  routeDiscovery,
@@ -84,7 +82,10 @@ export const createReactRouterRscVirtualModules = ({
84
82
  resolve(buildDirectory, 'server'),
85
83
  outputClientPath
86
84
  );
87
- const bootstrapPublicPath = normalizeAssetPrefix(publicPath);
85
+ // Absolute prefix the server must use for initial asset URLs (see
86
+ // `resolveEffectiveAssetPrefix`); the browser compiler may itself be on
87
+ // `'auto'`, which no server-rendered URL can express.
88
+ const serverPublicPath = normalizeAssetPrefix(publicPath);
88
89
 
89
90
  return {
90
91
  'virtual/react-router/unstable_rsc/routes': createRscRouteConfig({
@@ -111,9 +112,59 @@ export const createReactRouterRscVirtualModules = ({
111
112
  assetsBuildDirectory: rscAssetsBuildDirectory,
112
113
  publicPath,
113
114
  }),
114
- 'virtual/react-router/unstable_rsc/bootstrap-scripts': defaultExport([
115
- combineURLs(bootstrapPublicPath, `${jsDistPath}/index.js`),
116
- ]),
115
+ // Every server-facing asset URL in the rspack RSC manifest -- bootstrap
116
+ // `entryJsFiles`, route `entryCssFiles`, client references' `cssFiles`
117
+ // (react-server-dom-rspack renders those as <link>s), and Flight's
118
+ // `moduleLoading.prefix` for client-chunk preloads -- carries the browser
119
+ // compiler's public path, recorded in `moduleLoading.prefix`. With the
120
+ // browser compiler on `'auto'` rspack records `/`, which the server cannot
121
+ // serve from. `__rspack_rsc_manifest__` is this same object, so aligning
122
+ // it once, in place (arrays are mutated, not replaced, because
123
+ // `createServerEntry` has already captured references), makes every
124
+ // consumer agree on the server prefix without stacking a second one. The
125
+ // aligned manifest is exported (not imported for side effects only) so a
126
+ // `sideEffects: false` package cannot tree-shake the alignment away.
127
+ 'virtual/react-router/unstable_rsc/manifest-prefix': `const manifest = __webpack_require__.rscM;
128
+ const serverPrefix = ${JSON.stringify(serverPublicPath)};
129
+ const appliedPrefix = manifest?.moduleLoading?.prefix;
130
+ // An empty applied prefix (web \`assetPrefix: ''\`) yields relative references
131
+ // such as "static/js/index.js"; those are rebased too, while absolute and
132
+ // protocol-relative URLs are left alone.
133
+ const isAbsoluteUrl = url => /^(?:[a-z][a-z\\d+.-]*:|\\/\\/|\\/)/i.test(url);
134
+ if (typeof appliedPrefix === "string" && appliedPrefix !== serverPrefix) {
135
+ const rewrite = url =>
136
+ typeof url !== "string"
137
+ ? url
138
+ : appliedPrefix !== "" && url.startsWith(appliedPrefix)
139
+ ? serverPrefix + url.slice(appliedPrefix.length)
140
+ : appliedPrefix === "" && !isAbsoluteUrl(url)
141
+ ? serverPrefix + url
142
+ : url;
143
+ const rewriteAll = list => {
144
+ if (Array.isArray(list)) for (let i = 0; i < list.length; i++) list[i] = rewrite(list[i]);
145
+ };
146
+ manifest.moduleLoading.prefix = serverPrefix;
147
+ rewriteAll(manifest.entryJsFiles);
148
+ for (const files of Object.values(manifest.entryCssFiles ?? {})) rewriteAll(files);
149
+ for (const reference of Object.values(manifest.clientManifest ?? {})) rewriteAll(reference.cssFiles);
150
+ }
151
+ export const rscManifest = manifest;
152
+ `,
153
+ // The compiled browser entry scripts come from the manifest (like Next's
154
+ // `buildManifest` or the Vite plugin's `loadBootstrapScriptContent`), so
155
+ // hashed entry filenames resolve without any naming contract. The list and
156
+ // its order are preserved. An empty list is a build problem (rspack only
157
+ // records entry files named `*.js`); fail loudly instead of guessing a
158
+ // filename that would render a document which cannot hydrate.
159
+ 'virtual/react-router/unstable_rsc/bootstrap-scripts': `import { rscManifest } from "virtual/react-router/unstable_rsc/manifest-prefix";
160
+ const entryJsFiles = rscManifest?.entryJsFiles;
161
+ if (!entryJsFiles?.length) {
162
+ throw new Error(
163
+ "[rsbuild-plugin-react-router] The rspack RSC manifest lists no browser entry script (entryJsFiles is empty), so the server cannot render bootstrap scripts. Rspack only records entry files whose name ends in \\".js\\"; web output.filename.js values with a query (for example \\"[name].js?v=[contenthash:8]\\") or another extension are not supported in RSC mode."
164
+ );
165
+ }
166
+ export default entryJsFiles;
167
+ `,
117
168
  'virtual/react-router/unstable_rsc/server-manifest': `export default function getServerManifest() {
118
169
  return __webpack_require__.rscM?.serverManifest;
119
170
  }