@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 CHANGED
@@ -371,7 +371,7 @@ Production adapters enforce the app-router import policy when bundling loaders,
371
371
 
372
372
  For Lambda deployments, build with `mreact-router build --target=aws-lambda` or `buildApp({ targets: ["aws-lambda"] })`. The target writes Node-compatible server/client output, `.mreact/server/import-policy.json`, and `.mreact/aws-lambda/mreact-handler.mjs` while skipping `.mreact/cloudflare` route modules, so loaders and server helpers may import Node-only dependencies such as database drivers without being bundled for the Workers runtime.
373
373
 
374
- Package Lambda deployments with `mreact-router package aws-lambda --from .mreact --out .lambda` instead of pointing deployment tooling at the full project checkout. AWS Lambda enforces a 250 MB unzipped deployment package limit, and the runtime only needs `.mreact/`, `mreact-handler.mjs`, `package.json` / lockfiles, and production `node_modules`; `src/`, tests, dev dependencies, build caches, and Vite/Vitest/Playwright tooling are not required. `mreact-router build --target=aws-lambda` keeps compiled server route artifacts in `.mreact/server/server-modules/*.json` instead of embedding them in one large server manifest, writes compiled module bodies as hashed `.mjs` files, and keeps request/control artifacts separate from render artifacts so loader redirects do not read page render bundles. `createAwsLambdaRequestHandler()` treats `outDir` as read-only and materializes generated runtime files under `/tmp/mreact-router/<hash>/runtime` by default, with a `node_modules` symlink back to the deployed package root. Direct `createAwsLambdaRequestHandler()` and `createAwsLambdaStreamingRequestHandler()` handlers start only middleware and shared runtime preload in the background by default, so all-route preload work does not compete with the first user request. If a request arrives before preload finishes, middleware is resolved first, middleware responses or redirects return without loading the matched page artifact, and continuing requests load only the matched route's artifact closure. Static middleware `config.matcher` and `config.id` values are checked before importing the middleware module, so unmatched health checks and route-local middleware skips avoid evaluating heavyweight middleware dependencies. Route request artifacts omit page render exports, and built loader and route metadata artifacts are split, so loader redirects do not evaluate page-only or metadata-only dependencies before render or metadata is needed. Loader redirects settle before page component server transforms and render imports for non-stream routes, stream routes without a loading boundary, and stream loading routes whose loader source contains router control-flow helpers such as `redirect()` or `notFound()`. Prefer `await createPreloadedAwsLambdaRequestHandler()` in Node 24 ESM Lambda handlers when first-request latency matters: it waits for the full preload during Lambda initialization by default, increasing `Init Duration` but making the first handler invocation much closer to warm steady-state. Pass `runtimeDir` only when you need to control that writable cache location. With pnpm, run `pnpm --dir .lambda install --prod --frozen-lockfile --ignore-scripts --config.node-linker=hoisted`. pnpm's default isolated linker is symlink-heavy, so verify the artifact's symlink count with `find .lambda -type l | wc -l` and measure actual file bytes in addition to `du -sh .lambda` before upload. Packages listed in the generated import policy must also be installed in that production artifact.
374
+ Package Lambda deployments with `mreact-router package aws-lambda --from .mreact --out .lambda` instead of pointing deployment tooling at the full project checkout. AWS Lambda enforces a 250 MB unzipped deployment package limit, and the runtime only needs `.mreact/`, `mreact-handler.mjs`, `package.json` / lockfiles, and production `node_modules`; `src/`, tests, dev dependencies, build caches, and Vite/Vitest/Playwright tooling are not required. `mreact-router build --target=aws-lambda` keeps compiled server route artifacts in `.mreact/server/server-modules/*.json` instead of embedding them in one large server manifest, writes compiled module bodies as hashed `.mjs` files, and keeps request/control artifacts separate from render artifacts so loader redirects do not read page render bundles. AWS Lambda request/control artifacts bundle the generated import-policy packages they use for loaders, middleware, route handlers, and metadata, reducing first-hit package resolution on sparse Lambda traffic while leaving render-only, server action, custom handler, and adapter dependencies in production `node_modules`. `createAwsLambdaRequestHandler()` treats `outDir` as read-only and materializes generated runtime files under `/tmp/mreact-router/<hash>/runtime` by default, with a `node_modules` symlink back to the deployed package root. Direct `createAwsLambdaRequestHandler()` and `createAwsLambdaStreamingRequestHandler()` handlers start only middleware and shared runtime preload in the background by default, so all-route preload work does not compete with the first user request. If a request arrives before preload finishes, middleware is resolved first, middleware responses or redirects return without loading the matched page artifact, and continuing requests load only the matched route's artifact closure. Static middleware `config.matcher` and `config.id` values are checked before importing the middleware module, so unmatched health checks and route-local middleware skips avoid evaluating heavyweight middleware dependencies. Route request artifacts omit page render exports, and built loader and route metadata artifacts are split, so loader redirects do not evaluate page-only or metadata-only dependencies before render or metadata is needed. Loader redirects settle before page component server transforms and render imports for non-stream routes, stream routes without a loading boundary, and stream loading routes whose loader source contains router control-flow helpers such as `redirect()` or `notFound()`. Prefer `await createPreloadedAwsLambdaRequestHandler()` in Node 24 ESM Lambda handlers when first-request latency matters: it waits for the full preload during Lambda initialization by default, increasing `Init Duration` but making the first handler invocation much closer to warm steady-state. Pass `runtimeDir` only when you need to control that writable cache location. With pnpm, run `pnpm --dir .lambda install --prod --frozen-lockfile --ignore-scripts --config.node-linker=hoisted`. pnpm's default isolated linker is symlink-heavy, so verify the artifact's symlink count with `find .lambda -type l | wc -l` and measure actual file bytes in addition to `du -sh .lambda` before upload. Packages listed in the generated import policy may still be needed by render-only modules, inferred server actions, custom handlers, or adapter code, so keep them installed in that production artifact.
375
375
 
