Bugfix. Fix SSR pages filters. Remove dedicated API bundler, use SSR bundler for pages and api routes.

This commit is contained in:
Benjamin Toby 2026-04-12 06:48:10 +01:00
parent 532d0d6b56
commit 84d490b189
21 changed files with 131 additions and 138 deletions

View File

@ -8,35 +8,37 @@ const { BUNX_CWD_MODULE_CACHE_DIR } = grabDirNames();
export default async function apiRoutesContextBundler() { export default async function apiRoutesContextBundler() {
const pages = grabAllPages({ api_only: true }); const pages = grabAllPages({ api_only: true });
const dev = isDevelopment(); const dev = isDevelopment();
if (global.API_ROUTES_BUNDLER_CTX) { // if (global.API_ROUTES_BUNDLER_CTX) {
await global.API_ROUTES_BUNDLER_CTX.dispose(); // await global.API_ROUTES_BUNDLER_CTX.dispose();
global.API_ROUTES_BUNDLER_CTX = undefined; // global.API_ROUTES_BUNDLER_CTX = undefined;
} // }
global.API_ROUTES_BUNDLER_CTX = await esbuild.context({ // global.API_ROUTES_BUNDLER_CTX = await esbuild.context({
entryPoints: pages.map((p) => p.local_path), // entryPoints: pages.map((p) => p.local_path),
outdir: BUNX_CWD_MODULE_CACHE_DIR, // outdir: BUNX_CWD_MODULE_CACHE_DIR,
bundle: true, // bundle: true,
minify: !dev, // minify: !dev,
format: "esm", // format: "esm",
target: "esnext", // target: "esnext",
platform: "node", // platform: "node",
define: { // define: {
"process.env.NODE_ENV": JSON.stringify(dev ? "development" : "production"), // "process.env.NODE_ENV": JSON.stringify(
}, // dev ? "development" : "production",
entryNames: "api/[dir]/[hash]", // ),
metafile: true, // },
plugins: [ // entryNames: "api/[dir]/[hash]",
tailwindEsbuildPlugin, // metafile: true,
apiRoutesCTXArtifactTracker({ pages }), // plugins: [
], // tailwindEsbuildPlugin,
jsx: "automatic", // apiRoutesCTXArtifactTracker({ pages }),
external: [ // ],
"react", // jsx: "automatic",
"react-dom", // external: [
"react/jsx-runtime", // "react",
"react/jsx-dev-runtime", // "react-dom",
"bun:*", // "react/jsx-runtime",
], // "react/jsx-dev-runtime",
}); // "bun:*",
await global.API_ROUTES_BUNDLER_CTX.rebuild(); // ],
// });
// await global.API_ROUTES_BUNDLER_CTX.rebuild();
} }

View File

@ -5,7 +5,7 @@ export default async function buildOnstartErrorHandler(params) {
global.BUNDLER_CTX_DISPOSED = true; global.BUNDLER_CTX_DISPOSED = true;
global.RECOMPILING = false; global.RECOMPILING = false;
global.IS_SERVER_COMPONENT = false; global.IS_SERVER_COMPONENT = false;
await Promise.all([ Promise.all([
global.SSR_BUNDLER_CTX?.dispose(), global.SSR_BUNDLER_CTX?.dispose(),
global.BUNDLER_CTX?.dispose(), global.BUNDLER_CTX?.dispose(),
]); ]);

View File

@ -9,7 +9,7 @@ import ssrVirtualFilesPlugin from "./plugins/ssr-virtual-files-plugin";
import ssrCTXArtifactTracker from "./plugins/ssr-ctx-artifact-tracker"; import ssrCTXArtifactTracker from "./plugins/ssr-ctx-artifact-tracker";
const { BUNX_CWD_MODULE_CACHE_DIR } = grabDirNames(); const { BUNX_CWD_MODULE_CACHE_DIR } = grabDirNames();
export default async function pagesSSRContextBundler(params) { export default async function pagesSSRContextBundler(params) {
const pages = grabAllPages({ exclude_api: true }); const pages = grabAllPages();
const dev = isDevelopment(); const dev = isDevelopment();
if (global.SSR_BUNDLER_CTX) { if (global.SSR_BUNDLER_CTX) {
await global.SSR_BUNDLER_CTX.dispose(); await global.SSR_BUNDLER_CTX.dispose();
@ -61,6 +61,7 @@ export default async function pagesSSRContextBundler(params) {
"react-dom", "react-dom",
"react/jsx-runtime", "react/jsx-runtime",
"react/jsx-dev-runtime", "react/jsx-dev-runtime",
"bun:*",
], ],
// logLevel: "silent", // logLevel: "silent",
}); });

