rsbuild-plugin-react-router 0.3.0 → 0.4.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 (64) hide show
  1. package/README.md +88 -35
  2. package/dist/451.js +164 -30
  3. package/dist/build-manifest.d.ts +6 -3
  4. package/dist/build-output-transforms.d.ts +2 -1
  5. package/dist/concurrency.d.ts +2 -1
  6. package/dist/config-imports.d.ts +7 -0
  7. package/dist/dev-background-resources.d.ts +38 -0
  8. package/dist/dev-generation.d.ts +2 -2
  9. package/dist/dev-hmr.d.ts +45 -0
  10. package/dist/dev-runtime-artifacts.d.ts +9 -1
  11. package/dist/dev-runtime-compilation.d.ts +17 -2
  12. package/dist/dev-runtime-controller.d.ts +6 -1
  13. package/dist/dev-server.d.ts +5 -0
  14. package/dist/effect-runtime.d.ts +18 -0
  15. package/dist/export-utils.d.ts +2 -2
  16. package/dist/index.cjs +11852 -848
  17. package/dist/index.d.ts +5 -0
  18. package/dist/index.js +8289 -773
  19. package/dist/lazy-compilation-prewarm.d.ts +25 -0
  20. package/dist/lazy-compilation.d.ts +2 -1
  21. package/dist/manifest.d.ts +19 -4
  22. package/dist/parallel-route-transforms.d.ts +17 -2
  23. package/dist/prerender-build.d.ts +4 -0
  24. package/dist/prerender.d.ts +0 -1
  25. package/dist/react-router-config.d.ts +8 -5
  26. package/dist/route-artifacts.d.ts +10 -2
  27. package/dist/route-transform-tasks.d.ts +3 -0
  28. package/dist/server-build-resolution.d.ts +3 -0
  29. package/dist/ssr-externals.d.ts +1 -0
  30. package/dist/typegen.d.ts +14 -1
  31. package/dist/types.d.ts +15 -6
  32. package/package.json +18 -10
  33. package/src/build-manifest.ts +110 -73
  34. package/src/build-output-transforms.ts +5 -0
  35. package/src/concurrency.ts +3 -22
  36. package/src/config-imports.ts +38 -0
  37. package/src/dev-background-resources.ts +255 -0
  38. package/src/dev-generation.ts +43 -53
  39. package/src/dev-hmr.ts +431 -0
  40. package/src/dev-runtime-artifacts.ts +50 -18
  41. package/src/dev-runtime-compilation.ts +80 -1
  42. package/src/dev-runtime-controller.ts +155 -31
  43. package/src/dev-runtime-session.ts +18 -11
  44. package/src/dev-server.ts +31 -1
  45. package/src/effect-runtime.ts +130 -0
  46. package/src/export-utils.ts +82 -23
  47. package/src/index.ts +166 -153
  48. package/src/lazy-compilation-prewarm.ts +279 -0
  49. package/src/lazy-compilation.ts +12 -5
  50. package/src/manifest.ts +366 -255
  51. package/src/modify-browser-manifest.ts +2 -1
  52. package/src/parallel-route-transforms.ts +195 -69
  53. package/src/prerender-build.ts +147 -63
  54. package/src/prerender.ts +1 -19
  55. package/src/react-router-config.ts +98 -73
  56. package/src/route-artifacts.ts +122 -3
  57. package/src/route-export-resolution.ts +3 -3
  58. package/src/route-transform-tasks.ts +173 -2
  59. package/src/route-watch.ts +119 -84
  60. package/src/server-build-resolution.ts +131 -0
  61. package/src/server-utils.ts +7 -106
  62. package/src/ssr-externals.ts +1 -1
  63. package/src/typegen.ts +162 -33
  64. package/src/types.ts +16 -6
