@reckona/mreact-router 0.0.157 → 0.0.159
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 +1 -1
- package/dist/build.d.ts +3 -1
- package/dist/build.d.ts.map +1 -1
- package/dist/build.js +141 -81
- package/dist/build.js.map +1 -1
- package/dist/import-policy.d.ts +1 -0
- package/dist/import-policy.d.ts.map +1 -1
- package/dist/import-policy.js +6 -4
- package/dist/import-policy.js.map +1 -1
- package/dist/render.d.ts +1 -0
- package/dist/render.d.ts.map +1 -1
- package/dist/render.js +1 -0
- package/dist/render.js.map +1 -1
- package/package.json +11 -11
- package/src/build.ts +198 -81
- package/src/import-policy.ts +7 -4
- package/src/render.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reckona/mreact-router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.159",
|
|
4
4
|
"description": "File-system app router, SSR, actions, and deployment adapters for mreact.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jsx",
|
|
@@ -105,20 +105,20 @@
|
|
|
105
105
|
},
|
|
106
106
|
"dependencies": {
|
|
107
107
|
"typescript": "^6.0.3",
|
|
108
|
-
"@reckona/mreact
|
|
109
|
-
"@reckona/mreact-
|
|
110
|
-
"@reckona/mreact-
|
|
111
|
-
"@reckona/mreact-
|
|
112
|
-
"@reckona/mreact-
|
|
113
|
-
"@reckona/mreact": "0.0.
|
|
114
|
-
"@reckona/mreact-reactive-dom": "0.0.
|
|
115
|
-
"@reckona/mreact-server": "0.0.
|
|
116
|
-
"@reckona/mreact-shared": "0.0.
|
|
108
|
+
"@reckona/mreact": "0.0.159",
|
|
109
|
+
"@reckona/mreact-compat": "0.0.159",
|
|
110
|
+
"@reckona/mreact-compiler": "0.0.159",
|
|
111
|
+
"@reckona/mreact-query": "0.0.159",
|
|
112
|
+
"@reckona/mreact-reactive-core": "0.0.159",
|
|
113
|
+
"@reckona/mreact-devtools": "0.0.159",
|
|
114
|
+
"@reckona/mreact-reactive-dom": "0.0.159",
|
|
115
|
+
"@reckona/mreact-server": "0.0.159",
|
|
116
|
+
"@reckona/mreact-shared": "0.0.159"
|
|
117
117
|
},
|
|
118
118
|
"peerDependencies": {
|
|
119
119
|
"vite": ">=8 <9"
|
|
120
120
|
},
|
|
121
121
|
"optionalDependencies": {
|
|
122
|
-
"@reckona/mreact-router-native": "0.0.
|
|
122
|
+
"@reckona/mreact-router-native": "0.0.159"
|
|
123
123
|
}
|
|
124
124
|
}
|
package/src/build.ts
CHANGED
|
@@ -85,6 +85,7 @@ import {
|
|
|
85
85
|
bundleRouterModules,
|
|
86
86
|
type RouterCompatPlugin,
|
|
87
87
|
type RouterBundleChunkOutput,
|
|
88
|
+
type RouterBundleModulesOutput,
|
|
88
89
|
type RouterBundleOutput,
|
|
89
90
|
} from "./bundle-pipeline.js";
|
|
90
91
|
import { collectRouteCssFilesFromSources, collectSpecialBoundaryFiles } from "./route-styles.js";
|
|
@@ -448,7 +449,7 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
|
|
|
448
449
|
);
|
|
449
450
|
|
|
450
451
|
const clientRouteInferenceCache = createClientRouteInferenceCache();
|
|
451
|
-
const [serverActionManifest,
|
|
452
|
+
const [serverActionManifest, generatedImportPolicy] = await Promise.all([
|
|
452
453
|
shouldTrackBuildPhases === false
|
|
453
454
|
? collectBuildServerActionManifest({
|
|
454
455
|
files,
|
|
@@ -464,8 +465,32 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
|
|
|
464
465
|
routesDir: project.routesDir,
|
|
465
466
|
}),
|
|
466
467
|
),
|
|
468
|
+
shouldTrackBuildPhases === false
|
|
469
|
+
? buildGeneratedImportPolicy({
|
|
470
|
+
files,
|
|
471
|
+
projectRoot: project.projectRoot,
|
|
472
|
+
routes,
|
|
473
|
+
routesDir: project.routesDir,
|
|
474
|
+
})
|
|
475
|
+
: timeBuildPhase(timingSink, progressSink, "importPolicy", () =>
|
|
476
|
+
buildGeneratedImportPolicy({
|
|
477
|
+
files,
|
|
478
|
+
projectRoot: project.projectRoot,
|
|
479
|
+
routes,
|
|
480
|
+
routesDir: project.routesDir,
|
|
481
|
+
}),
|
|
482
|
+
),
|
|
483
|
+
]);
|
|
484
|
+
const actionRenderBundleExcludedFiles = new Set(
|
|
485
|
+
[...serverActionManifest.routeReferences.entries()]
|
|
486
|
+
.filter(([, references]) => references.length > 0)
|
|
487
|
+
.map(([file]) => file),
|
|
488
|
+
);
|
|
489
|
+
const { artifacts: serverModules, sharedChunks: serverModuleSharedChunks } = await (
|
|
467
490
|
shouldTrackBuildPhases === false
|
|
468
491
|
? buildServerModuleArtifacts({
|
|
492
|
+
actionRenderBundleExcludedFiles,
|
|
493
|
+
bundleRequestRuntimePackages: shouldBuildAwsLambda,
|
|
469
494
|
bundleCache: new Map(),
|
|
470
495
|
clientRouteInferenceCache: serverClientRouteInferenceCache,
|
|
471
496
|
define: viteDefine,
|
|
@@ -480,6 +505,8 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
|
|
|
480
505
|
})
|
|
481
506
|
: timeBuildPhase(timingSink, progressSink, "serverModules", () =>
|
|
482
507
|
buildServerModuleArtifacts({
|
|
508
|
+
actionRenderBundleExcludedFiles,
|
|
509
|
+
bundleRequestRuntimePackages: shouldBuildAwsLambda,
|
|
483
510
|
bundleCache: new Map(),
|
|
484
511
|
clientRouteInferenceCache: serverClientRouteInferenceCache,
|
|
485
512
|
define: viteDefine,
|
|
@@ -492,23 +519,8 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
|
|
|
492
519
|
serverTransformCache,
|
|
493
520
|
vitePlugins,
|
|
494
521
|
}),
|
|
495
|
-
)
|
|
496
|
-
|
|
497
|
-
? buildGeneratedImportPolicy({
|
|
498
|
-
files,
|
|
499
|
-
projectRoot: project.projectRoot,
|
|
500
|
-
routes,
|
|
501
|
-
routesDir: project.routesDir,
|
|
502
|
-
})
|
|
503
|
-
: timeBuildPhase(timingSink, progressSink, "importPolicy", () =>
|
|
504
|
-
buildGeneratedImportPolicy({
|
|
505
|
-
files,
|
|
506
|
-
projectRoot: project.projectRoot,
|
|
507
|
-
routes,
|
|
508
|
-
routesDir: project.routesDir,
|
|
509
|
-
}),
|
|
510
|
-
),
|
|
511
|
-
]);
|
|
522
|
+
)
|
|
523
|
+
);
|
|
512
524
|
const serverRoutes = routes.map((route) => ({
|
|
513
525
|
...route,
|
|
514
526
|
file: relative(project.projectRoot, route.file),
|
|
@@ -519,12 +531,14 @@ export async function buildApp(options: BuildAppOptions): Promise<BuildAppResult
|
|
|
519
531
|
serverDir,
|
|
520
532
|
serverModules,
|
|
521
533
|
generatedImportPolicy.runtimePackages,
|
|
534
|
+
serverModuleSharedChunks,
|
|
522
535
|
)
|
|
523
536
|
: timeBuildPhase(timingSink, progressSink, "serverModuleArtifacts", () =>
|
|
524
537
|
writeServerModuleArtifactFiles(
|
|
525
538
|
serverDir,
|
|
526
539
|
serverModules,
|
|
527
540
|
generatedImportPolicy.runtimePackages,
|
|
541
|
+
serverModuleSharedChunks,
|
|
528
542
|
),
|
|
529
543
|
),
|
|
530
544
|
shouldTrackBuildPhases === false
|
|
@@ -1043,6 +1057,7 @@ async function writeServerModuleArtifactFiles(
|
|
|
1043
1057
|
serverDir: string,
|
|
1044
1058
|
serverModules: Record<string, BuiltServerModuleArtifact>,
|
|
1045
1059
|
portableRuntimePackages: readonly string[] = [],
|
|
1060
|
+
sharedChunks: readonly SharedServerModuleChunk[] = [],
|
|
1046
1061
|
): Promise<{
|
|
1047
1062
|
files: Record<string, string>;
|
|
1048
1063
|
renderFiles: Record<string, string>;
|
|
@@ -1064,6 +1079,22 @@ async function writeServerModuleArtifactFiles(
|
|
|
1064
1079
|
mkdir(join(modulesDir, "render"), { recursive: true }),
|
|
1065
1080
|
]);
|
|
1066
1081
|
|
|
1082
|
+
if (sharedChunks.length > 0) {
|
|
1083
|
+
// Shared request chunks are referenced from externalized module code via
|
|
1084
|
+
// "./chunks/..." imports, so they live next to server-modules/code files.
|
|
1085
|
+
await mkdir(join(modulesDir, "code", "chunks"), { recursive: true });
|
|
1086
|
+
await Promise.all(
|
|
1087
|
+
sharedChunks.map((chunk) =>
|
|
1088
|
+
writeFile(
|
|
1089
|
+
join(modulesDir, "code", chunk.fileName),
|
|
1090
|
+
rewriteCompatVendorPlaceholderImports(
|
|
1091
|
+
rewritePortableRuntimePackageImports(chunk.code, portableRuntimePackages),
|
|
1092
|
+
),
|
|
1093
|
+
),
|
|
1094
|
+
),
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1067
1098
|
const usedCompatVendorEntries = collectCompatVendorEntryUsage(artifactEntries);
|
|
1068
1099
|
|
|
1069
1100
|
if (usedCompatVendorEntries.size > 0) {
|
|
@@ -1993,6 +2024,8 @@ function routePathFromParams(route: AppRoute, params: StaticParams): string {
|
|
|
1993
2024
|
}
|
|
1994
2025
|
|
|
1995
2026
|
async function buildServerModuleArtifacts(options: {
|
|
2027
|
+
actionRenderBundleExcludedFiles?: ReadonlySet<string> | undefined;
|
|
2028
|
+
bundleRequestRuntimePackages: boolean;
|
|
1996
2029
|
bundleCache: Map<string, Promise<RouterBundleOutput>>;
|
|
1997
2030
|
cacheDir?: string | undefined;
|
|
1998
2031
|
clientRouteInferenceCache: ClientRouteInferenceCache;
|
|
@@ -2005,7 +2038,10 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2005
2038
|
sourceAnalysis: BuildSourceAnalysisScope;
|
|
2006
2039
|
serverTransformCache: ServerTransformCache;
|
|
2007
2040
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
2008
|
-
}): Promise<
|
|
2041
|
+
}): Promise<{
|
|
2042
|
+
artifacts: Record<string, BuiltServerModuleArtifact>;
|
|
2043
|
+
sharedChunks: readonly SharedServerModuleChunk[];
|
|
2044
|
+
}> {
|
|
2009
2045
|
const routeByFile = new Map(
|
|
2010
2046
|
options.routes.map((route) => [relative(options.projectRoot, route.file), route]),
|
|
2011
2047
|
);
|
|
@@ -2069,9 +2105,22 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2069
2105
|
});
|
|
2070
2106
|
}
|
|
2071
2107
|
|
|
2108
|
+
if (isMiddlewareFile(options.project.routesDir, absoluteFile)) {
|
|
2109
|
+
// Middleware joins the batch when runtime packages are bundled so the
|
|
2110
|
+
// auth/control dependency graph is shared with route loader artifacts.
|
|
2111
|
+
if (options.bundleRequestRuntimePackages) {
|
|
2112
|
+
requestBatchEntries.push({
|
|
2113
|
+
code: source,
|
|
2114
|
+
filename: absoluteFile,
|
|
2115
|
+
key: routeRequestArtifactBatchKey(file, "request"),
|
|
2116
|
+
label: "Middleware",
|
|
2117
|
+
});
|
|
2118
|
+
}
|
|
2119
|
+
continue;
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2072
2122
|
if (
|
|
2073
2123
|
requestArtifactFiles.has(file) &&
|
|
2074
|
-
!isMiddlewareFile(options.project.routesDir, absoluteFile) &&
|
|
2075
2124
|
route?.kind !== "server" &&
|
|
2076
2125
|
route?.kind !== "metadata"
|
|
2077
2126
|
) {
|
|
@@ -2084,18 +2133,20 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2084
2133
|
}
|
|
2085
2134
|
}
|
|
2086
2135
|
|
|
2087
|
-
const requestBatchOutputs =
|
|
2088
|
-
requestBatchEntries.length >= 3
|
|
2136
|
+
const { codeByKey: requestBatchOutputs, sharedChunks } =
|
|
2137
|
+
requestBatchEntries.length >= (options.bundleRequestRuntimePackages ? 2 : 3)
|
|
2089
2138
|
? await bundleRouteRequestModuleBatchCode({
|
|
2090
2139
|
appDir: options.project.routesDir,
|
|
2091
2140
|
bundleCache: options.bundleCache,
|
|
2092
2141
|
cacheDir: options.cacheDir,
|
|
2142
|
+
emitSharedChunks: options.bundleRequestRuntimePackages,
|
|
2093
2143
|
entries: requestBatchEntries,
|
|
2144
|
+
externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
|
|
2094
2145
|
importPolicy: requestModuleImportPolicy,
|
|
2095
2146
|
define: options.define,
|
|
2096
2147
|
vitePlugins: options.vitePlugins,
|
|
2097
2148
|
})
|
|
2098
|
-
: new Map<string, string>();
|
|
2149
|
+
: { codeByKey: new Map<string, string>(), sharedChunks: [] };
|
|
2099
2150
|
|
|
2100
2151
|
const artifactEntries = await mapWithBuildConcurrency(
|
|
2101
2152
|
Object.entries(options.files),
|
|
@@ -2119,6 +2170,7 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2119
2170
|
cacheDir: options.cacheDir,
|
|
2120
2171
|
code: stripRouteLoaderOnlyExports(source, absoluteFile),
|
|
2121
2172
|
filename: absoluteFile,
|
|
2173
|
+
externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
|
|
2122
2174
|
importPolicy: requestModuleImportPolicy,
|
|
2123
2175
|
define: options.define,
|
|
2124
2176
|
vitePlugins: options.vitePlugins,
|
|
@@ -2138,6 +2190,7 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2138
2190
|
cacheDir: options.cacheDir,
|
|
2139
2191
|
code: stripRouteMetadataOnlyExports(source, absoluteFile),
|
|
2140
2192
|
filename: absoluteFile,
|
|
2193
|
+
externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
|
|
2141
2194
|
importPolicy: requestModuleImportPolicy,
|
|
2142
2195
|
label: "Metadata",
|
|
2143
2196
|
define: options.define,
|
|
@@ -2161,6 +2214,7 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2161
2214
|
bundleCache: options.bundleCache,
|
|
2162
2215
|
cacheDir: options.cacheDir,
|
|
2163
2216
|
filename: absoluteFile,
|
|
2217
|
+
externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
|
|
2164
2218
|
importPolicy: requestModuleImportPolicy,
|
|
2165
2219
|
define: options.define,
|
|
2166
2220
|
routeKind: route?.kind,
|
|
@@ -2273,23 +2327,26 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2273
2327
|
return undefined;
|
|
2274
2328
|
}
|
|
2275
2329
|
|
|
2330
|
+
const shouldWriteRenderBundle =
|
|
2331
|
+
options.prebundleServerComponents &&
|
|
2332
|
+
options.actionRenderBundleExcludedFiles?.has(file) !== true;
|
|
2333
|
+
const bundleCode = shouldWriteRenderBundle
|
|
2334
|
+
? await buildServerComponentBundleArtifactCode({
|
|
2335
|
+
clientRouteInferenceCache: options.clientRouteInferenceCache,
|
|
2336
|
+
code: output.code,
|
|
2337
|
+
externalizeCompatVendor,
|
|
2338
|
+
filename: absoluteFile,
|
|
2339
|
+
define: options.define,
|
|
2340
|
+
root: options.projectRoot,
|
|
2341
|
+
serverOutput,
|
|
2342
|
+
vitePlugins: options.vitePlugins,
|
|
2343
|
+
})
|
|
2344
|
+
: undefined;
|
|
2345
|
+
|
|
2276
2346
|
return [
|
|
2277
2347
|
serverOutput,
|
|
2278
2348
|
{
|
|
2279
|
-
...(
|
|
2280
|
-
? {
|
|
2281
|
-
bundleCode: await buildServerComponentBundleArtifactCode({
|
|
2282
|
-
clientRouteInferenceCache: options.clientRouteInferenceCache,
|
|
2283
|
-
code: output.code,
|
|
2284
|
-
externalizeCompatVendor,
|
|
2285
|
-
filename: absoluteFile,
|
|
2286
|
-
define: options.define,
|
|
2287
|
-
root: options.projectRoot,
|
|
2288
|
-
serverOutput,
|
|
2289
|
-
vitePlugins: options.vitePlugins,
|
|
2290
|
-
}),
|
|
2291
|
-
}
|
|
2292
|
-
: {}),
|
|
2349
|
+
...(bundleCode === undefined ? {} : { bundleCode }),
|
|
2293
2350
|
code: output.code,
|
|
2294
2351
|
metadata: output.metadata,
|
|
2295
2352
|
sourceHash: hashText(code),
|
|
@@ -2314,7 +2371,7 @@ async function buildServerModuleArtifacts(options: {
|
|
|
2314
2371
|
}
|
|
2315
2372
|
}
|
|
2316
2373
|
|
|
2317
|
-
return artifacts;
|
|
2374
|
+
return { artifacts, sharedChunks };
|
|
2318
2375
|
}
|
|
2319
2376
|
|
|
2320
2377
|
async function buildServerComponentBundleArtifactCode(options: {
|
|
@@ -2476,6 +2533,7 @@ async function buildRequestModuleArtifactCode(options: {
|
|
|
2476
2533
|
bundleCache: Map<string, Promise<RouterBundleOutput>>;
|
|
2477
2534
|
cacheDir?: string | undefined;
|
|
2478
2535
|
define?: UserConfig["define"] | undefined;
|
|
2536
|
+
externalizeAllowedPackages: boolean;
|
|
2479
2537
|
filename: string;
|
|
2480
2538
|
importPolicy: AppRouterImportPolicy;
|
|
2481
2539
|
routeKind?: AppRoute["kind"] | undefined;
|
|
@@ -2488,6 +2546,7 @@ async function buildRequestModuleArtifactCode(options: {
|
|
|
2488
2546
|
code: options.source,
|
|
2489
2547
|
define: options.define,
|
|
2490
2548
|
file: options.filename,
|
|
2549
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2491
2550
|
importPolicy: options.importPolicy,
|
|
2492
2551
|
vitePlugins: options.vitePlugins,
|
|
2493
2552
|
});
|
|
@@ -2512,6 +2571,7 @@ async function buildRequestModuleArtifactCode(options: {
|
|
|
2512
2571
|
cacheDir: options.cacheDir,
|
|
2513
2572
|
code: stripRouteRequestOnlyExports(options.source, options.filename),
|
|
2514
2573
|
define: options.define,
|
|
2574
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2515
2575
|
filename: options.filename,
|
|
2516
2576
|
importPolicy: options.importPolicy,
|
|
2517
2577
|
vitePlugins: options.vitePlugins,
|
|
@@ -2524,6 +2584,7 @@ async function bundleRouteLoaderModuleCode(options: {
|
|
|
2524
2584
|
cacheDir?: string | undefined;
|
|
2525
2585
|
code: string;
|
|
2526
2586
|
define?: UserConfig["define"] | undefined;
|
|
2587
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
2527
2588
|
filename: string;
|
|
2528
2589
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
2529
2590
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
@@ -2539,36 +2600,42 @@ async function bundleRouteRequestModuleBatchCode(options: {
|
|
|
2539
2600
|
bundleCache?: Map<string, Promise<RouterBundleOutput>> | undefined;
|
|
2540
2601
|
cacheDir?: string | undefined;
|
|
2541
2602
|
define?: UserConfig["define"] | undefined;
|
|
2603
|
+
emitSharedChunks?: boolean | undefined;
|
|
2542
2604
|
entries: readonly RouteRequestModuleBatchEntry[];
|
|
2605
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
2543
2606
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
2544
2607
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
2545
|
-
}): Promise<
|
|
2608
|
+
}): Promise<RouteRequestModuleBatchOutput> {
|
|
2546
2609
|
if (options.entries.length === 0) {
|
|
2547
|
-
return new Map();
|
|
2610
|
+
return { codeByKey: new Map(), sharedChunks: [] };
|
|
2548
2611
|
}
|
|
2549
2612
|
|
|
2550
2613
|
if (options.entries.length === 1) {
|
|
2551
2614
|
const entry = options.entries[0];
|
|
2552
2615
|
if (entry === undefined) {
|
|
2553
|
-
return new Map();
|
|
2616
|
+
return { codeByKey: new Map(), sharedChunks: [] };
|
|
2554
2617
|
}
|
|
2555
2618
|
|
|
2556
|
-
return
|
|
2557
|
-
[
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2619
|
+
return {
|
|
2620
|
+
codeByKey: new Map([
|
|
2621
|
+
[
|
|
2622
|
+
entry.key,
|
|
2623
|
+
await bundleRouteRequestModuleCode({
|
|
2624
|
+
appDir: options.appDir,
|
|
2625
|
+
bundleCache: options.bundleCache,
|
|
2626
|
+
cacheDir: options.cacheDir,
|
|
2627
|
+
code: entry.code,
|
|
2628
|
+
define: options.define,
|
|
2629
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2630
|
+
filename: entry.filename,
|
|
2631
|
+
importPolicy: options.importPolicy,
|
|
2632
|
+
label: entry.label,
|
|
2633
|
+
vitePlugins: options.vitePlugins,
|
|
2634
|
+
}),
|
|
2635
|
+
],
|
|
2636
|
+
]),
|
|
2637
|
+
sharedChunks: [],
|
|
2638
|
+
};
|
|
2572
2639
|
}
|
|
2573
2640
|
|
|
2574
2641
|
const namesByKey = new Map(
|
|
@@ -2579,13 +2646,15 @@ async function bundleRouteRequestModuleBatchCode(options: {
|
|
|
2579
2646
|
);
|
|
2580
2647
|
const output = await bundleRouterModules({
|
|
2581
2648
|
cacheDir: options.cacheDir,
|
|
2582
|
-
|
|
2649
|
+
// Externalized module code lives flat in server-modules/code, so shared
|
|
2650
|
+
// chunks must be importable as "./chunks/..." from any entry file there.
|
|
2651
|
+
chunkFileNames: "chunks/request.[hash].mjs",
|
|
2583
2652
|
entries: options.entries.map((entry) => ({
|
|
2584
2653
|
code: entry.code,
|
|
2585
2654
|
filename: entry.filename,
|
|
2586
2655
|
name: namesByKey.get(entry.key) ?? hashText(entry.key).slice(0, 8),
|
|
2587
2656
|
})),
|
|
2588
|
-
entryFileNames: "
|
|
2657
|
+
entryFileNames: "[name].mjs",
|
|
2589
2658
|
define: options.define,
|
|
2590
2659
|
platform: "node",
|
|
2591
2660
|
plugins: [
|
|
@@ -2594,14 +2663,16 @@ async function bundleRouteRequestModuleBatchCode(options: {
|
|
|
2594
2663
|
appDir: options.appDir,
|
|
2595
2664
|
importPolicy: options.importPolicy,
|
|
2596
2665
|
label: "Request artifact",
|
|
2666
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2597
2667
|
}),
|
|
2598
2668
|
],
|
|
2599
2669
|
root:
|
|
2600
2670
|
options.importPolicy?.projectRoot ?? dirname(options.entries[0]?.filename ?? options.appDir),
|
|
2601
2671
|
vitePlugins: options.vitePlugins,
|
|
2602
2672
|
});
|
|
2673
|
+
const sharedChunks = output.chunks.filter((chunk) => !chunk.isEntry);
|
|
2603
2674
|
|
|
2604
|
-
if (
|
|
2675
|
+
if (sharedChunks.length > 0 && !canEmitSharedRequestChunks(options.emitSharedChunks, output)) {
|
|
2605
2676
|
const fallbackEntries = await mapWithBuildConcurrency(
|
|
2606
2677
|
options.entries,
|
|
2607
2678
|
async (entry) =>
|
|
@@ -2613,6 +2684,7 @@ async function bundleRouteRequestModuleBatchCode(options: {
|
|
|
2613
2684
|
cacheDir: options.cacheDir,
|
|
2614
2685
|
code: entry.code,
|
|
2615
2686
|
define: options.define,
|
|
2687
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2616
2688
|
filename: entry.filename,
|
|
2617
2689
|
importPolicy: options.importPolicy,
|
|
2618
2690
|
label: entry.label,
|
|
@@ -2620,21 +2692,46 @@ async function bundleRouteRequestModuleBatchCode(options: {
|
|
|
2620
2692
|
}),
|
|
2621
2693
|
] as const,
|
|
2622
2694
|
);
|
|
2623
|
-
return new Map(fallbackEntries);
|
|
2695
|
+
return { codeByKey: new Map(fallbackEntries), sharedChunks: [] };
|
|
2624
2696
|
}
|
|
2625
2697
|
|
|
2626
2698
|
const chunksByName = new Map(output.chunks.map((chunk) => [chunk.name, chunk]));
|
|
2627
|
-
return
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2699
|
+
return {
|
|
2700
|
+
codeByKey: new Map(
|
|
2701
|
+
options.entries.map((entry) => {
|
|
2702
|
+
const name = namesByKey.get(entry.key);
|
|
2703
|
+
const chunk = name === undefined ? undefined : chunksByName.get(name);
|
|
2631
2704
|
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2705
|
+
if (chunk === undefined) {
|
|
2706
|
+
throw new Error(`Failed to compile request artifact for ${entry.filename}.`);
|
|
2707
|
+
}
|
|
2635
2708
|
|
|
2636
|
-
|
|
2637
|
-
|
|
2709
|
+
return [entry.key, chunk.code] as const;
|
|
2710
|
+
}),
|
|
2711
|
+
),
|
|
2712
|
+
sharedChunks: sharedChunks.map((chunk) => ({ code: chunk.code, fileName: chunk.fileName })),
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
|
|
2716
|
+
function canEmitSharedRequestChunks(
|
|
2717
|
+
emitSharedChunks: boolean | undefined,
|
|
2718
|
+
output: RouterBundleModulesOutput,
|
|
2719
|
+
): boolean {
|
|
2720
|
+
if (emitSharedChunks !== true) {
|
|
2721
|
+
return false;
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
if (output.assets !== undefined && output.assets.length > 0) {
|
|
2725
|
+
return false;
|
|
2726
|
+
}
|
|
2727
|
+
|
|
2728
|
+
// Entry code is rewritten into content-addressed module files, so emitted
|
|
2729
|
+
// imports may only target shared chunk files or external specifiers.
|
|
2730
|
+
const entryFileNames = new Set(
|
|
2731
|
+
output.chunks.filter((chunk) => chunk.isEntry).map((chunk) => chunk.fileName),
|
|
2732
|
+
);
|
|
2733
|
+
return output.chunks.every((chunk) =>
|
|
2734
|
+
chunk.imports.every((specifier) => !entryFileNames.has(specifier)),
|
|
2638
2735
|
);
|
|
2639
2736
|
}
|
|
2640
2737
|
|
|
@@ -2643,18 +2740,22 @@ export async function __bundleRouteRequestModuleBatchForTests(options: {
|
|
|
2643
2740
|
cacheDir?: string | undefined;
|
|
2644
2741
|
define?: UserConfig["define"] | undefined;
|
|
2645
2742
|
entries: readonly RouteRequestModuleBatchEntry[];
|
|
2743
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
2646
2744
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
2647
2745
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
2648
2746
|
}): Promise<Record<string, string>> {
|
|
2649
2747
|
return Object.fromEntries(
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2748
|
+
(
|
|
2749
|
+
await bundleRouteRequestModuleBatchCode({
|
|
2750
|
+
appDir: options.appDir,
|
|
2751
|
+
cacheDir: options.cacheDir,
|
|
2752
|
+
define: options.define,
|
|
2753
|
+
entries: options.entries,
|
|
2754
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2755
|
+
importPolicy: options.importPolicy,
|
|
2756
|
+
vitePlugins: options.vitePlugins,
|
|
2757
|
+
})
|
|
2758
|
+
).codeByKey,
|
|
2658
2759
|
);
|
|
2659
2760
|
}
|
|
2660
2761
|
|
|
@@ -2664,9 +2765,10 @@ async function bundleRouteRequestModuleCode(options: {
|
|
|
2664
2765
|
cacheDir?: string | undefined;
|
|
2665
2766
|
code: string;
|
|
2666
2767
|
define?: UserConfig["define"] | undefined;
|
|
2768
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
2667
2769
|
filename: string;
|
|
2668
2770
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
2669
|
-
label:
|
|
2771
|
+
label: RouteRequestModuleBundleLabel;
|
|
2670
2772
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
2671
2773
|
}): Promise<string> {
|
|
2672
2774
|
const output = await bundleRouterModule({
|
|
@@ -2683,6 +2785,7 @@ async function bundleRouteRequestModuleCode(options: {
|
|
|
2683
2785
|
fileImportMetaUrlPlugin(),
|
|
2684
2786
|
createAppRouterImportPolicyPlugin({
|
|
2685
2787
|
appDir: options.appDir,
|
|
2788
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2686
2789
|
importPolicy: options.importPolicy,
|
|
2687
2790
|
label: options.label,
|
|
2688
2791
|
}),
|
|
@@ -2701,9 +2804,10 @@ function routeRequestBundleCacheKey(options: {
|
|
|
2701
2804
|
appDir: string;
|
|
2702
2805
|
code: string;
|
|
2703
2806
|
define?: UserConfig["define"] | undefined;
|
|
2807
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
2704
2808
|
filename: string;
|
|
2705
2809
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
2706
|
-
label:
|
|
2810
|
+
label: RouteRequestModuleBundleLabel;
|
|
2707
2811
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
2708
2812
|
}): string {
|
|
2709
2813
|
return stableCacheKey({
|
|
@@ -2723,6 +2827,7 @@ function routeRequestBundleCacheKey(options: {
|
|
|
2723
2827
|
? undefined
|
|
2724
2828
|
: resolve(options.importPolicy.projectRoot),
|
|
2725
2829
|
},
|
|
2830
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2726
2831
|
label: options.label,
|
|
2727
2832
|
platform: "node",
|
|
2728
2833
|
target: "es2022",
|
|
@@ -2802,7 +2907,19 @@ interface RouteRequestModuleBatchEntry {
|
|
|
2802
2907
|
code: string;
|
|
2803
2908
|
filename: string;
|
|
2804
2909
|
key: string;
|
|
2805
|
-
label:
|
|
2910
|
+
label: RouteRequestModuleBundleLabel;
|
|
2911
|
+
}
|
|
2912
|
+
|
|
2913
|
+
type RouteRequestModuleBundleLabel = "Loader" | "Metadata" | "Middleware";
|
|
2914
|
+
|
|
2915
|
+
interface SharedServerModuleChunk {
|
|
2916
|
+
code: string;
|
|
2917
|
+
fileName: string;
|
|
2918
|
+
}
|
|
2919
|
+
|
|
2920
|
+
interface RouteRequestModuleBatchOutput {
|
|
2921
|
+
codeByKey: Map<string, string>;
|
|
2922
|
+
sharedChunks: readonly SharedServerModuleChunk[];
|
|
2806
2923
|
}
|
|
2807
2924
|
|
|
2808
2925
|
async function writeCloudflareRouteModules(options: {
|
package/src/import-policy.ts
CHANGED
|
@@ -21,6 +21,7 @@ export interface AppRouterImportPolicy {
|
|
|
21
21
|
export interface AppRouterImportPolicyPluginOptions {
|
|
22
22
|
allowedSourceDirs?: readonly string[] | undefined;
|
|
23
23
|
appDir: string;
|
|
24
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
24
25
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
25
26
|
label: string;
|
|
26
27
|
projectRoot?: string | undefined;
|
|
@@ -110,10 +111,12 @@ export function createAppRouterImportPolicyPlugin(options: AppRouterImportPolicy
|
|
|
110
111
|
return undefined;
|
|
111
112
|
}
|
|
112
113
|
|
|
113
|
-
return
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
return options.externalizeAllowedPackages === false
|
|
115
|
+
? undefined
|
|
116
|
+
: {
|
|
117
|
+
external: true,
|
|
118
|
+
path: pathToFileURL(resolvedPackage).href,
|
|
119
|
+
};
|
|
117
120
|
});
|
|
118
121
|
},
|
|
119
122
|
};
|
package/src/render.ts
CHANGED
|
@@ -2525,6 +2525,7 @@ export async function bundleMiddlewareModuleCode(options: {
|
|
|
2525
2525
|
appDir: string;
|
|
2526
2526
|
code: string;
|
|
2527
2527
|
define?: UserConfig["define"] | undefined;
|
|
2528
|
+
externalizeAllowedPackages?: boolean | undefined;
|
|
2528
2529
|
file: string;
|
|
2529
2530
|
importPolicy?: AppRouterImportPolicy | undefined;
|
|
2530
2531
|
vitePlugins?: readonly PluginOption[] | undefined;
|
|
@@ -2539,6 +2540,7 @@ export async function bundleMiddlewareModuleCode(options: {
|
|
|
2539
2540
|
fileImportMetaUrlPlugin(),
|
|
2540
2541
|
createAppRouterImportPolicyPlugin({
|
|
2541
2542
|
appDir: options.appDir,
|
|
2543
|
+
externalizeAllowedPackages: options.externalizeAllowedPackages,
|
|
2542
2544
|
importPolicy: options.importPolicy,
|
|
2543
2545
|
label: "Middleware",
|
|
2544
2546
|
}),
|