View File

@ -44,17 +44,21 @@ export default function apiRoutesCTXArtifactTracker({ pages }) {
url_path, url_path,
}; };
}); });
if (artifacts?.[0] && artifacts.length > 0) { // if (artifacts?.[0] && artifacts.length > 0) {
for (let i = 0; i < artifacts.length; i++) { // for (let i = 0; i < artifacts.length; i++) {
const artifact = artifacts[i]; // const artifact = artifacts[i];
if (artifact?.local_path && // if (
global.API_ROUTES_BUNDLER_CTX_MAP) { // artifact?.local_path &&
global.API_ROUTES_BUNDLER_CTX_MAP[artifact.local_path] = artifact; // global.API_ROUTES_BUNDLER_CTX_MAP
} // ) {
} // global.API_ROUTES_BUNDLER_CTX_MAP[
} // artifact.local_path
// const elapsed = (performance.now() - build_start).toFixed(0); // ] = artifact;
// log.success(`API Routes [Built] in ${elapsed}ms`); // }
// }
// }
const elapsed = (performance.now() - build_start).toFixed(0);
log.success(`API Routes [Built] in ${elapsed}ms`);
}); });
}, },
}; };

View File

@ -48,12 +48,6 @@ export default function esbuildCTXArtifactTracker({ entryToPage, post_build_fn,
else { else {
pagesSSRContextBundler(); pagesSSRContextBundler();
} }
if (global.API_ROUTES_BUNDLER_CTX) {
global.API_ROUTES_BUNDLER_CTX.rebuild();
}
else {
apiRoutesContextBundler();
}
}); });
}, },
}; };

View File

@ -1,6 +1,7 @@
import {} from "esbuild"; import {} from "esbuild";
import grabArtifactsFromBundledResults from "../grab-artifacts-from-bundled-result"; import grabArtifactsFromBundledResults from "../grab-artifacts-from-bundled-result";
import buildOnstartErrorHandler from "../build-on-start-error-handler"; import buildOnstartErrorHandler from "../build-on-start-error-handler";
import { log } from "../../../utils/log";
let build_start = 0; let build_start = 0;
let build_starts = 0; let build_starts = 0;
const MAX_BUILD_STARTS = 2; const MAX_BUILD_STARTS = 2;
@ -34,7 +35,11 @@ export default function ssrCTXArtifactTracker({ entryToPage, post_build_fn, }) {
artifact; artifact;
} }
} }
post_build_fn?.({ artifacts }); // post_build_fn?.({ artifacts });
// const elapsed = (performance.now() - build_start).toFixed(
// 0,
// );
// log.success(`SSR [Built] in ${elapsed}ms`);
} }
}); });
}, },

View File