376
376
  When a deployment needs custom adapter options such as `serverActions.authorize`, `onResponse`, `errorHandler`, or `allowedHosts`, create an app handler and package it with `mreact-router package aws-lambda --from .mreact --out .lambda --handler src/lambda.ts`. The package command bundles that handler into `.lambda/mreact-handler.mjs`, resolves app-local TypeScript imports with Vite-style extensionless paths, and keeps package imports external so production `node_modules` remains the runtime dependency boundary. If the handler imports the same app server modules that routes also import, those modules are compiled into the handler bundle separately from the mreact route artifacts; use `getServerRuntimeState()` for state that must be shared through the router runtime instead of relying on module singletons.
377
377
 
package/dist/build.d.ts CHANGED
@@ -147,6 +147,7 @@ export declare function __bundleRouteRequestModuleBatchForTests(options: {
147
147
  cacheDir?: string | undefined;
148
148
  define?: UserConfig["define"] | undefined;
149
149
  entries: readonly RouteRequestModuleBatchEntry[];
150
+ externalizeAllowedPackages?: boolean | undefined;
150
151
  importPolicy?: AppRouterImportPolicy | undefined;
151
152
  vitePlugins?: readonly PluginOption[] | undefined;
152
153
  }): Promise<Record<string, string>>;
@@ -154,8 +155,9 @@ interface RouteRequestModuleBatchEntry {
154
155
  code: string;
155
156
  filename: string;
156
157
  key: string;
157
- label: "Loader" | "Metadata";
158
+ label: RouteRequestModuleBundleLabel;
158
159
  }