@@ -0,0 +1,45 @@
1
+ import type { Rspack } from '@rsbuild/core';
2
+ export declare const DEV_HMR_RUNTIME_MODULE_ID = "virtual/react-router/hmr-runtime";
3
+ export declare const isRspackSwcReactRefreshEnabled: (rspackConfig: Rspack.Configuration) => boolean;
4
+ /**
5
+ * Resolves the `react-refresh/runtime` module that
6
+ * `@rspack/plugin-react-refresh` injects into the web bundle. The resolution
7
+ * walks the same dependency chain the refresh plugin uses so the returned file
8
+ * is the exact runtime instance already present in the browser module graph.
9
+ * Returns `undefined` when React Fast Refresh is unavailable, in which case
10
+ * dev HMR falls back to full reloads.
11
+ */
12
+ export declare const resolveReactRefreshRuntimePath: (rootPath: string) => string | undefined;
13
+ /**
14
+ * The HDR revision module is a real file (not a virtual module) because it
15
+ * must wake the web compiler through the regular file watcher: the browser
16
+ * HMR runtime imports it, so bumping the revision produces a web hot update
17
+ * whenever server code changes, which the client answers by revalidating
18
+ * React Router loader data.
19
+ */
20
+ export declare const DEV_HDR_REVISION_RELATIVE_PATH = ".react-router/hdr-revision.mjs";
21
+ export declare const getDevHdrRevisionFilePath: (rootPath: string) => string;
22
+ export type DevHdrRevisionSignal = {
23
+ /** Writes the initial revision module so the first compile can resolve it. */
24
+ ensure: () => void;
25
+ /** Increments the revision, signaling hot data revalidation to the client. */
26
+ bump: () => void;
27
+ };
28
+ export declare const createDevHdrRevisionSignal: ({ filePath, onError, }: {
29
+ filePath: string;
30
+ onError?: (error: Error) => void;
31
+ }) => DevHdrRevisionSignal;
32
+ /**
33
+ * Browser-side HMR runtime shared by all route client entries in development.
34
+ *
35
+ * This mirrors React Router's Vite HMR contract (see `refresh-utils.mjs` in
36
+ * `@react-router/dev`): route module updates are applied by patching
37
+ * `window.__reactRouterRouteModules` while preserving the previous component
38
+ * identities (React Fast Refresh swaps their implementations in place),
39
+ * recreating the client routes with revalidation opt-out, revalidating loader
40
+ * data, and finally performing a React refresh.
41
+ */
42
+ export declare const generateDevHmrRuntimeModule: ({ reactRefreshRuntimePath, hdrRevisionFilePath, }: {
43
+ reactRefreshRuntimePath: string;
44
+ hdrRevisionFilePath: string;
45
+ }) => string;
@@ -8,6 +8,11 @@ export type ReactRouterDevBuildPlan = {
8
8
  };
9
9
  export type ReactRouterDevManifestSet = Readonly<Record<string, ReactRouterDevManifest>>;
10
10
  export type ReactRouterServerBuilds = Readonly<Record<string, ServerBuild>>;