@ -23,9 +23,6 @@ declare global {
var SSR_BUNDLER_CTX_MAP: { var SSR_BUNDLER_CTX_MAP: {
[k: string]: BundlerCTXMap; [k: string]: BundlerCTXMap;
}; };
var API_ROUTES_BUNDLER_CTX_MAP: {
[k: string]: BundlerCTXMap;
};
var BUNDLER_REBUILDS: 0; var BUNDLER_REBUILDS: 0;
var PAGES_SRC_WATCHER: FSWatcher | undefined; var PAGES_SRC_WATCHER: FSWatcher | undefined;
var CURRENT_VERSION: string | undefined; var CURRENT_VERSION: string | undefined;
@ -34,7 +31,6 @@ declare global {
var SKIPPED_BROWSER_MODULES: Set<string>; var SKIPPED_BROWSER_MODULES: Set<string>;
var BUNDLER_CTX: BuildContext | undefined; var BUNDLER_CTX: BuildContext | undefined;
var SSR_BUNDLER_CTX: BuildContext | undefined; var SSR_BUNDLER_CTX: BuildContext | undefined;
var API_ROUTES_BUNDLER_CTX: BuildContext | undefined;
var DIR_NAMES: ReturnType<typeof grabDirNames>; var DIR_NAMES: ReturnType<typeof grabDirNames>;
var REACT_IMPORTS_MAP: { var REACT_IMPORTS_MAP: {
imports: Record<string, string>; imports: Record<string, string>;

View File

@ -15,7 +15,7 @@ export default async function bunextInit() {
global.HMR_CONTROLLERS = []; global.HMR_CONTROLLERS = [];
global.BUNDLER_CTX_MAP = {}; global.BUNDLER_CTX_MAP = {};
global.SSR_BUNDLER_CTX_MAP = {}; global.SSR_BUNDLER_CTX_MAP = {};
global.API_ROUTES_BUNDLER_CTX_MAP = {}; // global.API_ROUTES_BUNDLER_CTX_MAP = {};
global.BUNDLER_REBUILDS = 0; global.BUNDLER_REBUILDS = 0;
global.REBUILD_RETRIES = 0; global.REBUILD_RETRIES = 0;
global.PAGE_FILES = []; global.PAGE_FILES = [];

View File

@ -30,8 +30,8 @@ export default async function ({ req }) {
}); });
let module; let module;
const now = Date.now(); const now = Date.now();
if (is_dev && global.API_ROUTES_BUNDLER_CTX_MAP?.[match.filePath]?.path) { if (is_dev && global.SSR_BUNDLER_CTX_MAP?.[match.filePath]?.path) {
const target_import = path.join(ROOT_DIR, global.API_ROUTES_BUNDLER_CTX_MAP[match.filePath].path); const target_import = path.join(ROOT_DIR, global.SSR_BUNDLER_CTX_MAP[match.filePath].path);
module = await import(`${target_import}?t=${now}`); module = await import(`${target_import}?t=${now}`);
} }
else { else {

View File

@ -2,7 +2,6 @@ import { existsSync, readdirSync, statSync } from "fs";
import grabDirNames from "./grab-dir-names"; import grabDirNames from "./grab-dir-names";
import path from "path"; import path from "path";
import AppNames from "./grab-app-names"; import AppNames from "./grab-app-names";
import pagePathTransform from "./page-path-transform";
import checkExcludedPatterns from "./check-excluded-patterns"; import checkExcludedPatterns from "./check-excluded-patterns";
export default function grabAllPages(params) { export default function grabAllPages(params) {
const { PAGES_DIR } = grabDirNames(); const { PAGES_DIR } = grabDirNames();
@ -32,18 +31,15 @@ function grabPageDirRecursively({ page_dir }) {
if (page.match(new RegExp(`${AppNames["RootPagesComponentName"]}`))) { if (page.match(new RegExp(`${AppNames["RootPagesComponentName"]}`))) {
continue; continue;
} }
if (checkExcludedPatterns({ path: page })) { if (checkExcludedPatterns({ path: full_page_path })) {
continue; continue;
} }
if (page.match(/\/api\//)) { if (page_name.match(/\.server\.tsx?/)) {
continue;
}
if (page_name.split(".").length > 2) {
continue; continue;
} }
const page_stat = statSync(full_page_path); const page_stat = statSync(full_page_path);
if (page_stat.isDirectory()) { if (page_stat.isDirectory()) {
if (checkExcludedPatterns({ path: page })) if (checkExcludedPatterns({ path: full_page_path }))
continue; continue;
const new_page_files = grabPageDirRecursively({ const new_page_files = grabPageDirRecursively({
page_dir: full_page_path, page_dir: full_page_path,

View File

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

View File

@ -11,39 +11,39 @@ export default async function apiRoutesContextBundler() {
const pages = grabAllPages({ api_only: true }); const pages = grabAllPages({ api_only: true });
const dev = isDevelopment(); const dev = isDevelopment();
if (global.API_ROUTES_BUNDLER_CTX) { // if (global.API_ROUTES_BUNDLER_CTX) {
await global.API_ROUTES_BUNDLER_CTX.dispose(); // await global.API_ROUTES_BUNDLER_CTX.dispose();
global.API_ROUTES_BUNDLER_CTX = undefined; // global.API_ROUTES_BUNDLER_CTX = undefined;
} // }
global.API_ROUTES_BUNDLER_CTX = await esbuild.context({ // global.API_ROUTES_BUNDLER_CTX = await esbuild.context({
entryPoints: pages.map((p) => p.local_path), // entryPoints: pages.map((p) => p.local_path),
outdir: BUNX_CWD_MODULE_CACHE_DIR, // outdir: BUNX_CWD_MODULE_CACHE_DIR,
bundle: true, // bundle: true,
minify: !dev, // minify: !dev,
format: "esm", // format: "esm",
target: "esnext", // target: "esnext",
platform: "node", // platform: "node",
define: { // define: {
"process.env.NODE_ENV": JSON.stringify( // "process.env.NODE_ENV": JSON.stringify(
dev ? "development" : "production", // dev ? "development" : "production",
), // ),
}, // },
entryNames: "api/[dir]/[hash]", // entryNames: "api/[dir]/[hash]",
metafile: true, // metafile: true,
plugins: [ // plugins: [
tailwindEsbuildPlugin, // tailwindEsbuildPlugin,
apiRoutesCTXArtifactTracker({ pages }), // apiRoutesCTXArtifactTracker({ pages }),
], // ],
jsx: "automatic", // jsx: "automatic",
external: [ // external: [
"react", // "react",
"react-dom", // "react-dom",
"react/jsx-runtime", // "react/jsx-runtime",
"react/jsx-dev-runtime", // "react/jsx-dev-runtime",
"bun:*", // "bun:*",
], // ],
}); // });
await global.API_ROUTES_BUNDLER_CTX.rebuild(); // await global.API_ROUTES_BUNDLER_CTX.rebuild();
} }

View File

@ -11,7 +11,7 @@ export default async function buildOnstartErrorHandler(params?: Params) {
global.RECOMPILING = false; global.RECOMPILING = false;
global.IS_SERVER_COMPONENT = false; global.IS_SERVER_COMPONENT = false;
await Promise.all([ Promise.all([
global.SSR_BUNDLER_CTX?.dispose(), global.SSR_BUNDLER_CTX?.dispose(),
global.BUNDLER_CTX?.dispose(), global.BUNDLER_CTX?.dispose(),
]); ]);

View File

@ -16,7 +16,7 @@ type Params = {
}; };
export default async function pagesSSRContextBundler(params?: Params) { export default async function pagesSSRContextBundler(params?: Params) {
const pages = grabAllPages({ exclude_api: true }); const pages = grabAllPages();
const dev = isDevelopment(); const dev = isDevelopment();
if (global.SSR_BUNDLER_CTX) { if (global.SSR_BUNDLER_CTX) {
@ -77,6 +77,7 @@ export default async function pagesSSRContextBundler(params?: Params) {
"react-dom", "react-dom",
"react/jsx-runtime", "react/jsx-runtime",
"react/jsx-dev-runtime", "react/jsx-dev-runtime",
"bun:*",
], ],
// logLevel: "silent", // logLevel: "silent",
}); });

View File

@ -66,22 +66,22 @@ export default function apiRoutesCTXArtifactTracker({ pages }: Params) {
}; };
}); });
if (artifacts?.[0] && artifacts.length > 0) { // if (artifacts?.[0] && artifacts.length > 0) {
for (let i = 0; i < artifacts.length; i++) { // for (let i = 0; i < artifacts.length; i++) {
const artifact = artifacts[i]; // const artifact = artifacts[i];
if ( // if (
artifact?.local_path && // artifact?.local_path &&
global.API_ROUTES_BUNDLER_CTX_MAP // global.API_ROUTES_BUNDLER_CTX_MAP
) { // ) {
global.API_ROUTES_BUNDLER_CTX_MAP[ // global.API_ROUTES_BUNDLER_CTX_MAP[
artifact.local_path // artifact.local_path
] = artifact; // ] = artifact;
} // }
} // }
} // }
// const elapsed = (performance.now() - build_start).toFixed(0); const elapsed = (performance.now() - build_start).toFixed(0);
// log.success(`API Routes [Built] in ${elapsed}ms`); log.success(`API Routes [Built] in ${elapsed}ms`);
}); });
}, },
}; };

