rsbuild-plugin-react-router 0.1.1 → 0.3.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.
- package/README.md +185 -204
- package/dist/451.js +1087 -0
- package/dist/bounded-cache.d.ts +1 -0
- package/dist/build-manifest.d.ts +1 -1
- package/dist/build-output-transforms.d.ts +30 -0
- package/dist/concurrency.d.ts +2 -0
- package/dist/config-imports.d.ts +3 -0
- package/dist/constants.d.ts +3 -0
- package/dist/dev-generation.d.ts +25 -0
- package/dist/dev-runtime-artifacts.d.ts +39 -0
- package/dist/dev-runtime-compilation.d.ts +32 -0
- package/dist/dev-runtime-controller.d.ts +14 -0
- package/dist/dev-runtime-session.d.ts +34 -0
- package/dist/dev-server.d.ts +11 -2
- package/dist/export-utils.d.ts +15 -7
- package/dist/index.cjs +3085 -1272
- package/dist/index.d.ts +4 -1
- package/dist/index.js +2039 -1299
- package/dist/lazy-compilation.d.ts +5 -0
- package/dist/manifest.d.ts +32 -9
- package/dist/modify-browser-manifest.d.ts +30 -13
- package/dist/parallel-route-transform-protocol.d.ts +25 -0
- package/dist/parallel-route-transform-worker.d.ts +1 -0
- package/dist/parallel-route-transform-worker.js +38 -0
- package/dist/parallel-route-transforms.d.ts +14 -0
- package/dist/performance.d.ts +26 -0
- package/dist/plugin-utils.d.ts +2 -12
- package/dist/prerender-build.d.ts +32 -0
- package/dist/prerender.d.ts +28 -2
- package/dist/react-router-config.d.ts +8 -1
- package/dist/route-artifacts.d.ts +33 -0
- package/dist/route-ast.d.ts +21 -0
- package/dist/route-chunks.d.ts +9 -1
- package/dist/route-component-transform.d.ts +5 -0
- package/dist/route-export-pruning.d.ts +6 -0
- package/dist/route-export-resolution.d.ts +5 -0
- package/dist/route-transform-tasks.d.ts +47 -0
- package/dist/route-watch.d.ts +27 -0
- package/dist/server-build-plan.d.ts +22 -0
- package/dist/server-utils.d.ts +3 -2
- package/dist/templates/entry.client.js +3 -3
- package/dist/templates/entry.server.cjs +11 -8
- package/dist/templates/entry.server.js +5 -5
- package/dist/typegen.d.ts +2 -0
- package/dist/types.d.ts +30 -12
- package/dist/virtual-modules.d.ts +2 -0
- package/dist/warnings/warn-on-client-source-maps.d.ts +1 -0
- package/dist/yuku.d.ts +15 -0
- package/package.json +26 -22
- package/src/bounded-cache.ts +18 -0
- package/src/build-manifest.ts +168 -0
- package/src/build-output-transforms.ts +273 -0
- package/src/concurrency.ts +34 -0
- package/src/config-imports.ts +45 -0
- package/src/constants.ts +91 -0
- package/src/dev-generation.ts +700 -0
- package/src/dev-runtime-artifacts.ts +207 -0
- package/src/dev-runtime-compilation.ts +92 -0
- package/src/dev-runtime-controller.ts +462 -0
- package/src/dev-runtime-session.ts +184 -0
- package/src/dev-server.ts +58 -0
- package/src/export-utils.ts +219 -0
- package/src/index.ts +1025 -0
- package/src/lazy-compilation.ts +94 -0
- package/src/manifest.ts +480 -0
- package/src/modify-browser-manifest.ts +245 -0
- package/src/parallel-route-transform-protocol.ts +35 -0
- package/src/parallel-route-transform-worker.ts +82 -0
- package/src/parallel-route-transforms.ts +332 -0
- package/src/performance.ts +254 -0
- package/src/plugin-utils.ts +82 -0
- package/src/prerender-build.ts +623 -0
- package/src/prerender.ts +367 -0
- package/src/react-router-config.ts +220 -0
- package/src/route-artifacts.ts +155 -0
- package/src/route-ast.ts +163 -0
- package/src/route-chunks.ts +857 -0
- package/src/route-component-transform.ts +314 -0
- package/src/route-config.ts +106 -0
- package/src/route-export-pruning.ts +668 -0
- package/src/route-export-resolution.ts +329 -0
- package/src/route-transform-tasks.ts +249 -0
- package/src/route-watch.ts +322 -0
- package/src/server-build-plan.ts +91 -0
- package/src/server-utils.ts +210 -0
- package/src/ssr-externals.ts +59 -0
- package/src/templates/context.ts +12 -0
- package/src/templates/entry.client.tsx +12 -0
- package/src/templates/entry.server.tsx +76 -0
- package/src/typegen.ts +49 -0
- package/src/types.ts +82 -0
- package/src/validation/validate-plugin-order.ts +76 -0
- package/src/virtual-modules.ts +30 -0
- package/src/warnings/warn-on-client-source-maps.ts +96 -0
- package/src/yuku.ts +67 -0
- package/dist/906.js +0 -1
- package/dist/946.js +0 -1
- package/dist/babel.d.ts +0 -8
- package/dist/rslib-runtime.js +0 -23
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { isAbsolute, relative } from 'node:path';
|
|
2
|
+
import type { RsbuildDevServer, Rspack } from '@rsbuild/core';
|
|
3
|
+
import type { ServerBuild } from 'react-router';
|
|
4
|
+
import type { ReactRouterManifestForDev } from './manifest.js';
|
|
5
|
+
import { resolveServerBuildModule } from './server-utils.js';
|
|
6
|
+
|
|
7
|
+
export type ReactRouterDevManifest = ReactRouterManifestForDev;
|
|
8
|
+
|
|
9
|
+
export type ReactRouterDevBuildPlan = {
|
|
10
|
+
defaultEntryName: string;
|
|
11
|
+
entryNames: readonly string[];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type ReactRouterDevManifestSet = Readonly<
|
|
15
|
+
Record<string, ReactRouterDevManifest>
|
|
16
|
+
>;
|
|
17
|
+
|
|
18
|
+
export type ReactRouterServerBuilds = Readonly<Record<string, ServerBuild>>;
|
|
19
|
+
|
|
20
|
+
export type DependencySnapshot = {
|
|
21
|
+
files: ReadonlySet<string>;
|
|
22
|
+
contexts: ReadonlySet<string>;
|
|
23
|
+
missing: ReadonlySet<string>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type DevChangedFiles = {
|
|
27
|
+
known: boolean;
|
|
28
|
+
files: ReadonlySet<string>;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type DevGraphChanges = {
|
|
32
|
+
web: DevChangedFiles;
|
|
33
|
+
node: DevChangedFiles;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export type DevCompilationIdentity = symbol;
|
|
37
|
+
|
|
38
|
+
export type DevGraphIdentity = {
|
|
39
|
+
web: DevCompilationIdentity | undefined;
|
|
40
|
+
node: DevCompilationIdentity | undefined;
|
|
41
|
+
nodeWeb: DevCompilationIdentity | undefined;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type WebArtifact = {
|
|
45
|
+
manifestsByEntryName: ReactRouterDevManifestSet;
|
|
46
|
+
dependencies: DependencySnapshot;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const snapshotDevChangedFiles = (
|
|
50
|
+
compiler: Pick<Rspack.Compiler, 'modifiedFiles' | 'removedFiles'> | undefined
|
|
51
|
+
): DevChangedFiles => {
|
|
52
|
+
if (!compiler) {
|
|
53
|
+
return { known: false, files: new Set() };
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
known:
|
|
57
|
+
compiler.modifiedFiles !== undefined ||
|
|
58
|
+
compiler.removedFiles !== undefined,
|
|
59
|
+
files: new Set([
|
|
60
|
+
...(compiler.modifiedFiles ?? []),
|
|
61
|
+
...(compiler.removedFiles ?? []),
|
|
62
|
+
]),
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export const snapshotDependencies = (
|
|
67
|
+
compilation: Rspack.Compilation
|
|
68
|
+
): DependencySnapshot => ({
|
|
69
|
+
files: new Set([
|
|
70
|
+
...compilation.fileDependencies,
|
|
71
|
+
...(compilation.buildDependencies ?? []),
|
|
72
|
+
]),
|
|
73
|
+
contexts: new Set(compilation.contextDependencies),
|
|
74
|
+
missing: new Set(compilation.missingDependencies),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
const isWithinDirectory = (directory: string, file: string): boolean => {
|
|
78
|
+
const relativePath = relative(directory, file);
|
|
79
|
+
return (
|
|
80
|
+
relativePath === '' ||
|
|
81
|
+
(!relativePath.startsWith('..') && !isAbsolute(relativePath))
|
|
82
|
+
);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
export const isSafeOneSidedChange = (
|
|
86
|
+
changes: DevChangedFiles,
|
|
87
|
+
dependencies: DependencySnapshot
|
|
88
|
+
): boolean => {
|
|
89
|
+
if (!changes.known || changes.files.size === 0) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
for (const file of changes.files) {
|
|
93
|
+
if (dependencies.files.has(file) || dependencies.missing.has(file)) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
for (const directory of dependencies.contexts) {
|
|
97
|
+
if (isWithinDirectory(directory, file)) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return true;
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
export const getEnvironmentStats = (
|
|
106
|
+
stats: Rspack.Stats | Rspack.MultiStats,
|
|
107
|
+
name: 'web' | 'node'
|
|
108
|
+
): Rspack.Stats | undefined => {
|
|
109
|
+
const children = Array.isArray((stats as Rspack.MultiStats).stats)
|
|
110
|
+
? (stats as Rspack.MultiStats).stats
|
|
111
|
+
: [stats as Rspack.Stats];
|
|
112
|
+
return children.find(child => {
|
|
113
|
+
const compilation = child.compilation;
|
|
114
|
+
return compilation.name === name || compilation.compiler?.name === name;
|
|
115
|
+
});
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
const evaluateServerBuild = async (
|
|
119
|
+
server: RsbuildDevServer,
|
|
120
|
+
entryName: string
|
|
121
|
+
): Promise<ServerBuild> => {
|
|
122
|
+
const loaded = await server.environments.node.loadBundle(entryName);
|
|
123
|
+
return resolveServerBuildModule(
|
|
124
|
+
loaded,
|
|
125
|
+
`Server entry ${JSON.stringify(entryName)}`
|
|
126
|
+
);
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export const evaluateServerBuilds = async (
|
|
130
|
+
server: RsbuildDevServer,
|
|
131
|
+
entryNames: readonly string[]
|
|
132
|
+
): Promise<ReactRouterServerBuilds> => {
|
|
133
|
+
const evaluated = await Promise.all(
|
|
134
|
+
entryNames.map(async entryName => [
|
|
135
|
+
entryName,
|
|
136
|
+
await evaluateServerBuild(server, entryName),
|
|
137
|
+
])
|
|
138
|
+
);
|
|
139
|
+
return Object.fromEntries(evaluated) as Record<string, ServerBuild>;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const assertBuildMatchesManifest = (
|
|
143
|
+
entryName: string,
|
|
144
|
+
build: ServerBuild,
|
|
145
|
+
manifest: ReactRouterDevManifest
|
|
146
|
+
): void => {
|
|
147
|
+
for (const [routeId, manifestRoute] of Object.entries(manifest.routes)) {
|
|
148
|
+
const routeModule = build.routes[routeId]?.module;
|
|
149
|
+
if (!routeModule) {
|
|
150
|
+
throw new Error(
|
|
151
|
+
`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} route ${JSON.stringify(routeId)} is missing from the evaluated server build.`
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
if (
|
|
155
|
+
Boolean(manifestRoute.hasLoader) !==
|
|
156
|
+
(typeof routeModule.loader === 'function')
|
|
157
|
+
) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} route ${JSON.stringify(routeId)} loader export does not match its web manifest.`
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
if (
|
|
163
|
+
Boolean(manifestRoute.hasAction) !==
|
|
164
|
+
(typeof routeModule.action === 'function')
|
|
165
|
+
) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} route ${JSON.stringify(routeId)} action export does not match its web manifest.`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const pinBuildToManifest = (
|
|
174
|
+
entryName: string,
|
|
175
|
+
build: ServerBuild,
|
|
176
|
+
manifest: ReactRouterDevManifest
|
|
177
|
+
): ServerBuild => {
|
|
178
|
+
assertBuildMatchesManifest(entryName, build, manifest);
|
|
179
|
+
return {
|
|
180
|
+
...build,
|
|
181
|
+
assets: structuredClone(manifest) as ServerBuild['assets'],
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
export const pinServerBuildsToManifests = (
|
|
186
|
+
builds: ReactRouterServerBuilds,
|
|
187
|
+
entryNames: readonly string[],
|
|
188
|
+
manifestsByEntryName: ReactRouterDevManifestSet
|
|
189
|
+
): ReactRouterServerBuilds => {
|
|
190
|
+
const pinned: Record<string, ServerBuild> = {};
|
|
191
|
+
for (const entryName of entryNames) {
|
|
192
|
+
const build = builds[entryName];
|
|
193
|
+
if (!build) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`[rsbuild-plugin-react-router] Expected server build ${JSON.stringify(entryName)} was not evaluated.`
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
const manifest = manifestsByEntryName[entryName];
|
|
199
|
+
if (!manifest) {
|
|
200
|
+
throw new Error(
|
|
201
|
+
`[rsbuild-plugin-react-router] Server build ${JSON.stringify(entryName)} has no matching web manifest.`
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
pinned[entryName] = pinBuildToManifest(entryName, build, manifest);
|
|
205
|
+
}
|
|
206
|
+
return pinned;
|
|
207
|
+
};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { Rspack } from '@rsbuild/core';
|
|
2
|
+
import type {
|
|
3
|
+
DevCompilationIdentity,
|
|
4
|
+
DevGraphChanges,
|
|
5
|
+
DevGraphIdentity,
|
|
6
|
+
} from './dev-runtime-artifacts.js';
|
|
7
|
+
|
|
8
|
+
export type DevCompilerPair = {
|
|
9
|
+
web: Rspack.Compiler;
|
|
10
|
+
node: Rspack.Compiler;
|
|
11
|
+
settledCompilations: WeakSet<Rspack.Compilation>;
|
|
12
|
+
pendingAttempt?: PendingDevCompilation;
|
|
13
|
+
latestCompletedWebIdentity?: DevCompilationIdentity;
|
|
14
|
+
latestWebStart?: CompilationStart;
|
|
15
|
+
latestNodeStart?: CompilationStart;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export type PendingDevCompilation = {
|
|
19
|
+
stats: Rspack.Stats | Rspack.MultiStats;
|
|
20
|
+
changes: DevGraphChanges;
|
|
21
|
+
identity: DevGraphIdentity;
|
|
22
|
+
webCompilation: Rspack.Compilation;
|
|
23
|
+
nodeCompilation: Rspack.Compilation;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type CompilationStart =
|
|
27
|
+
| { status: 'pending' }
|
|
28
|
+
| { status: 'started'; identity: DevCompilationIdentity };
|
|
29
|
+
|
|
30
|
+
export const isLatestStartedCompilation = (
|
|
31
|
+
identity: DevCompilationIdentity | undefined,
|
|
32
|
+
start: CompilationStart | undefined
|
|
33
|
+
): boolean =>
|
|
34
|
+
!identity || (start?.status === 'started' && start.identity === identity);
|
|
35
|
+
|
|
36
|
+
export const hasPendingCompilation = (pair: DevCompilerPair): boolean =>
|
|
37
|
+
pair.latestWebStart?.status === 'pending' ||
|
|
38
|
+
pair.latestNodeStart?.status === 'pending';
|
|
39
|
+
|
|
40
|
+
export type CompilationIdentityTracker = {
|
|
41
|
+
getCompilationIdentity(
|
|
42
|
+
compilation: Rspack.Compilation
|
|
43
|
+
): DevCompilationIdentity;
|
|
44
|
+
getWebIdentityForNodeCompilation(
|
|
45
|
+
compilation: Rspack.Compilation
|
|
46
|
+
): DevCompilationIdentity | undefined;
|
|
47
|
+
setWebIdentityForNodeCompilation(
|
|
48
|
+
compilation: Rspack.Compilation,
|
|
49
|
+
identity: DevCompilationIdentity
|
|
50
|
+
): void;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const createCompilationIdentityTracker =
|
|
54
|
+
(): CompilationIdentityTracker => {
|
|
55
|
+
const identityByCompilation = new WeakMap<
|
|
56
|
+
Rspack.Compilation,
|
|
57
|
+
DevCompilationIdentity
|
|
58
|
+
>();
|
|
59
|
+
const webIdentityByNodeCompilation = new WeakMap<
|
|
60
|
+
Rspack.Compilation,
|
|
61
|
+
DevCompilationIdentity
|
|
62
|
+
>();
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
getCompilationIdentity(
|
|
66
|
+
compilation: Rspack.Compilation
|
|
67
|
+
): DevCompilationIdentity {
|
|
68
|
+
const existing = identityByCompilation.get(compilation);
|
|
69
|
+
if (existing) {
|
|
70
|
+
return existing;
|
|
71
|
+
}
|
|
72
|
+
const identity = Symbol();
|
|
73
|
+
// Keep compact lineage tokens in committed state without retaining entire
|
|
74
|
+
// Rspack compilation graphs across failed rebuilds.
|
|
75
|
+
identityByCompilation.set(compilation, identity);
|
|
76
|
+
return identity;
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
getWebIdentityForNodeCompilation(
|
|
80
|
+
compilation: Rspack.Compilation
|
|
81
|
+
): DevCompilationIdentity | undefined {
|
|
82
|
+
return webIdentityByNodeCompilation.get(compilation);
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
setWebIdentityForNodeCompilation(
|
|
86
|
+
compilation: Rspack.Compilation,
|
|
87
|
+
identity: DevCompilationIdentity
|
|
88
|
+
): void {
|
|
89
|
+
webIdentityByNodeCompilation.set(compilation, identity);
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
};
|