Fix build lags

This commit is contained in:
2026-10-02 14:48:38 +01:00
parent 17a5c3df01
commit 8fa5b64b48
38 changed files with 1390 additions and 1238 deletions
+71 -45
View File
@@ -9,9 +9,23 @@ import virtualFilesPlugin from "./plugins/virtual-files-plugin";
import esbuildCTXArtifactTracker from "./plugins/esbuild-ctx-artifact-tracker";
import { logBuildErrorsOnce, } from "../../utils/build-error-log";
import { log } from "../../utils/log";
import grabRootFilePath from "../server/web-pages/grab-root-file-path";
const { HYDRATION_DST_DIR, BUNX_HYDRATION_SRC_DIR } = grabDirNames();
// Snapshot of the entry key set + root file presence of the last build.
// When it differs from the freshly computed set, the esbuild context must
// be recreated (entry points are fixed at context creation).
let last_entry_keys = undefined;
let last_root_file_path = undefined;
function arraysEqual(a, b) {
if (a.length !== b.length)
return false;
for (let i = 0; i < a.length; i++) {
if (a[i] !== b[i])
return false;
}
return true;
}
export default async function allPagesESBuildContextBundler(params) {
const _t0 = Date.now();
try {
const pages = grabAllPages({ exclude_api: true });
global.BUNEXT_PAGE_FILES = pages;
@@ -25,53 +39,65 @@ export default async function allPagesESBuildContextBundler(params) {
continue;
}
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}`);
// This is a brand-new context: wipe the previous context's failure
// history so the "2 failed starts => dispose" guard starts fresh.
global.BUNEXT_MAIN_CTX_BUILD_STARTS = 0;
global.BUNEXT_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,
build_only: params?.build_only || params?.start,
}),
],
jsx: "automatic",
splitting: true,
treeShaking: true,
external: [
"react",
"react-dom",
"react-dom/client",
"react/jsx-runtime",
"react/jsx-dev-runtime",
...(global.BUNEXT_CONFIG.page_compiler_excludes || []),
],
// esbuild's own error logging prints per attempt; the
// artifact-tracker plugin reports errors (deduped, once) itself.
logLevel: "silent",
});
const entry_keys = [...entryToPage.keys()].sort();
const { root_file_path } = grabRootFilePath();
const structure_changed = !global.BUNEXT_BUNDLER_CTX ||
global.BUNEXT_BUNDLER_CTX_DISPOSED ||
!last_entry_keys ||
!arraysEqual(last_entry_keys, entry_keys) ||
last_root_file_path !== root_file_path;
if (structure_changed) {
try {
await global.BUNEXT_BUNDLER_CTX?.dispose();
}
catch (error) { }
global.BUNEXT_BUNDLER_CTX = undefined;
global.BUNEXT_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,
build_only: params?.build_only || params?.start,
}),
],
jsx: "automatic",
splitting: true,
treeShaking: true,
external: [
"react",
"react-dom",
"react-dom/client",
"react/jsx-runtime",
"react/jsx-dev-runtime",
...(global.BUNEXT_CONFIG.page_compiler_excludes || []),
],
// esbuild's own error logging prints per attempt; the
// artifact-tracker plugin reports errors (deduped, once) itself.
logLevel: "silent",
});
last_entry_keys = entry_keys;
last_root_file_path = root_file_path;
}
await global.BUNEXT_BUNDLER_CTX.rebuild();
}
catch (error) {