View File

@ -31,6 +31,7 @@ export default function esbuildCTXArtifactTracker({
build.onStart(async () => { build.onStart(async () => {
build_starts++; build_starts++;
build_start = performance.now(); build_start = performance.now();
if (build_starts == MAX_BUILD_STARTS) { if (build_starts == MAX_BUILD_STARTS) {
await buildOnstartErrorHandler(); await buildOnstartErrorHandler();
} }
@ -74,12 +75,6 @@ export default function esbuildCTXArtifactTracker({
} else { } else {
pagesSSRContextBundler(); pagesSSRContextBundler();
} }
if (global.API_ROUTES_BUNDLER_CTX) {
global.API_ROUTES_BUNDLER_CTX.rebuild();
} else {
apiRoutesContextBundler();
}
}); });
}, },
}; };

View File

@ -2,6 +2,7 @@ import { type Plugin } from "esbuild";
import type { PageFiles } from "../../../types"; import type { PageFiles } from "../../../types";
import grabArtifactsFromBundledResults from "../grab-artifacts-from-bundled-result"; import grabArtifactsFromBundledResults from "../grab-artifacts-from-bundled-result";
import buildOnstartErrorHandler from "../build-on-start-error-handler"; import buildOnstartErrorHandler from "../build-on-start-error-handler";
import { log } from "../../../utils/log";
let build_start = 0; let build_start = 0;
let build_starts = 0; let build_starts = 0;
@ -56,7 +57,12 @@ export default function ssrCTXArtifactTracker({
} }
} }
post_build_fn?.({ artifacts }); // post_build_fn?.({ artifacts });
// const elapsed = (performance.now() - build_start).toFixed(
// 0,
// );
// log.success(`SSR [Built] in ${elapsed}ms`);
} }
}); });
}, },

