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,155 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CLIENT_ROUTE_EXPORTS_SET,
|
|
3
|
+
SERVER_ONLY_ROUTE_EXPORTS_SET,
|
|
4
|
+
} from './constants.js';
|
|
5
|
+
import { getExportNames } from './export-utils.js';
|
|
6
|
+
import {
|
|
7
|
+
buildEnforceChunkValidity,
|
|
8
|
+
detectRouteChunksIfEnabled,
|
|
9
|
+
emptyRouteChunkSnippet,
|
|
10
|
+
getRouteChunkIfEnabled,
|
|
11
|
+
getRouteChunkNameFromModuleId,
|
|
12
|
+
shouldAnalyzeRouteChunks,
|
|
13
|
+
validateRouteChunks,
|
|
14
|
+
type RouteChunkCache,
|
|
15
|
+
type RouteChunkConfig,
|
|
16
|
+
} from './route-chunks.js';
|
|
17
|
+
|
|
18
|
+
export type RouteClientEntryArtifactOptions = {
|
|
19
|
+
code: string;
|
|
20
|
+
resourcePath: string;
|
|
21
|
+
environmentName?: string;
|
|
22
|
+
isBuild: boolean;
|
|
23
|
+
routeChunkCache?: RouteChunkCache;
|
|
24
|
+
routeChunkConfig: RouteChunkConfig;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
type RouteClientEntryArtifact = {
|
|
28
|
+
code: string;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type RouteChunkArtifactOptions = {
|
|
32
|
+
code: string;
|
|
33
|
+
resource: string;
|
|
34
|
+
resourcePath: string;
|
|
35
|
+
isBuild: boolean;
|
|
36
|
+
routeChunkCache?: RouteChunkCache;
|
|
37
|
+
routeChunkConfig: RouteChunkConfig;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
type RouteChunkArtifact = {
|
|
41
|
+
code: string;
|
|
42
|
+
map: null;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export const buildRouteClientEntryCode = ({
|
|
46
|
+
exportNames,
|
|
47
|
+
chunkedExports,
|
|
48
|
+
isServer,
|
|
49
|
+
resourcePath,
|
|
50
|
+
}: {
|
|
51
|
+
exportNames: readonly string[];
|
|
52
|
+
chunkedExports: readonly string[];
|
|
53
|
+
isServer: boolean;
|
|
54
|
+
resourcePath: string;
|
|
55
|
+
}): string => {
|
|
56
|
+
const chunkedExportSet =
|
|
57
|
+
chunkedExports.length > 0 ? new Set<string>(chunkedExports) : undefined;
|
|
58
|
+
const reexports = exportNames
|
|
59
|
+
.filter(exp => {
|
|
60
|
+
if (chunkedExportSet?.has(exp)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
return (
|
|
64
|
+
CLIENT_ROUTE_EXPORTS_SET.has(exp) ||
|
|
65
|
+
(isServer && SERVER_ONLY_ROUTE_EXPORTS_SET.has(exp))
|
|
66
|
+
);
|
|
67
|
+
})
|
|
68
|
+
.sort();
|
|
69
|
+
const target = `${resourcePath}?react-router-route`;
|
|
70
|
+
return `export { ${reexports.join(', ')} } from ${JSON.stringify(target)};`;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export const createRouteClientEntryArtifact = async ({
|
|
74
|
+
code,
|
|
75
|
+
resourcePath,
|
|
76
|
+
environmentName,
|
|
77
|
+
isBuild,
|
|
78
|
+
routeChunkCache,
|
|
79
|
+
routeChunkConfig,
|
|
80
|
+
}: RouteClientEntryArtifactOptions): Promise<RouteClientEntryArtifact> => {
|
|
81
|
+
const isServer = environmentName === 'node';
|
|
82
|
+
const mightHaveRouteChunks =
|
|
83
|
+
!isServer &&
|
|
84
|
+
isBuild &&
|
|
85
|
+
shouldAnalyzeRouteChunks(routeChunkConfig, resourcePath, code);
|
|
86
|
+
const routeChunkInfo = mightHaveRouteChunks
|
|
87
|
+
? await detectRouteChunksIfEnabled(
|
|
88
|
+
routeChunkCache,
|
|
89
|
+
routeChunkConfig,
|
|
90
|
+
resourcePath,
|
|
91
|
+
code
|
|
92
|
+
)
|
|
93
|
+
: null;
|
|
94
|
+
const exportNames =
|
|
95
|
+
routeChunkInfo?.exportNames ?? (await getExportNames(code));
|
|
96
|
+
const chunkedExports = routeChunkInfo?.chunkedExports ?? [];
|
|
97
|
+
return {
|
|
98
|
+
code: buildRouteClientEntryCode({
|
|
99
|
+
exportNames,
|
|
100
|
+
chunkedExports,
|
|
101
|
+
isServer,
|
|
102
|
+
resourcePath,
|
|
103
|
+
}),
|
|
104
|
+
};
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export const createRouteChunkArtifact = async ({
|
|
108
|
+
code,
|
|
109
|
+
resource,
|
|
110
|
+
resourcePath,
|
|
111
|
+
isBuild,
|
|
112
|
+
routeChunkCache,
|
|
113
|
+
routeChunkConfig,
|
|
114
|
+
}: RouteChunkArtifactOptions): Promise<RouteChunkArtifact> => {
|
|
115
|
+
const splitRouteModules = routeChunkConfig.splitRouteModules;
|
|
116
|
+
if (!isBuild || !splitRouteModules) {
|
|
117
|
+
return {
|
|
118
|
+
code: emptyRouteChunkSnippet(),
|
|
119
|
+
map: null,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const chunkName = getRouteChunkNameFromModuleId(resource);
|
|
124
|
+
if (!chunkName) {
|
|
125
|
+
throw new Error(`Invalid route chunk name in "${resource}"`);
|
|
126
|
+
}
|
|
127
|
+
if (chunkName !== 'main' && !code.includes(chunkName)) {
|
|
128
|
+
return {
|
|
129
|
+
code: emptyRouteChunkSnippet(),
|
|
130
|
+
map: null,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const chunk = await getRouteChunkIfEnabled(
|
|
135
|
+
routeChunkCache,
|
|
136
|
+
routeChunkConfig,
|
|
137
|
+
resourcePath,
|
|
138
|
+
chunkName,
|
|
139
|
+
code
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
if (splitRouteModules === 'enforce' && chunkName === 'main' && chunk) {
|
|
143
|
+
const exportNames = await getExportNames(chunk);
|
|
144
|
+
validateRouteChunks({
|
|
145
|
+
config: routeChunkConfig,
|
|
146
|
+
id: resourcePath,
|
|
147
|
+
valid: buildEnforceChunkValidity(exportNames),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
code: chunk ?? emptyRouteChunkSnippet(),
|
|
153
|
+
map: null,
|
|
154
|
+
};
|
|
155
|
+
};
|
package/src/route-ast.ts
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { ParseResult } from 'yuku-parser';
|
|
2
|
+
|
|
3
|
+
export type AnyNode = Record<string, any>;
|
|
4
|
+
|
|
5
|
+
export type ProgramNode = AnyNode & {
|
|
6
|
+
body: AnyNode[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const getProgram = (ast: ParseResult | AnyNode): ProgramNode =>
|
|
10
|
+
((ast as ParseResult).program ?? ast) as ProgramNode;
|
|
11
|
+
|
|
12
|
+
export const getPatternIdentifierNames = (
|
|
13
|
+
pattern: AnyNode | null | undefined,
|
|
14
|
+
names: Set<string> = new Set()
|
|
15
|
+
): Set<string> => {
|
|
16
|
+
if (!pattern) {
|
|
17
|
+
return names;
|
|
18
|
+
}
|
|
19
|
+
if (pattern.type === 'Identifier') {
|
|
20
|
+
names.add(pattern.name);
|
|
21
|
+
return names;
|
|
22
|
+
}
|
|
23
|
+
if (pattern.type === 'RestElement') {
|
|
24
|
+
return getPatternIdentifierNames(pattern.argument, names);
|
|
25
|
+
}
|
|
26
|
+
if (pattern.type === 'AssignmentPattern') {
|
|
27
|
+
return getPatternIdentifierNames(pattern.left, names);
|
|
28
|
+
}
|
|
29
|
+
if (pattern.type === 'ArrayPattern') {
|
|
30
|
+
for (const element of pattern.elements ?? []) {
|
|
31
|
+
getPatternIdentifierNames(element, names);
|
|
32
|
+
}
|
|
33
|
+
return names;
|
|
34
|
+
}
|
|
35
|
+
if (pattern.type === 'ObjectPattern') {
|
|
36
|
+
for (const property of pattern.properties ?? []) {
|
|
37
|
+
if (property.type === 'RestElement') {
|
|
38
|
+
getPatternIdentifierNames(property.argument, names);
|
|
39
|
+
} else {
|
|
40
|
+
getPatternIdentifierNames(property.value, names);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return names;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export const getIdentifierNamesFromPattern = (
|
|
48
|
+
pattern: AnyNode | null | undefined
|
|
49
|
+
): string[] => Array.from(getPatternIdentifierNames(pattern));
|
|
50
|
+
|
|
51
|
+
export const patternIncludesName = (
|
|
52
|
+
pattern: AnyNode | null | undefined,
|
|
53
|
+
name: string
|
|
54
|
+
): boolean => getPatternIdentifierNames(pattern).has(name);
|
|
55
|
+
|
|
56
|
+
export const getExportedName = (
|
|
57
|
+
node: AnyNode | null | undefined
|
|
58
|
+
): string | null => {
|
|
59
|
+
const exported = node?.exported ?? node;
|
|
60
|
+
if (!exported) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
if (exported.type === 'Identifier') {
|
|
64
|
+
return exported.name;
|
|
65
|
+
}
|
|
66
|
+
if (exported.type === 'Literal' || exported.type === 'StringLiteral') {
|
|
67
|
+
return String(exported.value);
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export const identifier = (name: string): AnyNode => ({
|
|
73
|
+
type: 'Identifier',
|
|
74
|
+
start: 0,
|
|
75
|
+
end: 0,
|
|
76
|
+
name,
|
|
77
|
+
decorators: [],
|
|
78
|
+
optional: false,
|
|
79
|
+
typeAnnotation: null,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
export const literal = (value: string): AnyNode => ({
|
|
83
|
+
type: 'Literal',
|
|
84
|
+
start: 0,
|
|
85
|
+
end: 0,
|
|
86
|
+
value,
|
|
87
|
+
raw: JSON.stringify(value),
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
export const callExpression = (callee: AnyNode, args: AnyNode[]): AnyNode => ({
|
|
91
|
+
type: 'CallExpression',
|
|
92
|
+
start: 0,
|
|
93
|
+
end: 0,
|
|
94
|
+
callee,
|
|
95
|
+
arguments: args,
|
|
96
|
+
optional: false,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
export const importDeclaration = (
|
|
100
|
+
specifiers: Array<{ local: string; imported: string }>,
|
|
101
|
+
source: string
|
|
102
|
+
): AnyNode => ({
|
|
103
|
+
type: 'ImportDeclaration',
|
|
104
|
+
start: 0,
|
|
105
|
+
end: 0,
|
|
106
|
+
specifiers: specifiers.map(specifier => ({
|
|
107
|
+
type: 'ImportSpecifier',
|
|
108
|
+
start: 0,
|
|
109
|
+
end: 0,
|
|
110
|
+
imported: identifier(specifier.imported),
|
|
111
|
+
local: identifier(specifier.local),
|
|
112
|
+
importKind: 'value',
|
|
113
|
+
})),
|
|
114
|
+
source: literal(source),
|
|
115
|
+
attributes: [],
|
|
116
|
+
phase: null,
|
|
117
|
+
importKind: 'value',
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
export const exportSpecifier = (local: string, exported: string): AnyNode => ({
|
|
121
|
+
type: 'ExportSpecifier',
|
|
122
|
+
start: 0,
|
|
123
|
+
end: 0,
|
|
124
|
+
local: identifier(local),
|
|
125
|
+
exported: identifier(exported),
|
|
126
|
+
exportKind: 'value',
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
export const exportNamedDeclaration = (specifiers: AnyNode[]): AnyNode => ({
|
|
130
|
+
type: 'ExportNamedDeclaration',
|
|
131
|
+
start: 0,
|
|
132
|
+
end: 0,
|
|
133
|
+
declaration: null,
|
|
134
|
+
specifiers,
|
|
135
|
+
source: null,
|
|
136
|
+
attributes: [],
|
|
137
|
+
exportKind: 'value',
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
export const variableDeclaration = (name: string, init: AnyNode): AnyNode => ({
|
|
141
|
+
type: 'VariableDeclaration',
|
|
142
|
+
start: 0,
|
|
143
|
+
end: 0,
|
|
144
|
+
kind: 'const',
|
|
145
|
+
declare: false,
|
|
146
|
+
declarations: [
|
|
147
|
+
{
|
|
148
|
+
type: 'VariableDeclarator',
|
|
149
|
+
start: 0,
|
|
150
|
+
end: 0,
|
|
151
|
+
id: identifier(name),
|
|
152
|
+
init,
|
|
153
|
+
definite: false,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
export const removeFromArray = <T>(array: T[], value: T): void => {
|
|
159
|
+
const index = array.indexOf(value);
|
|
160
|
+
if (index >= 0) {
|
|
161
|
+
array.splice(index, 1);
|
|
162
|
+
}
|
|
163
|
+
};
|