Fix memory leak in dev server
This commit is contained in:
+15
-1
@@ -77,8 +77,16 @@ export default async function genWebHTML({ component: Main, pageProps, bundledMa
|
||||
let htmlBody;
|
||||
let render_error;
|
||||
let has_render_error = false;
|
||||
const render_timeout_ms = global.BUNEXT_CONFIG.ssr_render_timeout_ms ||
|
||||
AppData["DefaultSSRRenderTimeoutMs"];
|
||||
// Without a deadline, a Suspense boundary that never settles keeps the
|
||||
// request (and its whole render tree) alive forever. The timer is
|
||||
// cleared once the render ends so finished requests don't linger.
|
||||
const render_abort = new AbortController();
|
||||
const render_timeout = setTimeout(() => render_abort.abort(new RenderTimeoutError(`Page render timed out after ${render_timeout_ms}ms`)), render_timeout_ms);
|
||||
try {
|
||||
const stream = await renderToReadableStream(final_component, {
|
||||
signal: render_abort.signal,
|
||||
onError(error) {
|
||||
if (error?.message?.includes('unique "key" prop'))
|
||||
return;
|
||||
@@ -86,12 +94,16 @@ export default async function genWebHTML({ component: Main, pageProps, bundledMa
|
||||
has_render_error = true;
|
||||
render_error = error;
|
||||
}
|
||||
original_console.error(error);
|
||||
// A timeout has no useful stack; it's logged upstream.
|
||||
if (!(error instanceof RenderTimeoutError)) {
|
||||
original_console.error(error);
|
||||
}
|
||||
},
|
||||
});
|
||||
htmlBody = await new Response(stream).text();
|
||||
}
|
||||
finally {
|
||||
clearTimeout(render_timeout);
|
||||
restoreConsole();
|
||||
}
|
||||
// A component crash during SSR must surface as a proper error (handled
|
||||
@@ -103,6 +115,8 @@ export default async function genWebHTML({ component: Main, pageProps, bundledMa
|
||||
html += htmlBody;
|
||||
return html;
|
||||
}
|
||||
class RenderTimeoutError extends Error {
|
||||
}
|
||||
let original_console = console;
|
||||
let silenced_renders = 0;
|
||||
/**
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
type Params = {
|
||||
file_path: string;
|
||||
out_file?: string;
|
||||
};
|
||||
export default function grabFilePathModule<T extends any = any>({ file_path, out_file, }: Params): Promise<T>;
|
||||
export {};
|
||||
@@ -1,30 +0,0 @@
|
||||
import isDevelopment from "../../../utils/is-development";
|
||||
import * as esbuild from "esbuild";
|
||||
import grabDirNames from "../../../utils/grab-dir-names";
|
||||
import path from "path";
|
||||
import tailwindEsbuildPlugin from "./tailwind-esbuild-plugin";
|
||||
export default async function grabFilePathModule({ file_path, out_file, }) {
|
||||
const dev = isDevelopment();
|
||||
const { BUNX_CWD_MODULE_CACHE_DIR } = grabDirNames();
|
||||
const target_cache_file_path = out_file ||
|
||||
path.join(BUNX_CWD_MODULE_CACHE_DIR, `${path.basename(file_path)}.js`);
|
||||
await esbuild.build({
|
||||
entryPoints: [file_path],
|
||||
bundle: true,
|
||||
format: "esm",
|
||||
target: "es2020",
|
||||
platform: "node",
|
||||
// external: ["react", "react-dom"],
|
||||
minify: true,
|
||||
define: {
|
||||
"process.env.NODE_ENV": JSON.stringify(dev ? "development" : "production"),
|
||||
},
|
||||
metafile: true,
|
||||
plugins: [tailwindEsbuildPlugin],
|
||||
jsx: "automatic",
|
||||
outfile: target_cache_file_path,
|
||||
});
|
||||
// Loader.registry.delete(target_cache_file_path);
|
||||
const module = await import(`${target_cache_file_path}?t=${Date.now()}`);
|
||||
return module;
|
||||
}
|
||||
Reference in New Issue
Block a user