View File

@ -33,7 +33,7 @@ declare global {
var LAST_BUILD_TIME: number; var LAST_BUILD_TIME: number;
var BUNDLER_CTX_MAP: { [k: string]: BundlerCTXMap }; var BUNDLER_CTX_MAP: { [k: string]: BundlerCTXMap };
var SSR_BUNDLER_CTX_MAP: { [k: string]: BundlerCTXMap }; var SSR_BUNDLER_CTX_MAP: { [k: string]: BundlerCTXMap };
var API_ROUTES_BUNDLER_CTX_MAP: { [k: string]: BundlerCTXMap }; // var API_ROUTES_BUNDLER_CTX_MAP: { [k: string]: BundlerCTXMap };
var BUNDLER_REBUILDS: 0; var BUNDLER_REBUILDS: 0;
var PAGES_SRC_WATCHER: FSWatcher | undefined; var PAGES_SRC_WATCHER: FSWatcher | undefined;
var CURRENT_VERSION: string | undefined; var CURRENT_VERSION: string | undefined;
@ -42,7 +42,7 @@ declare global {
var SKIPPED_BROWSER_MODULES: Set<string>; var SKIPPED_BROWSER_MODULES: Set<string>;
var BUNDLER_CTX: BuildContext | undefined; var BUNDLER_CTX: BuildContext | undefined;
var SSR_BUNDLER_CTX: BuildContext | undefined; var SSR_BUNDLER_CTX: BuildContext | undefined;
var API_ROUTES_BUNDLER_CTX: BuildContext | undefined; // var API_ROUTES_BUNDLER_CTX: BuildContext | undefined;
var DIR_NAMES: ReturnType<typeof grabDirNames>; var DIR_NAMES: ReturnType<typeof grabDirNames>;
var REACT_IMPORTS_MAP: { imports: Record<string, string> }; var REACT_IMPORTS_MAP: { imports: Record<string, string> };
var REACT_DOM_SERVER: any; var REACT_DOM_SERVER: any;
@ -60,7 +60,7 @@ export default async function bunextInit() {
global.HMR_CONTROLLERS = []; global.HMR_CONTROLLERS = [];
global.BUNDLER_CTX_MAP = {}; global.BUNDLER_CTX_MAP = {};
global.SSR_BUNDLER_CTX_MAP = {}; global.SSR_BUNDLER_CTX_MAP = {};
global.API_ROUTES_BUNDLER_CTX_MAP = {}; // global.API_ROUTES_BUNDLER_CTX_MAP = {};
global.BUNDLER_REBUILDS = 0; global.BUNDLER_REBUILDS = 0;
global.REBUILD_RETRIES = 0; global.REBUILD_RETRIES = 0;
global.PAGE_FILES = []; global.PAGE_FILES = [];

View File

@ -52,10 +52,10 @@ export default async function ({ req }: Params): Promise<Response | undefined> {
let module: any; let module: any;
const now = Date.now(); const now = Date.now();
if (is_dev && global.API_ROUTES_BUNDLER_CTX_MAP?.[match.filePath]?.path) { if (is_dev && global.SSR_BUNDLER_CTX_MAP?.[match.filePath]?.path) {
const target_import = path.join( const target_import = path.join(
ROOT_DIR, ROOT_DIR,
global.API_ROUTES_BUNDLER_CTX_MAP[match.filePath].path, global.SSR_BUNDLER_CTX_MAP[match.filePath].path,
); );
module = await import(`${target_import}?t=${now}`); module = await import(`${target_import}?t=${now}`);

View File

@ -1,5 +1,3 @@
import type { APIResponseObject } from "../types";
type Params = { type Params = {
path: string; path: string;
}; };

View File

@ -3,7 +3,6 @@ import grabDirNames from "./grab-dir-names";
import path from "path"; import path from "path";
import type { PageFiles } from "../types"; import type { PageFiles } from "../types";
import AppNames from "./grab-app-names"; import AppNames from "./grab-app-names";
import pagePathTransform from "./page-path-transform";
import checkExcludedPatterns from "./check-excluded-patterns"; import checkExcludedPatterns from "./check-excluded-patterns";
type Params = { type Params = {
@ -50,22 +49,18 @@ function grabPageDirRecursively({ page_dir }: { page_dir: string }) {
continue; continue;
} }
if (checkExcludedPatterns({ path: page })) { if (checkExcludedPatterns({ path: full_page_path })) {
continue; continue;
} }
if (page.match(/\/api\//)) { if (page_name.match(/\.server\.tsx?/)) {
continue;
}
if (page_name.split(".").length > 2) {
continue; continue;
} }
const page_stat = statSync(full_page_path); const page_stat = statSync(full_page_path);
if (page_stat.isDirectory()) { if (page_stat.isDirectory()) {
if (checkExcludedPatterns({ path: page })) continue; if (checkExcludedPatterns({ path: full_page_path })) continue;
const new_page_files = grabPageDirRecursively({ const new_page_files = grabPageDirRecursively({
page_dir: full_page_path, page_dir: full_page_path,
}); });