160
+ type RouteRequestModuleBundleLabel = "Loader" | "Metadata" | "Middleware";
159
161
  export declare function __buildCloudflareRouteLoaderModuleBatchForTests(options: {
160
162
  cacheDir?: string | undefined;
161
163
  define?: UserConfig["define"] | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"AAsDA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAGL,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EAG1B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGnD,OAAO,EAAqC,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAiCnG,OAAO,KAAK,EAAU,YAAY,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAa7D,MAAM,WAAW,eAAgB,SAAQ,uBAAuB;IAC9D,eAAe,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACvE,kBAAkB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,SAAS,oBAAoB,EAAE,GAAG,SAAS,CAAC;IACtD,UAAU,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;CACjE;AA0CD,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,cAAc,GACd,gBAAgB,GAChB,UAAU,GACV,eAAe,GACf,cAAc,GACd,sBAAsB,GACtB,eAAe,GACf,cAAc,GACd,uBAAuB,GACvB,eAAe,GACf,mBAAmB,GACnB,WAAW,GACX,YAAY,GACZ,gBAAgB,GAChB,kBAAkB,CAAC;AAEvB,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;CACtB;AAED,MAAM,MAAM,qBAAqB,GAC7B;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;CACtB,GACD;IACE,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,aAAa,CAAC;CACtB,GACD;IACE,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,mBAAmB,CAAC;CAC3B,CAAC;AAEN,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,QAAQ,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,CAAC;CACZ;AAED,MAAM,WAAW,+BAA+B;IAC9C,KAAK,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9C,OAAO,EAAE,kBAAkB,CAAC;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,CAAC;IACX,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,+BAA+B;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClD;AAED,MAAM,WAAW,qCAAqC;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,iBAAiB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,CAAC;IACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC1D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oCAAoC,EAAE,CAAC,CAAC;IACrF,oBAAoB,CAAC,EAAE,0BAA0B,EAAE,CAAC;IACpD,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC3C,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,wBAAwB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClD,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;CAC3D;AAED,MAAM,WAAW,0BAA0B;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oCAAoC;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,EAAE,+BAA+B,CAAC;IAC3C,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,aAAa,CAAC,EAAE,uBAAuB,CAAC;IACxC,OAAO,CAAC,EAAE,uBAAuB,CAAC;IAClC,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC,MAAM,CAAC,EAAE,uBAAuB,CAAC;CAClC;AAED,MAAM,WAAW,+BAA+B;IAC9C,kBAAkB,EAAE,OAAO,CAAC;IAC5B,WAAW,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAC3C,qBAAqB,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,6BAA6B,EAAE,SAAS,MAAM,EAAE,CAAC;IACjD,WAAW,EAAE,OAAO,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,OAAO,CAAC;IACrB,uBAAuB,EAAE,OAAO,CAAC;CAClC;AA6BD,MAAM,WAAW,uBAAuB;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAID;;;;GAIG;AACH,wBAAsB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CA0YhF;AA8FD,wBAAsB,iCAAiC,CAAC,CAAC,EAAE,CAAC,EAC1D,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC3C,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,CAAC,EAAE,CAAC,CAEd;AA0RD,wBAAsB,wCAAwC,CAC5D,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,GACvD,OAAO,CAAC;IACT,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC,CAAC,CAED;AAu+CD,wBAAsB,uCAAuC,CAAC,OAAO,EAAE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAC1C,OAAO,EAAE,SAAS,4BAA4B,EAAE,CAAC;IACjD,YAAY,CAAC,EAAE,qBAAqB,GAAG,SAAS,CAAC;IACjD,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;CACnD,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAWlC;AA8ID,UAAU,4BAA4B;IACpC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,QAAQ,GAAG,UAAU,CAAC;CAC9B;AAwuDD,wBAAsB,+CAA+C,CAAC,OAAO,EAAE;IAC7E,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,SAAS,CAAC;IAC1C,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACzD,WAAW,CAAC,EAAE,SAAS,YAAY,EAAE,GAAG,SAAS,CAAC;CACnD,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAYlC;AA0mCD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC5C,OAAO,EAAE,+BAA+B,GACvC,OAAO,CAAC,yBAAyB,CAAC,CA4CpC;AA6DD;;;;GAIG;AACH,wBAAsB,8BAA8B,CAClD,OAAO,EAAE,qCAAqC,GAC7C,OAAO,CAAC,+BAA+B,CAAC,CAsD1C"}
1
+ {"version":3,"file":"build.d.ts","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
package/dist/build.js CHANGED
@@ -156,7 +156,7 @@ export async function buildApp(options) {
156
156
  ? await buildPublicAssetManifest(project, clientDir)
157
157
  : await timeBuildPhase(timingSink, progressSink, "publicAssets", () => buildPublicAssetManifest(project, clientDir));
158
158
  const clientRouteInferenceCache = createClientRouteInferenceCache();
159
- const [serverActionManifest, serverModules, generatedImportPolicy] = await Promise.all([
159
+ const [serverActionManifest, generatedImportPolicy] = await Promise.all([
160
160
  shouldTrackBuildPhases === false
161
161
  ? collectBuildServerActionManifest({
162
162
  files,
@@ -170,33 +170,6 @@ export async function buildApp(options) {
170
170
  routes,
171
171
  routesDir: project.routesDir,
172
172
  })),
173
- shouldTrackBuildPhases === false
174
- ? buildServerModuleArtifacts({
175
- bundleCache: new Map(),
176
- clientRouteInferenceCache: serverClientRouteInferenceCache,
177
- define: viteDefine,
178
- files,
179
- prebundleServerComponents: buildTargets.includes("node") || shouldBuildAwsLambda,
180
- project,
181
- projectRoot: project.projectRoot,
182
- routes,
183
- sourceAnalysis,
184
- serverTransformCache,
185
- vitePlugins,
186
- })
187
- : timeBuildPhase(timingSink, progressSink, "serverModules", () => buildServerModuleArtifacts({
188
- bundleCache: new Map(),
189
- clientRouteInferenceCache: serverClientRouteInferenceCache,
190
- define: viteDefine,
191
- files,
192
- prebundleServerComponents: buildTargets.includes("node") || shouldBuildAwsLambda,
193
- project,
194
- projectRoot: project.projectRoot,
195
- routes,
196
- sourceAnalysis,
197
- serverTransformCache,
198
- vitePlugins,
199
- })),
200
173
  shouldTrackBuildPhases === false
201
174
  ? buildGeneratedImportPolicy({
202
175
  files,
@@ -211,14 +184,48 @@ export async function buildApp(options) {
211
184
  routesDir: project.routesDir,
212
185
  })),
213
186
  ]);
187
+ const actionRenderBundleExcludedFiles = new Set([...serverActionManifest.routeReferences.entries()]
188
+ .filter(([, references]) => references.length > 0)
189
+ .map(([file]) => file));
190
+ const { artifacts: serverModules, sharedChunks: serverModuleSharedChunks } = await (shouldTrackBuildPhases === false
191
+ ? buildServerModuleArtifacts({
192
+ actionRenderBundleExcludedFiles,
193
+ bundleRequestRuntimePackages: shouldBuildAwsLambda,
194
+ bundleCache: new Map(),
195
+ clientRouteInferenceCache: serverClientRouteInferenceCache,
196
+ define: viteDefine,
197
+ files,
198
+ prebundleServerComponents: buildTargets.includes("node") || shouldBuildAwsLambda,
199
+ project,
200
+ projectRoot: project.projectRoot,
201
+ routes,
202
+ sourceAnalysis,
203
+ serverTransformCache,
204
+ vitePlugins,
205
+ })
206
+ : timeBuildPhase(timingSink, progressSink, "serverModules", () => buildServerModuleArtifacts({
207
+ actionRenderBundleExcludedFiles,
208
+ bundleRequestRuntimePackages: shouldBuildAwsLambda,
209
+ bundleCache: new Map(),
210
+ clientRouteInferenceCache: serverClientRouteInferenceCache,
211
+ define: viteDefine,
212
+ files,
213
+ prebundleServerComponents: buildTargets.includes("node") || shouldBuildAwsLambda,
214
+ project,
215
+ projectRoot: project.projectRoot,
216
+ routes,
217
+ sourceAnalysis,
218
+ serverTransformCache,
219
+ vitePlugins,
220
+ })));
214
221
  const serverRoutes = routes.map((route) => ({
215
222
  ...route,
216
223
  file: relative(project.projectRoot, route.file),
217
224
  }));
218
225
  const [serverModuleArtifacts, clientBundle] = await Promise.all([
219
226
  shouldTrackBuildPhases === false
220
- ? writeServerModuleArtifactFiles(serverDir, serverModules, generatedImportPolicy.runtimePackages)
221
- : timeBuildPhase(timingSink, progressSink, "serverModuleArtifacts", () => writeServerModuleArtifactFiles(serverDir, serverModules, generatedImportPolicy.runtimePackages)),
227
+ ? writeServerModuleArtifactFiles(serverDir, serverModules, generatedImportPolicy.runtimePackages, serverModuleSharedChunks)
228
+ : timeBuildPhase(timingSink, progressSink, "serverModuleArtifacts", () => writeServerModuleArtifactFiles(serverDir, serverModules, generatedImportPolicy.runtimePackages, serverModuleSharedChunks)),
222
229
  shouldTrackBuildPhases === false
223
230
  ? writeClientRouteBundles({
224
231
  appDir: project.routesDir,
@@ -616,7 +623,7 @@ async function writeCompatVendorChunks(serverDir, usedEntries) {
616
623
  await mkdir(chunksDir, { recursive: true });
617
624
  await Promise.all(output.chunks.map((chunk) => writeFile(join(chunksDir, chunk.fileName), chunk.code)));
618
625
  }
619
- async function writeServerModuleArtifactFiles(serverDir, serverModules, portableRuntimePackages = []) {
626
+ async function writeServerModuleArtifactFiles(serverDir, serverModules, portableRuntimePackages = [], sharedChunks = []) {
620
627
  const files = {};
621
628
  const renderFiles = {};
622
629
  const requestFiles = {};
@@ -628,6 +635,12 @@ async function writeServerModuleArtifactFiles(serverDir, serverModules, portable
628
635
  mkdir(join(modulesDir, "request"), { recursive: true }),
629
636
  mkdir(join(modulesDir, "render"), { recursive: true }),
630
637
  ]);
638
+ if (sharedChunks.length > 0) {
639
+ // Shared request chunks are referenced from externalized module code via
640
+ // "./chunks/..." imports, so they live next to server-modules/code files.
641
+ await mkdir(join(modulesDir, "code", "chunks"), { recursive: true });
642
+ await Promise.all(sharedChunks.map((chunk) => writeFile(join(modulesDir, "code", chunk.fileName), rewriteCompatVendorPlaceholderImports(rewritePortableRuntimePackageImports(chunk.code, portableRuntimePackages)))));
643
+ }
631
644
  const usedCompatVendorEntries = collectCompatVendorEntryUsage(artifactEntries);
632
645
  if (usedCompatVendorEntries.size > 0) {
633
646
  await writeCompatVendorChunks(serverDir, usedCompatVendorEntries);
@@ -1296,8 +1309,20 @@ async function buildServerModuleArtifacts(options) {
1296
1309
  label: "Metadata",
1297
1310
  });
1298
1311
  }
1312
+ if (isMiddlewareFile(options.project.routesDir, absoluteFile)) {
1313
+ // Middleware joins the batch when runtime packages are bundled so the
1314
+ // auth/control dependency graph is shared with route loader artifacts.
1315
+ if (options.bundleRequestRuntimePackages) {
1316
+ requestBatchEntries.push({
1317
+ code: source,
1318
+ filename: absoluteFile,
1319
+ key: routeRequestArtifactBatchKey(file, "request"),
1320
+ label: "Middleware",
1321
+ });
1322
+ }
1323
+ continue;
1324
+ }
1299
1325
  if (requestArtifactFiles.has(file) &&
1300
- !isMiddlewareFile(options.project.routesDir, absoluteFile) &&
1301
1326
  route?.kind !== "server" &&
1302
1327
  route?.kind !== "metadata") {
1303
1328
  requestBatchEntries.push({
@@ -1308,17 +1333,19 @@ async function buildServerModuleArtifacts(options) {
1308
1333
  });
1309
1334
  }
1310
1335
  }
1311
- const requestBatchOutputs = requestBatchEntries.length >= 3
1336
+ const { codeByKey: requestBatchOutputs, sharedChunks } = requestBatchEntries.length >= (options.bundleRequestRuntimePackages ? 2 : 3)
1312
1337
  ? await bundleRouteRequestModuleBatchCode({
1313
1338
  appDir: options.project.routesDir,
1314
1339
  bundleCache: options.bundleCache,
1315
1340
  cacheDir: options.cacheDir,
1341
+ emitSharedChunks: options.bundleRequestRuntimePackages,
1316
1342
  entries: requestBatchEntries,
1343
+ externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
1317
1344
  importPolicy: requestModuleImportPolicy,
1318
1345
  define: options.define,
1319
1346
  vitePlugins: options.vitePlugins,
1320
1347
  })
1321
- : new Map();
1348
+ : { codeByKey: new Map(), sharedChunks: [] };
1322
1349
  const artifactEntries = await mapWithBuildConcurrency(Object.entries(options.files), async ([file, source]) => {
1323
1350
  const absoluteFile = join(options.projectRoot, file);
1324
1351
  const route = routeByFile.get(file);
@@ -1335,6 +1362,7 @@ async function buildServerModuleArtifacts(options) {
1335
1362
  cacheDir: options.cacheDir,
1336
1363
  code: stripRouteLoaderOnlyExports(source, absoluteFile),
1337
1364
  filename: absoluteFile,
1365
+ externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
1338
1366
  importPolicy: requestModuleImportPolicy,
1339
1367
  define: options.define,
1340
1368
  vitePlugins: options.vitePlugins,
@@ -1352,6 +1380,7 @@ async function buildServerModuleArtifacts(options) {
1352
1380
  cacheDir: options.cacheDir,
1353
1381
  code: stripRouteMetadataOnlyExports(source, absoluteFile),
1354
1382
  filename: absoluteFile,
1383
+ externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
1355
1384
  importPolicy: requestModuleImportPolicy,
1356
1385
  label: "Metadata",
1357
1386
  define: options.define,
@@ -1371,6 +1400,7 @@ async function buildServerModuleArtifacts(options) {
1371
1400
  bundleCache: options.bundleCache,
1372
1401
  cacheDir: options.cacheDir,
1373
1402
  filename: absoluteFile,
1403
+ externalizeAllowedPackages: !options.bundleRequestRuntimePackages,
1374
1404
  importPolicy: requestModuleImportPolicy,
1375
1405
  define: options.define,
1376
1406
  routeKind: route?.kind,
@@ -1455,23 +1485,24 @@ async function buildServerModuleArtifacts(options) {
1455
1485
  // cannot drop deferred Link content before the boundary resolves.
1456
1486
  return undefined;
1457
1487
  }
1488
+ const shouldWriteRenderBundle = options.prebundleServerComponents &&
1489
+ options.actionRenderBundleExcludedFiles?.has(file) !== true;
1490
+ const bundleCode = shouldWriteRenderBundle
1491
+ ? await buildServerComponentBundleArtifactCode({
1492
+ clientRouteInferenceCache: options.clientRouteInferenceCache,
1493
+ code: output.code,
1494
+ externalizeCompatVendor,
1495
+ filename: absoluteFile,
1496
+ define: options.define,
1497
+ root: options.projectRoot,
1498
+ serverOutput,
1499
+ vitePlugins: options.vitePlugins,
1500
+ })
1501
+ : undefined;
1458
1502
  return [
1459
1503
  serverOutput,
1460
1504
  {
1461
- ...(options.prebundleServerComponents
1462
- ? {
1463
- bundleCode: await buildServerComponentBundleArtifactCode({
1464
- clientRouteInferenceCache: options.clientRouteInferenceCache,
1465
- code: output.code,
1466
- externalizeCompatVendor,
1467
- filename: absoluteFile,
1468
- define: options.define,
1469
- root: options.projectRoot,
1470
- serverOutput,
1471
- vitePlugins: options.vitePlugins,
1472
- }),
1473
- }
1474
- : {}),
1505
+ ...(bundleCode === undefined ? {} : { bundleCode }),
1475
1506
  code: output.code,
1476
1507
  metadata: output.metadata,
1477
1508
  sourceHash: hashText(code),
@@ -1490,7 +1521,7 @@ async function buildServerModuleArtifacts(options) {
1490
1521
  artifacts[entry[0]] = entry[1];
1491
1522
  }
1492
1523
  }
1493
- return artifacts;
1524
+ return { artifacts, sharedChunks };
1494
1525
  }
1495
1526
  async function buildServerComponentBundleArtifactCode(options) {
1496
1527
  return await bundleAppRouterSourceModule({
@@ -1602,6 +1633,7 @@ async function buildRequestModuleArtifactCode(options) {
1602
1633
  code: options.source,
1603
1634
  define: options.define,
1604
1635
  file: options.filename,
1636
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1605
1637
  importPolicy: options.importPolicy,
1606
1638
  vitePlugins: options.vitePlugins,
1607
1639
  });
@@ -1624,6 +1656,7 @@ async function buildRequestModuleArtifactCode(options) {
1624
1656
  cacheDir: options.cacheDir,
1625
1657
  code: stripRouteRequestOnlyExports(options.source, options.filename),
1626
1658
  define: options.define,
1659
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1627
1660
  filename: options.filename,
1628
1661
  importPolicy: options.importPolicy,
1629
1662
  vitePlugins: options.vitePlugins,
@@ -1637,29 +1670,33 @@ async function bundleRouteLoaderModuleCode(options) {
1637
1670
  }
1638
1671
  async function bundleRouteRequestModuleBatchCode(options) {
1639
1672
  if (options.entries.length === 0) {
1640
- return new Map();
1673
+ return { codeByKey: new Map(), sharedChunks: [] };
1641
1674
  }
1642
1675
  if (options.entries.length === 1) {
1643
1676
  const entry = options.entries[0];
1644
1677
  if (entry === undefined) {
1645
- return new Map();
1678
+ return { codeByKey: new Map(), sharedChunks: [] };
1646
1679
  }
1647
- return new Map([
1648
- [
1649
- entry.key,
1650
- await bundleRouteRequestModuleCode({
1651
- appDir: options.appDir,
1652
- bundleCache: options.bundleCache,
1653
- cacheDir: options.cacheDir,
1654
- code: entry.code,
1655
- define: options.define,
1656
- filename: entry.filename,
1657
- importPolicy: options.importPolicy,
1658
- label: entry.label,
1659
- vitePlugins: options.vitePlugins,
1660
- }),
1661
- ],
1662
- ]);
1680
+ return {
1681
+ codeByKey: new Map([
1682
+ [
1683
+ entry.key,
1684
+ await bundleRouteRequestModuleCode({
1685
+ appDir: options.appDir,
1686
+ bundleCache: options.bundleCache,
1687
+ cacheDir: options.cacheDir,
1688
+ code: entry.code,
1689
+ define: options.define,
1690
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1691
+ filename: entry.filename,
1692
+ importPolicy: options.importPolicy,
1693
+ label: entry.label,
1694
+ vitePlugins: options.vitePlugins,
1695
+ }),
1696
+ ],
1697
+ ]),
1698
+ sharedChunks: [],
1699
+ };
1663
1700
  }
1664
1701
  const namesByKey = new Map(options.entries.map((entry, index) => [
1665
1702
  entry.key,
@@ -1667,13 +1704,15 @@ async function bundleRouteRequestModuleBatchCode(options) {
1667
1704
  ]));
1668
1705
  const output = await bundleRouterModules({
1669
1706
  cacheDir: options.cacheDir,
1670
- chunkFileNames: "request/chunks/[name].[hash].js",
1707
+ // Externalized module code lives flat in server-modules/code, so shared
1708
+ // chunks must be importable as "./chunks/..." from any entry file there.
1709
+ chunkFileNames: "chunks/request.[hash].mjs",
1671
1710
  entries: options.entries.map((entry) => ({
1672
1711
  code: entry.code,
1673
1712
  filename: entry.filename,
1674
1713
  name: namesByKey.get(entry.key) ?? hashText(entry.key).slice(0, 8),
1675
1714
  })),
1676
- entryFileNames: "request/[name].js",
1715
+ entryFileNames: "[name].mjs",
1677
1716
  define: options.define,
1678
1717
  platform: "node",
1679
1718
  plugins: [
@@ -1682,12 +1721,14 @@ async function bundleRouteRequestModuleBatchCode(options) {
1682
1721
  appDir: options.appDir,
1683
1722
  importPolicy: options.importPolicy,
1684
1723
  label: "Request artifact",
1724
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1685
1725
  }),
1686
1726
  ],
1687
1727
  root: options.importPolicy?.projectRoot ?? dirname(options.entries[0]?.filename ?? options.appDir),
1688
1728
  vitePlugins: options.vitePlugins,
1689
1729
  });
1690
- if (output.chunks.some((chunk) => !chunk.isEntry)) {
1730
+ const sharedChunks = output.chunks.filter((chunk) => !chunk.isEntry);
1731
+ if (sharedChunks.length > 0 && !canEmitSharedRequestChunks(options.emitSharedChunks, output)) {
1691
1732
  const fallbackEntries = await mapWithBuildConcurrency(options.entries, async (entry) => [
1692
1733
  entry.key,
1693
1734
  await bundleRouteRequestModuleCode({
@@ -1696,33 +1737,50 @@ async function bundleRouteRequestModuleBatchCode(options) {
1696
1737
  cacheDir: options.cacheDir,
1697
1738
  code: entry.code,
1698
1739
  define: options.define,
1740
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1699
1741
  filename: entry.filename,
1700
1742
  importPolicy: options.importPolicy,
1701
1743
  label: entry.label,
1702
1744
  vitePlugins: options.vitePlugins,
1703
1745
  }),
1704
1746
  ]);
1705
- return new Map(fallbackEntries);
1747
+ return { codeByKey: new Map(fallbackEntries), sharedChunks: [] };
1706
1748
  }
1707
1749
  const chunksByName = new Map(output.chunks.map((chunk) => [chunk.name, chunk]));
1708
- return new Map(options.entries.map((entry) => {
1709
- const name = namesByKey.get(entry.key);
1710
- const chunk = name === undefined ? undefined : chunksByName.get(name);
1711
- if (chunk === undefined) {
1712
- throw new Error(`Failed to compile request artifact for ${entry.filename}.`);
1713
- }
1714
- return [entry.key, chunk.code];
1715
- }));
1750
+ return {
1751
+ codeByKey: new Map(options.entries.map((entry) => {
1752
+ const name = namesByKey.get(entry.key);
1753
+ const chunk = name === undefined ? undefined : chunksByName.get(name);
1754
+ if (chunk === undefined) {
1755
+ throw new Error(`Failed to compile request artifact for ${entry.filename}.`);
1756
+ }
1757
+ return [entry.key, chunk.code];
1758
+ })),
1759
+ sharedChunks: sharedChunks.map((chunk) => ({ code: chunk.code, fileName: chunk.fileName })),
1760
+ };
1761
+ }
1762
+ function canEmitSharedRequestChunks(emitSharedChunks, output) {
1763
+ if (emitSharedChunks !== true) {
1764
+ return false;
1765
+ }
1766
+ if (output.assets !== undefined && output.assets.length > 0) {
1767
+ return false;
1768
+ }
1769
+ // Entry code is rewritten into content-addressed module files, so emitted
1770
+ // imports may only target shared chunk files or external specifiers.
1771
+ const entryFileNames = new Set(output.chunks.filter((chunk) => chunk.isEntry).map((chunk) => chunk.fileName));
1772
+ return output.chunks.every((chunk) => chunk.imports.every((specifier) => !entryFileNames.has(specifier)));
1716
1773
  }
1717
1774
  export async function __bundleRouteRequestModuleBatchForTests(options) {
1718
- return Object.fromEntries(await bundleRouteRequestModuleBatchCode({
1775
+ return Object.fromEntries((await bundleRouteRequestModuleBatchCode({
1719
1776
  appDir: options.appDir,
1720
1777
  cacheDir: options.cacheDir,
1721
1778
  define: options.define,
1722
1779
  entries: options.entries,
1780
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1723
1781
  importPolicy: options.importPolicy,
1724
1782
  vitePlugins: options.vitePlugins,
1725
- }));
1783
+ })).codeByKey);
1726
1784
  }
1727
1785
  async function bundleRouteRequestModuleCode(options) {
1728
1786
  const output = await bundleRouterModule({
@@ -1739,6 +1797,7 @@ async function bundleRouteRequestModuleCode(options) {
1739
1797
  fileImportMetaUrlPlugin(),
1740
1798
  createAppRouterImportPolicyPlugin({
1741
1799
  appDir: options.appDir,
1800
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1742
1801
  importPolicy: options.importPolicy,
1743
1802
  label: options.label,
1744
1803
  }),
@@ -1766,6 +1825,7 @@ function routeRequestBundleCacheKey(options) {
1766
1825
  ? undefined
1767
1826
  : resolve(options.importPolicy.projectRoot),
1768
1827
  },
1828
+ externalizeAllowedPackages: options.externalizeAllowedPackages,
1769
1829
  label: options.label,
1770
1830
  platform: "node",
1771
1831
  target: "es2022",