Refactor SSR strategy. Redirect before bundling any page component. Additional bugfixes for dev environment

This commit is contained in:
Benjamin Toby 2026-04-12 16:20:16 +01:00
parent 84d490b189
commit f0aae8a8fa
27 changed files with 210 additions and 87 deletions

View File

@ -1,6 +1,7 @@
import type { BundlerCTXMap } from "../../types";
type Params = { type Params = {
post_build_fn?: (params: { post_build_fn?: (params: {
artifacts: any[]; artifacts: BundlerCTXMap[];
}) => Promise<void> | void; }) => Promise<void> | void;
}; };
export default function allPagesESBuildContextBundler(params?: Params): Promise<void>; export default function allPagesESBuildContextBundler(params?: Params): Promise<void>;

View File

@ -1,4 +1,3 @@
import { log } from "../../utils/log";
export default async function buildOnstartErrorHandler(params) { export default async function buildOnstartErrorHandler(params) {
// const error_msg = `Build Failed. Please check all your components and imports.`; // const error_msg = `Build Failed. Please check all your components and imports.`;
// log.error(error_msg); // log.error(error_msg);

View File

@ -36,7 +36,9 @@ export default async function bunextInit() {
if (is_dev) { if (is_dev) {
log.build(`Building Modules ...`); log.build(`Building Modules ...`);
await allPagesESBuildContextBundler({ await allPagesESBuildContextBundler({
post_build_fn: serverPostBuildFn, post_build_fn: () => {
serverPostBuildFn();
},
}); });
watcherEsbuildCTX(); watcherEsbuildCTX();
} }

View File

@ -15,7 +15,9 @@ export default async function fullRebuild(params) {
await global.SSR_BUNDLER_CTX?.dispose(); await global.SSR_BUNDLER_CTX?.dispose();
global.SSR_BUNDLER_CTX = undefined; global.SSR_BUNDLER_CTX = undefined;
allPagesESBuildContextBundler({ allPagesESBuildContextBundler({
post_build_fn: serverPostBuildFn, post_build_fn: () => {
serverPostBuildFn();
},
}); });
} }
catch (error) { catch (error) {

View File

@ -1 +1,5 @@
export default function serverPostBuildFn(): Promise<void>; type Params = {
reload_all_controllers?: boolean;
};
export default function serverPostBuildFn(params?: Params): Promise<void>;
export {};

View File

@ -1,29 +1,49 @@
import _ from "lodash"; import _ from "lodash";
import grabPageComponent from "./web-pages/grab-page-component"; import grabPageComponent from "./web-pages/grab-page-component";
export default async function serverPostBuildFn() { export default async function serverPostBuildFn(params) {
if (!global.HMR_CONTROLLERS?.[0] || !global.BUNDLER_CTX_MAP) { if (!global.HMR_CONTROLLERS?.[0] || !global.BUNDLER_CTX_MAP) {
return; return;
} }
const reload_payload = { reload: true };
const reload_enqueue = `event: update\ndata: ${JSON.stringify(reload_payload)}\n\n`;
for (let i = global.HMR_CONTROLLERS.length - 1; i >= 0; i--) { for (let i = global.HMR_CONTROLLERS.length - 1; i >= 0; i--) {
const controller = global.HMR_CONTROLLERS[i]; const controller = global.HMR_CONTROLLERS[i];
if (!controller?.target_map?.local_path) { if (!controller) {
continue; continue;
} }
if (global.IS_404_PAGE) { if (!controller.target_map?.local_path) {
controller.controller.enqueue(`event: update\ndata: ${JSON.stringify({ reload: true })}\n\n`); // if (global.IS_404_PAGE) {
// controller.controller.enqueue(reload_enqueue);
// }
// if (!global.HMR_CONTROLLERS[i].page_reloaded) {
// controller.controller.enqueue(reload_enqueue);
// global.HMR_CONTROLLERS[i].page_reloaded = true;
// }
continue;
}
if (params?.reload_all_controllers) {
controller.controller.enqueue(reload_enqueue);
continue; continue;
} }
const target_artifact = global.BUNDLER_CTX_MAP[controller.target_map.local_path]; const target_artifact = global.BUNDLER_CTX_MAP[controller.target_map.local_path];
if (!target_artifact.local_path) {
controller.controller.enqueue(reload_enqueue);
continue;
}
const mock_req = target_artifact.req const mock_req = target_artifact.req
? target_artifact.req.clone() ? target_artifact.req.clone()
: new Request(controller.page_url); : new Request(controller.page_url);
const { serverRes } = global.IS_SERVER_COMPONENT const page_component = global.IS_SERVER_COMPONENT
? await grabPageComponent({ ? await grabPageComponent({
req: mock_req, req: mock_req,
return_server_res_only: true, return_server_res_only: true,
is_hydration: true, is_hydration: true,
}) })
: {}; : {};
if (page_component instanceof Response) {
continue;
}
const { serverRes } = page_component;
const final_artifact = { const final_artifact = {
..._.omit(controller, ["controller"]), ..._.omit(controller, ["controller"]),
target_map: target_artifact, target_map: target_artifact,
@ -37,7 +57,7 @@ export default async function serverPostBuildFn() {
try { try {
let final_data = {}; let final_data = {};
if (global.ROOT_FILE_UPDATED) { if (global.ROOT_FILE_UPDATED) {
final_data = { reload: true }; final_data = reload_payload;
} }
else { else {
final_data = final_artifact; final_data = final_artifact;

View File

@ -15,6 +15,10 @@ export default async function watcherEsbuildCTX() {
if (filename.match(/^\.\w+/)) { if (filename.match(/^\.\w+/)) {
return; return;
} }
if (global.BUNDLER_CTX_DISPOSED) {
await fullRebuild({ msg: `Restarting Bundler ...` });
global.BUNDLER_CTX_DISPOSED = false;
}
if (filename.endsWith(AppData["BunextTmpFileExt"])) { if (filename.endsWith(AppData["BunextTmpFileExt"])) {
return; return;
} }
@ -50,7 +54,7 @@ export default async function watcherEsbuildCTX() {
if (filename.match(/.*\.server\.tsx?/)) { if (filename.match(/.*\.server\.tsx?/)) {
global.IS_SERVER_COMPONENT = true; global.IS_SERVER_COMPONENT = true;
} }
if (global.BUNDLER_CTX && !global.BUNDLER_CTX_DISPOSED) { if (global.BUNDLER_CTX) {
try { try {
await global.BUNDLER_CTX.rebuild(); await global.BUNDLER_CTX.rebuild();
} }
@ -58,10 +62,6 @@ export default async function watcherEsbuildCTX() {
console.log(`ESBUILD Rebuild Error =>`, error); console.log(`ESBUILD Rebuild Error =>`, error);
} }
} }
else {
await fullRebuild({ msg: `Restarting Bundler ...` });
global.BUNDLER_CTX_DISPOSED = false;
}
if (filename.match(/(404|500)\.tsx?/)) { if (filename.match(/(404|500)\.tsx?/)) {
for (let i = global.HMR_CONTROLLERS.length - 1; i >= 0; i--) { for (let i = global.HMR_CONTROLLERS.length - 1; i >= 0; i--) {
const controller = global.HMR_CONTROLLERS[i]; const controller = global.HMR_CONTROLLERS[i];

View File

@ -8,5 +8,5 @@ type Params = {
skip_server_res?: boolean; skip_server_res?: boolean;
is_hydration?: boolean; is_hydration?: boolean;
}; };
export default function grabPageComponent(params: Params): Promise<GrabPageComponentRes>; export default function grabPageComponent(params: Params): Promise<GrabPageComponentRes | Response>;
export {}; export {};

View File

@ -5,6 +5,7 @@ import { log } from "../../../utils/log";
import grabPageModules from "./grab-page-modules"; import grabPageModules from "./grab-page-modules";
import grabPageCombinedServerRes from "./grab-page-combined-server-res"; import grabPageCombinedServerRes from "./grab-page-combined-server-res";
import fullRebuild from "../full-rebuild"; import fullRebuild from "../full-rebuild";
import serverPostBuildFn from "../server-post-build-fn";
class NotFoundError extends Error { class NotFoundError extends Error {
status = 404; status = 404;
constructor(message) { constructor(message) {
@ -41,7 +42,6 @@ export default async function grabPageComponent(params) {
} }
const bundledMap = global.BUNDLER_CTX_MAP[file_path]; const bundledMap = global.BUNDLER_CTX_MAP[file_path];
if (!bundledMap?.path) { if (!bundledMap?.path) {
console.log(global.BUNDLER_CTX_MAP);
const errMsg = `No Bundled File Path for this request path!`; const errMsg = `No Bundled File Path for this request path!`;
log.error(errMsg); log.error(errMsg);
throw new Error(errMsg); throw new Error(errMsg);
@ -62,7 +62,7 @@ export default async function grabPageComponent(params) {
}); });
return { serverRes }; return { serverRes };
} }
const { component, module, serverRes, root_module } = await grabPageModules({ const page_modules = await grabPageModules({
file_path, file_path,
debug, debug,
query: match?.query, query: match?.query,
@ -70,7 +70,10 @@ export default async function grabPageComponent(params) {
url, url,
skip_server_res, skip_server_res,
}); });
global.IS_404_PAGE = false; if (page_modules instanceof Response) {
return page_modules;
}
const { component, module, serverRes, root_module } = page_modules;
return { return {
component, component,
serverRes, serverRes,
@ -94,8 +97,10 @@ export default async function grabPageComponent(params) {
...params, ...params,
retry: true, retry: true,
}); });
if (component_retried.success) { if (component_retried instanceof Response ||
component_retried.success) {
global.REBUILD_RETRIES = 0; global.REBUILD_RETRIES = 0;
await serverPostBuildFn();
return component_retried; return component_retried;
} }
} }

View File

@ -5,5 +5,5 @@ type Params = {
is404?: boolean; is404?: boolean;
url?: URL; url?: URL;
}; };
export default function grabPageErrorComponent({ error, routeParams, is404, url, }: Params): Promise<GrabPageComponentRes>; export default function grabPageErrorComponent({ error, routeParams, is404, url, }: Params): Promise<GrabPageComponentRes | Response>;
export {}; export {};

View File

@ -31,12 +31,16 @@ export default async function grabPageErrorComponent({ error, routeParams, is404
} }
const file_path = match.filePath; const file_path = match.filePath;
const bundledMap = global.BUNDLER_CTX_MAP?.[file_path]; const bundledMap = global.BUNDLER_CTX_MAP?.[file_path];
const { component, module, serverRes, root_module } = await grabPageModules({ const page_component = await grabPageModules({
file_path: file_path, file_path: file_path,
query: match?.query, query: match?.query,
routeParams, routeParams,
url, url,
}); });
if (page_component instanceof Response) {
return page_component;
}
const { component, module, serverRes, root_module } = page_component;
return { return {
component, component,
routeParams, routeParams,

View File

@ -1,4 +1,5 @@
import type { BunextPageModule, BunxRouteParams } from "../../../types"; import type { BunextPageModule, BunextPageModuleServerReturn, BunxRouteParams } from "../../../types";
import type { FC } from "react";
type Params = { type Params = {
file_path: string; file_path: string;
debug?: boolean; debug?: boolean;
@ -7,10 +8,11 @@ type Params = {
routeParams?: BunxRouteParams; routeParams?: BunxRouteParams;
skip_server_res?: boolean; skip_server_res?: boolean;
}; };
export default function grabPageModules({ file_path, debug, url, query, routeParams, skip_server_res, }: Params): Promise<{ type Return = {
component: import("react").FC; component: FC;
serverRes: import("../../../types").BunextPageModuleServerReturn | undefined; serverRes: BunextPageModuleServerReturn | undefined;
module: BunextPageModule; module: BunextPageModule;
root_module: BunextPageModule | undefined; root_module: BunextPageModule | undefined;
}>; };
export default function grabPageModules({ file_path, debug, url, query, routeParams, skip_server_res, }: Params): Promise<Return | Response>;
export {}; export {};

View File

@ -5,14 +5,6 @@ import grabRootFilePath from "./grab-root-file-path";
import grabPageCombinedServerRes from "./grab-page-combined-server-res"; import grabPageCombinedServerRes from "./grab-page-combined-server-res";
export default async function grabPageModules({ file_path, debug, url, query, routeParams, skip_server_res, }) { export default async function grabPageModules({ file_path, debug, url, query, routeParams, skip_server_res, }) {
const now = Date.now(); const now = Date.now();
const { root_file_path } = grabRootFilePath();
const root_module = root_file_path
? await import(`${root_file_path}?t=${now}`)
: undefined;
const module = await import(`${file_path}?t=${now}`);
if (debug) {
log.info(`module:`, module);
}
const { serverRes } = skip_server_res const { serverRes } = skip_server_res
? {} ? {}
: await grabPageCombinedServerRes({ : await grabPageCombinedServerRes({
@ -22,6 +14,19 @@ export default async function grabPageModules({ file_path, debug, url, query, ro
routeParams, routeParams,
url, url,
}); });
if (serverRes?.redirect?.destination) {
return Response.redirect(serverRes.redirect.destination, serverRes.redirect.permanent
? 301
: serverRes.redirect.status_code || 302);
}
const { root_file_path } = grabRootFilePath();
const root_module = root_file_path
? await import(`${root_file_path}?t=${now}`)
: undefined;
const module = await import(`${file_path}?t=${now}`);
if (debug) {
log.info(`module:`, module);
}
const { component } = (await grabPageBundledReactComponent({ const { component } = (await grabPageBundledReactComponent({
file_path, file_path,
})) || {}; })) || {};

View File

@ -23,6 +23,9 @@ export default async function handleWebPages({ req, }) {
const componentRes = await grabPageComponent({ const componentRes = await grabPageComponent({
req, req,
}); });
if (componentRes instanceof Response) {
return componentRes;
}
return await generateWebPageResponseFromComponentReturn({ return await generateWebPageResponseFromComponentReturn({
...componentRes, ...componentRes,
}); });
@ -32,6 +35,9 @@ export default async function handleWebPages({ req, }) {
const componentRes = await grabPageErrorComponent({ const componentRes = await grabPageErrorComponent({
error, error,
}); });
if (componentRes instanceof Response) {
return componentRes;
}
return await generateWebPageResponseFromComponentReturn(componentRes); return await generateWebPageResponseFromComponentReturn(componentRes);
} }
} }

View File

@ -285,6 +285,7 @@ export type GlobalHMRControllerObject = {
page_url: string; page_url: string;
target_map?: BundlerCTXMap; target_map?: BundlerCTXMap;
page_props?: any; page_props?: any;
page_reloaded?: boolean;
}; };
export type BunextCacheFileMeta = { export type BunextCacheFileMeta = {
date_created: number; date_created: number;

View File

@ -1,6 +1,6 @@
{ {
"name": "@moduletrace/bunext", "name": "@moduletrace/bunext",
"version": "1.0.76", "version": "1.0.77",
"main": "dist/index.js", "main": "dist/index.js",
"module": "index.ts", "module": "index.ts",
"dependencies": { "dependencies": {

View File

@ -4,7 +4,7 @@ import grabDirNames from "../../utils/grab-dir-names";
import isDevelopment from "../../utils/is-development"; import isDevelopment from "../../utils/is-development";
import tailwindEsbuildPlugin from "../server/web-pages/tailwind-esbuild-plugin"; import tailwindEsbuildPlugin from "../server/web-pages/tailwind-esbuild-plugin";
import grabClientHydrationScript from "./grab-client-hydration-script"; import grabClientHydrationScript from "./grab-client-hydration-script";
import type { PageFiles } from "../../types"; import type { BundlerCTXMap, PageFiles } from "../../types";
import path from "path"; import path from "path";
import virtualFilesPlugin from "./plugins/virtual-files-plugin"; import virtualFilesPlugin from "./plugins/virtual-files-plugin";
import esbuildCTXArtifactTracker from "./plugins/esbuild-ctx-artifact-tracker"; import esbuildCTXArtifactTracker from "./plugins/esbuild-ctx-artifact-tracker";
@ -12,7 +12,9 @@ import esbuildCTXArtifactTracker from "./plugins/esbuild-ctx-artifact-tracker";
const { HYDRATION_DST_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames(); const { HYDRATION_DST_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames();
type Params = { type Params = {
post_build_fn?: (params: { artifacts: any[] }) => Promise<void> | void; post_build_fn?: (params: {
artifacts: BundlerCTXMap[];
}) => Promise<void> | void;
}; };
export default async function allPagesESBuildContextBundler(params?: Params) { export default async function allPagesESBuildContextBundler(params?: Params) {

View File

@ -1,5 +1,3 @@
import { log } from "../../utils/log";
type Params = {}; type Params = {};
export default async function buildOnstartErrorHandler(params?: Params) { export default async function buildOnstartErrorHandler(params?: Params) {

View File

@ -89,7 +89,9 @@ export default async function bunextInit() {
if (is_dev) { if (is_dev) {
log.build(`Building Modules ...`); log.build(`Building Modules ...`);
await allPagesESBuildContextBundler({ await allPagesESBuildContextBundler({
post_build_fn: serverPostBuildFn, post_build_fn: () => {
serverPostBuildFn();
},
}); });
watcherEsbuildCTX(); watcherEsbuildCTX();
} else { } else {

View File

@ -22,7 +22,9 @@ export default async function fullRebuild(params?: { msg?: string }) {
global.SSR_BUNDLER_CTX = undefined; global.SSR_BUNDLER_CTX = undefined;
allPagesESBuildContextBundler({ allPagesESBuildContextBundler({
post_build_fn: serverPostBuildFn, post_build_fn: () => {
serverPostBuildFn();
},
}); });
} catch (error: any) { } catch (error: any) {
log.error(error); log.error(error);

View File

@ -2,33 +2,54 @@ import _ from "lodash";
import type { GlobalHMRControllerObject } from "../../types"; import type { GlobalHMRControllerObject } from "../../types";
import grabPageComponent from "./web-pages/grab-page-component"; import grabPageComponent from "./web-pages/grab-page-component";
export default async function serverPostBuildFn() { type Params = {
reload_all_controllers?: boolean;
};
export default async function serverPostBuildFn(params?: Params) {
if (!global.HMR_CONTROLLERS?.[0] || !global.BUNDLER_CTX_MAP) { if (!global.HMR_CONTROLLERS?.[0] || !global.BUNDLER_CTX_MAP) {
return; return;
} }
const reload_payload = { reload: true };
const reload_enqueue = `event: update\ndata: ${JSON.stringify(reload_payload)}\n\n`;
for (let i = global.HMR_CONTROLLERS.length - 1; i >= 0; i--) { for (let i = global.HMR_CONTROLLERS.length - 1; i >= 0; i--) {
const controller = global.HMR_CONTROLLERS[i]; const controller = global.HMR_CONTROLLERS[i];
if (!controller?.target_map?.local_path) { if (!controller) {
continue; continue;
} }
if (global.IS_404_PAGE) { if (!controller.target_map?.local_path) {
controller.controller.enqueue( // if (global.IS_404_PAGE) {
`event: update\ndata: ${JSON.stringify({ reload: true })}\n\n`, // controller.controller.enqueue(reload_enqueue);
); // }
// if (!global.HMR_CONTROLLERS[i].page_reloaded) {
// controller.controller.enqueue(reload_enqueue);
// global.HMR_CONTROLLERS[i].page_reloaded = true;
// }
continue;
}
if (params?.reload_all_controllers) {
controller.controller.enqueue(reload_enqueue);
continue; continue;
} }
const target_artifact = const target_artifact =
global.BUNDLER_CTX_MAP[controller.target_map.local_path]; global.BUNDLER_CTX_MAP[controller.target_map.local_path];
if (!target_artifact.local_path) {
controller.controller.enqueue(reload_enqueue);
continue;
}
const mock_req = target_artifact.req const mock_req = target_artifact.req
? target_artifact.req.clone() ? target_artifact.req.clone()
: new Request(controller.page_url); : new Request(controller.page_url);
const { serverRes } = global.IS_SERVER_COMPONENT const page_component = global.IS_SERVER_COMPONENT
? await grabPageComponent({ ? await grabPageComponent({
req: mock_req, req: mock_req,
return_server_res_only: true, return_server_res_only: true,
@ -36,6 +57,12 @@ export default async function serverPostBuildFn() {
}) })
: {}; : {};
if (page_component instanceof Response) {
continue;
}
const { serverRes } = page_component;
const final_artifact: Omit<GlobalHMRControllerObject, "controller"> = { const final_artifact: Omit<GlobalHMRControllerObject, "controller"> = {
..._.omit(controller, ["controller"]), ..._.omit(controller, ["controller"]),
target_map: target_artifact, target_map: target_artifact,
@ -53,7 +80,7 @@ export default async function serverPostBuildFn() {
let final_data: { [k: string]: any } = {}; let final_data: { [k: string]: any } = {};
if (global.ROOT_FILE_UPDATED) { if (global.ROOT_FILE_UPDATED) {
final_data = { reload: true }; final_data = reload_payload;
} else { } else {
final_data = final_artifact; final_data = final_artifact;
} }

View File

@ -21,6 +21,11 @@ export default async function watcherEsbuildCTX() {
return; return;
} }
if (global.BUNDLER_CTX_DISPOSED) {
await fullRebuild({ msg: `Restarting Bundler ...` });
global.BUNDLER_CTX_DISPOSED = false;
}
if (filename.endsWith(AppData["BunextTmpFileExt"])) { if (filename.endsWith(AppData["BunextTmpFileExt"])) {
return; return;
} }
@ -64,15 +69,12 @@ export default async function watcherEsbuildCTX() {
global.IS_SERVER_COMPONENT = true; global.IS_SERVER_COMPONENT = true;
} }
if (global.BUNDLER_CTX && !global.BUNDLER_CTX_DISPOSED) { if (global.BUNDLER_CTX) {
try { try {
await global.BUNDLER_CTX.rebuild(); await global.BUNDLER_CTX.rebuild();
} catch (error) { } catch (error) {
console.log(`ESBUILD Rebuild Error =>`, error); console.log(`ESBUILD Rebuild Error =>`, error);
} }
} else {
await fullRebuild({ msg: `Restarting Bundler ...` });
global.BUNDLER_CTX_DISPOSED = false;
} }
if (filename.match(/(404|500)\.tsx?/)) { if (filename.match(/(404|500)\.tsx?/)) {

View File

@ -6,6 +6,7 @@ import { log } from "../../../utils/log";
import grabPageModules from "./grab-page-modules"; import grabPageModules from "./grab-page-modules";
import grabPageCombinedServerRes from "./grab-page-combined-server-res"; import grabPageCombinedServerRes from "./grab-page-combined-server-res";
import fullRebuild from "../full-rebuild"; import fullRebuild from "../full-rebuild";
import serverPostBuildFn from "../server-post-build-fn";
class NotFoundError extends Error { class NotFoundError extends Error {
status = 404; status = 404;
@ -28,7 +29,7 @@ type Params = {
export default async function grabPageComponent( export default async function grabPageComponent(
params: Params, params: Params,
): Promise<GrabPageComponentRes> { ): Promise<GrabPageComponentRes | Response> {
const { const {
req, req,
file_path: passed_file_path, file_path: passed_file_path,
@ -77,7 +78,6 @@ export default async function grabPageComponent(
const bundledMap = global.BUNDLER_CTX_MAP[file_path]; const bundledMap = global.BUNDLER_CTX_MAP[file_path];
if (!bundledMap?.path) { if (!bundledMap?.path) {
console.log(global.BUNDLER_CTX_MAP);
const errMsg = `No Bundled File Path for this request path!`; const errMsg = `No Bundled File Path for this request path!`;
log.error(errMsg); log.error(errMsg);
throw new Error(errMsg); throw new Error(errMsg);
@ -103,17 +103,20 @@ export default async function grabPageComponent(
return { serverRes }; return { serverRes };
} }
const { component, module, serverRes, root_module } = const page_modules = await grabPageModules({
await grabPageModules({ file_path,
file_path, debug,
debug, query: match?.query,
query: match?.query, routeParams,
routeParams, url,
url, skip_server_res,
skip_server_res, });
});
global.IS_404_PAGE = false; if (page_modules instanceof Response) {
return page_modules;
}
const { component, module, serverRes, root_module } = page_modules;
return { return {
component, component,
@ -141,8 +144,12 @@ export default async function grabPageComponent(
retry: true, retry: true,
}); });
if (component_retried.success) { if (
component_retried instanceof Response ||
component_retried.success
) {
global.REBUILD_RETRIES = 0; global.REBUILD_RETRIES = 0;
await serverPostBuildFn();
return component_retried; return component_retried;
} }
} }

View File

@ -20,7 +20,7 @@ export default async function grabPageErrorComponent({
routeParams, routeParams,
is404, is404,
url, url,
}: Params): Promise<GrabPageComponentRes> { }: Params): Promise<GrabPageComponentRes | Response> {
const router = global.ROUTER; const router = global.ROUTER;
const { BUNX_ROOT_500_PRESET_COMPONENT, BUNX_ROOT_404_PRESET_COMPONENT } = const { BUNX_ROOT_500_PRESET_COMPONENT, BUNX_ROOT_404_PRESET_COMPONENT } =
@ -61,13 +61,18 @@ export default async function grabPageErrorComponent({
const bundledMap = global.BUNDLER_CTX_MAP?.[file_path]; const bundledMap = global.BUNDLER_CTX_MAP?.[file_path];
const { component, module, serverRes, root_module } = const page_component = await grabPageModules({
await grabPageModules({ file_path: file_path,
file_path: file_path, query: match?.query,
query: match?.query, routeParams,
routeParams, url,
url, });
});
if (page_component instanceof Response) {
return page_component;
}
const { component, module, serverRes, root_module } = page_component;
return { return {
component, component,

View File

@ -1,5 +1,6 @@
import type { import type {
BunextPageModule, BunextPageModule,
BunextPageModuleServerReturn,
BunextRootModule, BunextRootModule,
BunxRouteParams, BunxRouteParams,
} from "../../../types"; } from "../../../types";
@ -8,6 +9,7 @@ import _ from "lodash";
import { log } from "../../../utils/log"; import { log } from "../../../utils/log";
import grabRootFilePath from "./grab-root-file-path"; import grabRootFilePath from "./grab-root-file-path";
import grabPageCombinedServerRes from "./grab-page-combined-server-res"; import grabPageCombinedServerRes from "./grab-page-combined-server-res";
import type { FC } from "react";
type Params = { type Params = {
file_path: string; file_path: string;
@ -18,6 +20,13 @@ type Params = {
skip_server_res?: boolean; skip_server_res?: boolean;
}; };
type Return = {
component: FC;
serverRes: BunextPageModuleServerReturn | undefined;
module: BunextPageModule;
root_module: BunextPageModule | undefined;
};
export default async function grabPageModules({ export default async function grabPageModules({
file_path, file_path,
debug, debug,
@ -25,9 +34,28 @@ export default async function grabPageModules({
query, query,
routeParams, routeParams,
skip_server_res, skip_server_res,
}: Params) { }: Params): Promise<Return | Response> {
const now = Date.now(); const now = Date.now();
const { serverRes } = skip_server_res
? {}
: await grabPageCombinedServerRes({
file_path,
debug,
query,
routeParams,
url,
});
if (serverRes?.redirect?.destination) {
return Response.redirect(
serverRes.redirect.destination,
serverRes.redirect.permanent
? 301
: serverRes.redirect.status_code || 302,
);
}
const { root_file_path } = grabRootFilePath(); const { root_file_path } = grabRootFilePath();
const root_module: BunextRootModule | undefined = root_file_path const root_module: BunextRootModule | undefined = root_file_path
? await import(`${root_file_path}?t=${now}`) ? await import(`${root_file_path}?t=${now}`)
@ -39,16 +67,6 @@ export default async function grabPageModules({
log.info(`module:`, module); log.info(`module:`, module);
} }
const { serverRes } = skip_server_res
? {}
: await grabPageCombinedServerRes({
file_path,
debug,
query,
routeParams,
url,
});
const { component } = const { component } =
(await grabPageBundledReactComponent({ (await grabPageBundledReactComponent({
file_path, file_path,

View File

@ -35,6 +35,10 @@ export default async function handleWebPages({
req, req,
}); });
if (componentRes instanceof Response) {
return componentRes;
}
return await generateWebPageResponseFromComponentReturn({ return await generateWebPageResponseFromComponentReturn({
...componentRes, ...componentRes,
}); });
@ -45,6 +49,10 @@ export default async function handleWebPages({
error, error,
}); });
if (componentRes instanceof Response) {
return componentRes;
}
return await generateWebPageResponseFromComponentReturn(componentRes); return await generateWebPageResponseFromComponentReturn(componentRes);
} }
} }

View File

@ -324,6 +324,7 @@ export type GlobalHMRControllerObject = {
page_url: string; page_url: string;
target_map?: BundlerCTXMap; target_map?: BundlerCTXMap;
page_props?: any; page_props?: any;
page_reloaded?: boolean;
}; };
export type BunextCacheFileMeta = { export type BunextCacheFileMeta = {