Add retries to page component function error. Reload for all 404 pages
This commit is contained in:
@@ -16,73 +16,77 @@ type Params = {
|
||||
};
|
||||
|
||||
export default async function allPagesESBuildContextBundler(params?: Params) {
|
||||
const pages = grabAllPages({ exclude_api: true });
|
||||
try {
|
||||
const pages = grabAllPages({ exclude_api: true });
|
||||
|
||||
global.PAGE_FILES = pages;
|
||||
global.PAGE_FILES = pages;
|
||||
|
||||
const dev = isDevelopment();
|
||||
const dev = isDevelopment();
|
||||
|
||||
const entryToPage = new Map<string, PageFiles & { tsx: string }>();
|
||||
const entryToPage = new Map<string, PageFiles & { tsx: string }>();
|
||||
|
||||
for (const page of pages) {
|
||||
const tsx = await grabClientHydrationScript({
|
||||
page_local_path: page.local_path,
|
||||
});
|
||||
for (const page of pages) {
|
||||
const tsx = await grabClientHydrationScript({
|
||||
page_local_path: page.local_path,
|
||||
});
|
||||
|
||||
if (!tsx) continue;
|
||||
if (!tsx) continue;
|
||||
|
||||
const entryFile = path.join(
|
||||
BUNX_HYDRATION_SRC_DIR,
|
||||
`${page.url_path}.tsx`,
|
||||
const entryFile = path.join(
|
||||
BUNX_HYDRATION_SRC_DIR,
|
||||
`${page.url_path}.tsx`,
|
||||
);
|
||||
|
||||
// await Bun.write(entryFile, txt, { createPath: true });
|
||||
entryToPage.set(entryFile, { ...page, tsx });
|
||||
}
|
||||
|
||||
const entryPoints = [...entryToPage.keys()].map(
|
||||
(e) => `hydration-virtual:${e}`,
|
||||
);
|
||||
|
||||
// await Bun.write(entryFile, txt, { createPath: true });
|
||||
entryToPage.set(entryFile, { ...page, tsx });
|
||||
global.BUNDLER_CTX = await esbuild.context({
|
||||
entryPoints,
|
||||
outdir: HYDRATION_DST_DIR,
|
||||
bundle: true,
|
||||
minify: !dev,
|
||||
format: "esm",
|
||||
target: "es2020",
|
||||
platform: "browser",
|
||||
define: {
|
||||
"process.env.NODE_ENV": JSON.stringify(
|
||||
dev ? "development" : "production",
|
||||
),
|
||||
},
|
||||
entryNames: "[dir]/[hash]",
|
||||
metafile: true,
|
||||
plugins: [
|
||||
forceExternalReact(),
|
||||
tailwindEsbuildPlugin,
|
||||
virtualFilesPlugin({
|
||||
entryToPage,
|
||||
}),
|
||||
esbuildCTXArtifactTracker({
|
||||
entryToPage,
|
||||
post_build_fn: params?.post_build_fn,
|
||||
}),
|
||||
],
|
||||
jsx: "automatic",
|
||||
splitting: true,
|
||||
treeShaking: true,
|
||||
external: [
|
||||
"react",
|
||||
"react-dom",
|
||||
"react-dom/client",
|
||||
"react/jsx-runtime",
|
||||
"react/jsx-dev-runtime",
|
||||
],
|
||||
});
|
||||
|
||||
await global.BUNDLER_CTX.rebuild();
|
||||
} catch (error) {
|
||||
console.log(`ESBUILD Error =>`, error);
|
||||
}
|
||||
|
||||
const entryPoints = [...entryToPage.keys()].map(
|
||||
(e) => `hydration-virtual:${e}`,
|
||||
);
|
||||
|
||||
global.BUNDLER_CTX = await esbuild.context({
|
||||
entryPoints,
|
||||
outdir: HYDRATION_DST_DIR,
|
||||
bundle: true,
|
||||
minify: !dev,
|
||||
format: "esm",
|
||||
target: "es2020",
|
||||
platform: "browser",
|
||||
define: {
|
||||
"process.env.NODE_ENV": JSON.stringify(
|
||||
dev ? "development" : "production",
|
||||
),
|
||||
},
|
||||
entryNames: "[dir]/[hash]",
|
||||
metafile: true,
|
||||
plugins: [
|
||||
forceExternalReact(),
|
||||
tailwindEsbuildPlugin,
|
||||
virtualFilesPlugin({
|
||||
entryToPage,
|
||||
}),
|
||||
esbuildCTXArtifactTracker({
|
||||
entryToPage,
|
||||
post_build_fn: params?.post_build_fn,
|
||||
}),
|
||||
],
|
||||
jsx: "automatic",
|
||||
splitting: true,
|
||||
treeShaking: true,
|
||||
external: [
|
||||
"react",
|
||||
"react-dom",
|
||||
"react-dom/client",
|
||||
"react/jsx-runtime",
|
||||
"react/jsx-dev-runtime",
|
||||
],
|
||||
});
|
||||
|
||||
await global.BUNDLER_CTX.rebuild();
|
||||
}
|
||||
|
||||
function forceExternalReact(): esbuild.Plugin {
|
||||
|
||||
@@ -46,6 +46,8 @@ declare global {
|
||||
var REACT_DOM_SERVER: any;
|
||||
var REACT_DOM_MODULE_CACHE: Map<string, { main: any; css: string }>;
|
||||
var BUNDLER_CTX_DISPOSED: boolean | undefined;
|
||||
var REBUILD_RETRIES: number;
|
||||
var IS_404_PAGE: boolean;
|
||||
}
|
||||
|
||||
const dirNames = grabDirNames();
|
||||
@@ -56,6 +58,7 @@ export default async function bunextInit() {
|
||||
global.BUNDLER_CTX_MAP = {};
|
||||
global.SSR_BUNDLER_CTX_MAP = {};
|
||||
global.BUNDLER_REBUILDS = 0;
|
||||
global.REBUILD_RETRIES = 0;
|
||||
global.PAGE_FILES = [];
|
||||
global.SKIPPED_BROWSER_MODULES = new Set<string>();
|
||||
global.DIR_NAMES = dirNames;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { log } from "../../utils/log";
|
||||
import allPagesESBuildContextBundler from "../bundler/all-pages-esbuild-context-bundler";
|
||||
import serverPostBuildFn from "./server-post-build-fn";
|
||||
import watcherEsbuildCTX from "./watcher-esbuild-ctx";
|
||||
|
||||
export default async function fullRebuild(params?: { msg?: string }) {
|
||||
try {
|
||||
const { msg } = params || {};
|
||||
|
||||
global.RECOMPILING = true;
|
||||
|
||||
if (msg) {
|
||||
log.watch(msg);
|
||||
}
|
||||
|
||||
global.ROUTER.reload();
|
||||
|
||||
await global.BUNDLER_CTX?.dispose();
|
||||
global.BUNDLER_CTX = undefined;
|
||||
global.BUNDLER_CTX_MAP = {};
|
||||
|
||||
await global.SSR_BUNDLER_CTX?.dispose();
|
||||
global.SSR_BUNDLER_CTX = undefined;
|
||||
global.SSR_BUNDLER_CTX_MAP = {};
|
||||
|
||||
allPagesESBuildContextBundler({
|
||||
post_build_fn: serverPostBuildFn,
|
||||
});
|
||||
} catch (error: any) {
|
||||
log.error(error);
|
||||
}
|
||||
|
||||
if (global.PAGES_SRC_WATCHER) {
|
||||
global.PAGES_SRC_WATCHER.close();
|
||||
watcherEsbuildCTX();
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,13 @@ export default async function serverPostBuildFn() {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (global.IS_404_PAGE) {
|
||||
controller.controller.enqueue(
|
||||
`event: update\ndata: ${JSON.stringify({ reload: true })}\n\n`,
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const target_artifact =
|
||||
global.BUNDLER_CTX_MAP[controller.target_map.local_path];
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import grabDirNames from "../../utils/grab-dir-names";
|
||||
import { log } from "../../utils/log";
|
||||
import allPagesESBuildContextBundler from "../bundler/all-pages-esbuild-context-bundler";
|
||||
import serverPostBuildFn from "./server-post-build-fn";
|
||||
import fullRebuild from "./full-rebuild";
|
||||
|
||||
const { ROOT_DIR } = grabDirNames();
|
||||
|
||||
@@ -49,9 +50,13 @@ export default async function watcherEsbuildCTX() {
|
||||
}
|
||||
|
||||
const target_files_match = /\.(tsx?|jsx?|css)$/;
|
||||
const rebuild_skip_paths = /\/pages\/api\//;
|
||||
|
||||
if (event !== "rename") {
|
||||
if (filename.match(target_files_match)) {
|
||||
if (
|
||||
filename.match(target_files_match) &&
|
||||
!filename.match(rebuild_skip_paths)
|
||||
) {
|
||||
if (global.RECOMPILING) return;
|
||||
global.RECOMPILING = true;
|
||||
|
||||
@@ -60,7 +65,11 @@ export default async function watcherEsbuildCTX() {
|
||||
}
|
||||
|
||||
if (global.BUNDLER_CTX && !global.BUNDLER_CTX_DISPOSED) {
|
||||
await global.BUNDLER_CTX.rebuild();
|
||||
try {
|
||||
await global.BUNDLER_CTX.rebuild();
|
||||
} catch (error) {
|
||||
console.log(`ESBUILD Rebuild Error =>`, error);
|
||||
}
|
||||
} else {
|
||||
await fullRebuild({ msg: `Restarting Bundler ...` });
|
||||
global.BUNDLER_CTX_DISPOSED = false;
|
||||
@@ -114,39 +123,6 @@ export default async function watcherEsbuildCTX() {
|
||||
global.PAGES_SRC_WATCHER = pages_src_watcher;
|
||||
}
|
||||
|
||||
async function fullRebuild(params?: { msg?: string }) {
|
||||
try {
|
||||
const { msg } = params || {};
|
||||
|
||||
global.RECOMPILING = true;
|
||||
|
||||
if (msg) {
|
||||
log.watch(msg);
|
||||
}
|
||||
|
||||
global.ROUTER.reload();
|
||||
|
||||
await global.BUNDLER_CTX?.dispose();
|
||||
global.BUNDLER_CTX = undefined;
|
||||
global.BUNDLER_CTX_MAP = {};
|
||||
|
||||
await global.SSR_BUNDLER_CTX?.dispose();
|
||||
global.SSR_BUNDLER_CTX = undefined;
|
||||
global.SSR_BUNDLER_CTX_MAP = {};
|
||||
|
||||
allPagesESBuildContextBundler({
|
||||
post_build_fn: serverPostBuildFn,
|
||||
});
|
||||
} catch (error: any) {
|
||||
log.error(error);
|
||||
}
|
||||
|
||||
if (global.PAGES_SRC_WATCHER) {
|
||||
global.PAGES_SRC_WATCHER.close();
|
||||
watcherEsbuildCTX();
|
||||
}
|
||||
}
|
||||
|
||||
function reloadWatcher() {
|
||||
if (global.PAGES_SRC_WATCHER) {
|
||||
global.PAGES_SRC_WATCHER.close();
|
||||
|
||||
@@ -5,6 +5,7 @@ import _ from "lodash";
|
||||
import { log } from "../../../utils/log";
|
||||
import grabPageModules from "./grab-page-modules";
|
||||
import grabPageCombinedServerRes from "./grab-page-combined-server-res";
|
||||
import fullRebuild from "../full-rebuild";
|
||||
|
||||
class NotFoundError extends Error {
|
||||
status = 404;
|
||||
@@ -19,17 +20,22 @@ type Params = {
|
||||
req?: Request;
|
||||
file_path?: string;
|
||||
debug?: boolean;
|
||||
retry?: boolean;
|
||||
return_server_res_only?: boolean;
|
||||
skip_server_res?: boolean;
|
||||
};
|
||||
|
||||
export default async function grabPageComponent({
|
||||
req,
|
||||
file_path: passed_file_path,
|
||||
debug,
|
||||
return_server_res_only,
|
||||
skip_server_res,
|
||||
}: Params): Promise<GrabPageComponentRes> {
|
||||
export default async function grabPageComponent(
|
||||
params: Params,
|
||||
): Promise<GrabPageComponentRes> {
|
||||
const {
|
||||
req,
|
||||
file_path: passed_file_path,
|
||||
debug,
|
||||
return_server_res_only,
|
||||
skip_server_res,
|
||||
} = params;
|
||||
|
||||
const url = req?.url ? new URL(req.url) : undefined;
|
||||
const router = global.ROUTER;
|
||||
|
||||
@@ -101,6 +107,8 @@ export default async function grabPageComponent({
|
||||
skip_server_res,
|
||||
});
|
||||
|
||||
global.IS_404_PAGE = false;
|
||||
|
||||
return {
|
||||
component,
|
||||
serverRes,
|
||||
@@ -108,6 +116,7 @@ export default async function grabPageComponent({
|
||||
module,
|
||||
bundledMap,
|
||||
root_module,
|
||||
success: true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
const is404 =
|
||||
@@ -115,7 +124,29 @@ export default async function grabPageComponent({
|
||||
error?.name === "NotFoundError" ||
|
||||
error?.status === 404;
|
||||
|
||||
if (!is404) {
|
||||
if (!params.retry) {
|
||||
while (global.REBUILD_RETRIES < 2) {
|
||||
global.REBUILD_RETRIES = global.REBUILD_RETRIES + 1;
|
||||
|
||||
await fullRebuild();
|
||||
await Bun.sleep(200);
|
||||
const component_retried = await grabPageComponent({
|
||||
...params,
|
||||
retry: true,
|
||||
});
|
||||
|
||||
if (component_retried.success) {
|
||||
global.REBUILD_RETRIES = 0;
|
||||
return component_retried;
|
||||
}
|
||||
}
|
||||
|
||||
global.REBUILD_RETRIES = 0;
|
||||
}
|
||||
|
||||
if (is404) {
|
||||
global.IS_404_PAGE = true;
|
||||
} else {
|
||||
log.error(`Error Grabbing Page Component: ${error.message}`);
|
||||
log.error(`Page: ${passed_file_path || url?.pathname}`);
|
||||
}
|
||||
@@ -128,34 +159,3 @@ export default async function grabPageComponent({
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// let root_module: any;
|
||||
|
||||
// if (root_file) {
|
||||
// if (isDevelopment()) {
|
||||
// root_module = await grabFilePathModule({
|
||||
// file_path: root_file,
|
||||
// });
|
||||
// } else {
|
||||
// root_module = root_file ? await import(root_file) : undefined;
|
||||
// }
|
||||
// }
|
||||
|
||||
// const RootComponent = root_module?.default as FC<any> | undefined;
|
||||
|
||||
// let module: BunextPageModule;
|
||||
|
||||
// if (isDevelopment()) {
|
||||
// module = await grabFilePathModule({ file_path });
|
||||
// } else {
|
||||
// module = await import(file_path);
|
||||
// }
|
||||
|
||||
// const Component = main_module.default as FC<any>;
|
||||
// const component = RootComponent ? (
|
||||
// <RootComponent {...serverRes}>
|
||||
// <Component {...serverRes} />
|
||||
// </RootComponent>
|
||||
// ) : (
|
||||
// <Component {...serverRes} />
|
||||
// );
|
||||
|
||||
@@ -284,6 +284,7 @@ export type GrabPageComponentRes = {
|
||||
module?: BunextPageModule;
|
||||
root_module?: BunextRootModule;
|
||||
debug?: boolean;
|
||||
success?: boolean;
|
||||
};
|
||||
|
||||
export type BunextRootModule = BunextPageModule;
|
||||
|
||||
Reference in New Issue
Block a user