11
+ export type PairedDevStats = {
12
+ web: Rspack.Stats;
13
+ node: Rspack.Stats;
14
+ };
15
+ export type DevRuntimeStats = Rspack.Stats | Rspack.MultiStats | PairedDevStats;
11
16
  export type DependencySnapshot = {
12
17
  files: ReadonlySet<string>;
13
18
  contexts: ReadonlySet<string>;
@@ -22,10 +27,12 @@ export type DevGraphChanges = {
22
27
  node: DevChangedFiles;
23
28
  };
24
29
  export type DevCompilationIdentity = symbol;
30
+ export type DevCompileAttemptIdentity = symbol;
25
31
  export type DevGraphIdentity = {
26
32
  web: DevCompilationIdentity | undefined;
27
33
  node: DevCompilationIdentity | undefined;
28
34
  nodeWeb: DevCompilationIdentity | undefined;
35
+ attempt: DevCompileAttemptIdentity | undefined;
29
36
  };
30
37
  export type WebArtifact = {
31
38
  manifestsByEntryName: ReactRouterDevManifestSet;
@@ -34,6 +41,7 @@ export type WebArtifact = {
34
41
  export declare const snapshotDevChangedFiles: (compiler: Pick<Rspack.Compiler, "modifiedFiles" | "removedFiles"> | undefined) => DevChangedFiles;
35
42
  export declare const snapshotDependencies: (compilation: Rspack.Compilation) => DependencySnapshot;
36
43
  export declare const isSafeOneSidedChange: (changes: DevChangedFiles, dependencies: DependencySnapshot) => boolean;
37
- export declare const getEnvironmentStats: (stats: Rspack.Stats | Rspack.MultiStats, name: "web" | "node") => Rspack.Stats | undefined;
44
+ export declare const isPairedDevStats: (stats: DevRuntimeStats) => stats is PairedDevStats;
45
+ export declare const getEnvironmentStats: (stats: DevRuntimeStats, name: "web" | "node") => Rspack.Stats | undefined;
38
46
  export declare const evaluateServerBuilds: (server: RsbuildDevServer, entryNames: readonly string[]) => Promise<ReactRouterServerBuilds>;
39
47
  export declare const pinServerBuildsToManifests: (builds: ReactRouterServerBuilds, entryNames: readonly string[], manifestsByEntryName: ReactRouterDevManifestSet) => ReactRouterServerBuilds;
@@ -1,16 +1,19 @@
1
1
  import type { Rspack } from '@rsbuild/core';
2
- import type { DevCompilationIdentity, DevGraphChanges, DevGraphIdentity } from './dev-runtime-artifacts.js';
2
+ import type { DevCompileAttemptIdentity, DevCompilationIdentity, DevRuntimeStats, DevGraphChanges, DevGraphIdentity } from './dev-runtime-artifacts.js';
3
3
  export type DevCompilerPair = {
4
4
  web: Rspack.Compiler;
5
5
  node: Rspack.Compiler;
6
6
  settledCompilations: WeakSet<Rspack.Compilation>;
7
7
  pendingAttempt?: PendingDevCompilation;
8
+ currentAttemptIdentity?: DevCompileAttemptIdentity;
8
9
  latestCompletedWebIdentity?: DevCompilationIdentity;
10
+ latestCompletedWebStats?: Rspack.Stats;
11
+ latestCompletedNodeStats?: Rspack.Stats;
9
12
  latestWebStart?: CompilationStart;
10
13
  latestNodeStart?: CompilationStart;
11
14
  };
12
15
  export type PendingDevCompilation = {
13
- stats: Rspack.Stats | Rspack.MultiStats;
16
+ stats: DevRuntimeStats;
14
17
  changes: DevGraphChanges;
15
18
  identity: DevGraphIdentity;
16
19
  webCompilation: Rspack.Compilation;
@@ -22,11 +25,23 @@ export type CompilationStart = {
22
25
  status: 'started';
23
26
  identity: DevCompilationIdentity;
24
27
  };
28
+ type CompilerPairStartSide = 'latestWebStart' | 'latestNodeStart';
29
+ export declare const createDevCompilerPair: ({ web, node, }: {
30
+ web: Rspack.Compiler;
31
+ node: Rspack.Compiler;
32
+ }) => DevCompilerPair;
33
+ export declare const resetDevCompilerPair: (pair: DevCompilerPair) => void;
25
34
  export declare const isLatestStartedCompilation: (identity: DevCompilationIdentity | undefined, start: CompilationStart | undefined) => boolean;
26
35
  export declare const hasPendingCompilation: (pair: DevCompilerPair) => boolean;
36
+ export declare const beginDevCompilerAttempt: (pair: DevCompilerPair) => void;
37
+ export declare const markDevCompilerPending: (pair: DevCompilerPair, side: CompilerPairStartSide) => boolean;
38
+ export declare const clearDevCompilerStart: (pair: DevCompilerPair, side: CompilerPairStartSide) => void;
27
39
  export type CompilationIdentityTracker = {
28
40
  getCompilationIdentity(compilation: Rspack.Compilation): DevCompilationIdentity;
29
41
  getWebIdentityForNodeCompilation(compilation: Rspack.Compilation): DevCompilationIdentity | undefined;
42
+ getAttemptIdentityForCompilation(compilation: Rspack.Compilation): DevCompileAttemptIdentity | undefined;
43
+ setAttemptIdentityForCompilation(compilation: Rspack.Compilation, identity: DevCompileAttemptIdentity): void;
30
44
  setWebIdentityForNodeCompilation(compilation: Rspack.Compilation, identity: DevCompilationIdentity): void;
31
45
  };
32
46
  export declare const createCompilationIdentityTracker: () => CompilationIdentityTracker;
47
+ export {};
@@ -9,6 +9,11 @@ type CreateControllerOptions = {
9
9
  api: RsbuildPluginAPI;
10
10
  isBuild: boolean;
11
11
  buildPlan: ReactRouterDevBuildPlan;
12
+ /**
13
+ * Invoked after a development attempt commits a re-evaluated node build for
14
+ * changed server files. Used to signal hot data revalidation to the client.
15
+ */
16
+ onNodeRebuildCommitted?: () => void;
12
17
  };
13
- export declare const createReactRouterDevRuntimeController: ({ api, isBuild, buildPlan, }: CreateControllerOptions) => ReactRouterDevRuntimeController;
18
+ export declare const createReactRouterDevRuntimeController: ({ api, isBuild, buildPlan, onNodeRebuildCommitted, }: CreateControllerOptions) => ReactRouterDevRuntimeController;
14
19
  export {};
@@ -1,5 +1,7 @@
1
1
  import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { RsbuildConfig } from '@rsbuild/core';
2
3
  import type { ServerBuild } from 'react-router';
4
+ export type ServerSetup = Exclude<NonNullable<NonNullable<RsbuildConfig['server']>['setup']>, unknown[]>;
3
5
  export type DevServerMiddleware = (req: IncomingMessage, res: ServerResponse, next: (err?: unknown) => void) => Promise<void>;
4
6
  type RequestHandler = (request: Request) => Response | Promise<Response>;
5
7
  type BuildProvider = () => Promise<ServerBuild>;
@@ -9,4 +11,7 @@ export type DevServerMiddlewareDependencies = {
9
11
  createRequestListener?: (handler: RequestHandler) => (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
10
12
  };
11
13
  export declare const createDevServerMiddleware: (dependencies: DevServerMiddlewareDependencies) => DevServerMiddleware;
14
+ export declare const createReactRouterDevServerSetup: ({ loadBuild, }: {
15
+ loadBuild: BuildProvider;
16
+ }) => ServerSetup;
12
17
  export {};
@@ -0,0 +1,18 @@
1
+ import * as Effect from 'effect/Effect';
2
+ export declare const DEV_BACKGROUND_STARTUP_DELAY_MS = 3000;
3
+ export declare const normalizeEffectError: (cause: unknown) => Error;
4
+ export declare const runPluginEffect: <A, E>(effect: Effect.Effect<A, E, never>) => Promise<A>;
5
+ export declare const tryPluginSync: <A>(evaluate: () => A) => Effect.Effect<A, Error, never>;
6
+ export declare const tryPluginPromise: <A>(evaluate: () => PromiseLike<A> | A) => Effect.Effect<A, Error, never>;
7
+ type DelayedPluginTask = {
8
+ schedule(): void;
9
+ reschedule(): void;
10
+ cancelEffect(): Effect.Effect<void, Error, never>;
11
+ cancel(): Promise<void>;
12
+ };
13
+ export declare const createDelayedPluginTask: ({ delayMs, run, onError, }: {
14
+ delayMs: number;
15
+ run: () => Effect.Effect<void, Error, never>;
16
+ onError: (error: Error) => void;
17
+ }) => DelayedPluginTask;
18
+ export {};
@@ -9,7 +9,7 @@ type RouteModuleAnalysis = {
9
9
  readonly exportAllModules: readonly string[];
10
10
  };
11
11
  export declare const collectProgramExportNames: (program: ProgramNode) => string[];
12
- export declare const getExportNames: (code: string) => Promise<readonly string[]>;
13
- export declare const getExportNamesAndExportAll: (code: string) => Promise<ExportInfo>;
12
+ export declare const getExportNames: (code: string, resourcePath?: string) => Promise<readonly string[]>;
13
+ export declare const getExportNamesAndExportAll: (code: string, resourcePath?: string) => Promise<ExportInfo>;
14
14
  export declare const getRouteModuleAnalysis: (resourcePath: string) => Promise<RouteModuleAnalysis>;
15
15
  export {};