From 7dbd1f7e12eef724a50c3102403133a5a5bfb0eb Mon Sep 17 00:00:00 2001 From: Benjamin Toby Date: Tue, 31 Mar 2026 06:57:44 +0100 Subject: [PATCH] Remove esm.sh externals --- dist/commands/build/index.js | 3 - dist/commands/index.js | 2 +- .../all-pages-esbuild-context-bundler.js | 15 ++-- dist/functions/bunext-init.d.ts | 2 + dist/functions/bunext-init.js | 4 +- dist/functions/server/bunext-req-handler.js | 2 +- .../server/handle-bunext-public-assets.js | 45 ++++++++++-- dist/functions/server/handle-public.d.ts | 3 + dist/functions/server/handle-public.js | 19 ++--- dist/functions/server/watcher-esbuild-ctx.js | 1 - .../server/web-pages/generate-web-html.js | 70 ++++++++++-------- dist/types/index.d.ts | 36 +++++----- dist/utils/grab-dir-names.js | 71 +++++++++++++++++++ package.json | 2 +- src/commands/index.ts | 2 +- .../all-pages-esbuild-context-bundler.ts | 15 ++-- src/functions/server/watcher-esbuild-ctx.ts | 1 - .../server/web-pages/generate-web-html.tsx | 41 +++++++---- 18 files changed, 232 insertions(+), 102 deletions(-) diff --git a/dist/commands/build/index.js b/dist/commands/build/index.js index 83b6340..095abeb 100644 --- a/dist/commands/build/index.js +++ b/dist/commands/build/index.js @@ -1,11 +1,8 @@ import { Command } from "commander"; import { log } from "../../utils/log"; import init from "../../functions/init"; -// import rewritePagesModule from "../../utils/rewrite-pages-module"; -import allPagesBunBundler from "../../functions/bundler/all-pages-bun-bundler"; import grabDirNames from "../../utils/grab-dir-names"; import { rmSync } from "fs"; -import allPagesBundler from "../../functions/bundler/all-pages-bundler"; import allPagesESBuildContextBundler from "../../functions/bundler/all-pages-esbuild-context-bundler"; const { HYDRATION_DST_DIR, BUNX_CWD_PAGES_REWRITE_DIR } = grabDirNames(); export default function () { diff --git a/dist/commands/index.js b/dist/commands/index.js index 924a72b..4e2b5f2 100644 --- a/dist/commands/index.js +++ b/dist/commands/index.js @@ -11,7 +11,7 @@ import rewritePages from "./rewrite-pages"; program .name(`bunext`) .description(`A React Next JS replacement built with bun JS`) - .version(`1.0.0`); + .version(`1.0.43`); /** * # Declare Commands */ diff --git a/dist/functions/bundler/all-pages-esbuild-context-bundler.js b/dist/functions/bundler/all-pages-esbuild-context-bundler.js index b37c72b..4c61601 100644 --- a/dist/functions/bundler/all-pages-esbuild-context-bundler.js +++ b/dist/functions/bundler/all-pages-esbuild-context-bundler.js @@ -53,13 +53,14 @@ export default async function allPagesESBuildContextBundler(params) { logLevel: "silent", // logLevel: "silent", // logLevel: dev ? "error" : "silent", - external: [ - "react", - "react-dom", - "react-dom/client", - "react/jsx-runtime", - "react/jsx-dev-runtime", - ], + // external: [ + // "react", + // "react-dom", + // "react-dom/client", + // "react/jsx-runtime", + // "react/jsx-dev-runtime", + // ], + // jsxDev: dev, }); await global.BUNDLER_CTX.rebuild(); } diff --git a/dist/functions/bunext-init.d.ts b/dist/functions/bunext-init.d.ts index 776473e..76c3d5a 100644 --- a/dist/functions/bunext-init.d.ts +++ b/dist/functions/bunext-init.d.ts @@ -1,5 +1,6 @@ import type { BundlerCTXMap, BunextConfig, GlobalHMRControllerObject, PageFiles } from "../types"; import type { FileSystemRouter, Server } from "bun"; +import grabDirNames from "../utils/grab-dir-names"; import { type FSWatcher } from "fs"; import type { BuildContext } from "esbuild"; /** @@ -23,5 +24,6 @@ declare global { var ROOT_FILE_UPDATED: boolean; var SKIPPED_BROWSER_MODULES: Set; var BUNDLER_CTX: BuildContext | undefined; + var DIR_NAMES: ReturnType; } export default function bunextInit(): Promise; diff --git a/dist/functions/bunext-init.js b/dist/functions/bunext-init.js index 7193ac7..288daa8 100644 --- a/dist/functions/bunext-init.js +++ b/dist/functions/bunext-init.js @@ -5,13 +5,15 @@ import isDevelopment from "../utils/is-development"; import { log } from "../utils/log"; import cron from "./server/cron"; import watcherEsbuildCTX from "./server/watcher-esbuild-ctx"; -const { PAGES_DIR } = grabDirNames(); +const dirNames = grabDirNames(); +const { PAGES_DIR } = dirNames; export default async function bunextInit() { global.HMR_CONTROLLERS = []; global.BUNDLER_CTX_MAP = {}; global.BUNDLER_REBUILDS = 0; global.PAGE_FILES = []; global.SKIPPED_BROWSER_MODULES = new Set(); + global.DIR_NAMES = dirNames; await init(); log.banner(); const router = new Bun.FileSystemRouter({ diff --git a/dist/functions/server/bunext-req-handler.js b/dist/functions/server/bunext-req-handler.js index 2413196..ad5fd51 100644 --- a/dist/functions/server/bunext-req-handler.js +++ b/dist/functions/server/bunext-req-handler.js @@ -32,7 +32,7 @@ export default async function bunextRequestHandler({ req: initial_req, server, } if (url.pathname === "/__hmr" && is_dev) { response = await handleHmr({ req }); } - else if (url.pathname.startsWith("/.bunext/public/pages")) { + else if (url.pathname.startsWith("/.bunext")) { response = await handleBunextPublicAssets({ req }); } else if (url.pathname.startsWith("/api/")) { diff --git a/dist/functions/server/handle-bunext-public-assets.js b/dist/functions/server/handle-bunext-public-assets.js index e4236b4..f749bde 100644 --- a/dist/functions/server/handle-bunext-public-assets.js +++ b/dist/functions/server/handle-bunext-public-assets.js @@ -2,22 +2,53 @@ import grabDirNames from "../../utils/grab-dir-names"; import path from "path"; import isDevelopment from "../../utils/is-development"; import { existsSync } from "fs"; +import { readFileResponse } from "./handle-public"; const { HYDRATION_DST_DIR } = grabDirNames(); export default async function ({ req }) { try { const is_dev = isDevelopment(); const url = new URL(req.url); + // switch (url.pathname) { + // case "/.bunext/react": + // return readFileResponse({ + // file_path: is_dev + // ? global.DIR_NAMES.REACT_DEVELOPMENT_MODULE + // : global.DIR_NAMES.REACT_PRODUCTION_MODULE, + // }); + // case "/.bunext/react-dom": + // return readFileResponse({ + // file_path: is_dev + // ? global.DIR_NAMES.REACT_DOM_DEVELOPMENT_MODULE + // : global.DIR_NAMES.REACT_DOM_PRODUCTION_MODULE, + // }); + // case "/.bunext/react-dom-client": + // return readFileResponse({ + // file_path: is_dev + // ? global.DIR_NAMES.REACT_DOM_CLIENT_DEVELOPMENT_MODULE + // : global.DIR_NAMES.REACT_DOM_CLIENT_PRODUCTION_MODULE, + // }); + // case "/.bunext/react-jsx-runtime": + // return readFileResponse({ + // file_path: is_dev + // ? global.DIR_NAMES.REACT_JSX_RUNTIME_DEVELOPMENT_MODULE + // : global.DIR_NAMES.REACT_JSX_RUNTIME_PRODUCTION_MODULE, + // }); + // case "/.bunext/react-jsx-dev-runtime": + // return readFileResponse({ + // file_path: is_dev + // ? global.DIR_NAMES + // .REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE + // : global.DIR_NAMES + // .REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE, + // }); + // default: + // break; + // } const file_path = path.join(HYDRATION_DST_DIR, url.pathname.replace(/\/\.bunext\/public\/pages\//, "")); if (!file_path.startsWith(HYDRATION_DST_DIR + path.sep)) { return new Response("Forbidden", { status: 403 }); } - if (!existsSync(file_path)) { - return new Response(`File Doesn't Exist`, { - status: 404, - }); - } - const file = Bun.file(file_path); - return new Response(file); + return readFileResponse({ file_path }); } catch (error) { return new Response(`File Not Found`, { diff --git a/dist/functions/server/handle-public.d.ts b/dist/functions/server/handle-public.d.ts index 9130e3e..7071a78 100644 --- a/dist/functions/server/handle-public.d.ts +++ b/dist/functions/server/handle-public.d.ts @@ -2,4 +2,7 @@ type Params = { req: Request; }; export default function ({ req }: Params): Promise; +export declare function readFileResponse({ file_path }: { + file_path: string; +}): Response; export {}; diff --git a/dist/functions/server/handle-public.js b/dist/functions/server/handle-public.js index 6197c44..2f03ff9 100644 --- a/dist/functions/server/handle-public.js +++ b/dist/functions/server/handle-public.js @@ -11,14 +11,7 @@ export default async function ({ req }) { if (!file_path.startsWith(PUBLIC_DIR + path.sep)) { return new Response("Forbidden", { status: 403 }); } - if (!existsSync(file_path)) { - return new Response(`Public File Doesn't Exist`, { - status: 404, - }); - } - const file = Bun.file(file_path); - let res_opts = {}; - return new Response(file, res_opts); + return readFileResponse({ file_path }); } catch (error) { return new Response(`Public File Not Found`, { @@ -26,3 +19,13 @@ export default async function ({ req }) { }); } } +export function readFileResponse({ file_path }) { + if (!existsSync(file_path)) { + return new Response(`Public File Doesn't Exist`, { + status: 404, + }); + } + const file = Bun.file(file_path); + // let res_opts: ResponseInit = {}; + return new Response(file); +} diff --git a/dist/functions/server/watcher-esbuild-ctx.js b/dist/functions/server/watcher-esbuild-ctx.js index 1e6b40f..c7b53ef 100644 --- a/dist/functions/server/watcher-esbuild-ctx.js +++ b/dist/functions/server/watcher-esbuild-ctx.js @@ -1,7 +1,6 @@ import { watch, existsSync } from "fs"; import path from "path"; import grabDirNames from "../../utils/grab-dir-names"; -import rebuildBundler from "./rebuild-bundler"; import { log } from "../../utils/log"; import allPagesESBuildContextBundler from "../bundler/all-pages-esbuild-context-bundler"; import serverPostBuildFn from "./server-post-build-fn"; diff --git a/dist/functions/server/web-pages/generate-web-html.js b/dist/functions/server/web-pages/generate-web-html.js index 3357716..598608b 100644 --- a/dist/functions/server/web-pages/generate-web-html.js +++ b/dist/functions/server/web-pages/generate-web-html.js @@ -1,5 +1,5 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime"; -import { renderToString } from "react-dom/server"; +import { renderToReadableStream, renderToString } from "react-dom/server"; import grabContants from "../../../utils/grab-constants"; import EJSON from "../../../utils/ejson"; import isDevelopment from "../../../utils/is-development"; @@ -10,6 +10,8 @@ import { AppData } from "../../../data/app-data"; import { readFileSync } from "fs"; import path from "path"; import _ from "lodash"; +import grabDirNames from "../../../utils/grab-dir-names"; +const {} = grabDirNames(); let _reactVersion = "19"; try { _reactVersion = JSON.parse(readFileSync(path.join(process.cwd(), "node_modules/react/package.json"), "utf-8")).version; @@ -45,40 +47,46 @@ export default async function genWebHTML({ component, pageProps, bundledMap, mod const RootHead = root_module?.Head; const dev = isDevelopment(); const devSuffix = dev ? "?dev" : ""; - const browser_imports = { - react: `https://esm.sh/react@${_reactVersion}`, - "react-dom": `https://esm.sh/react-dom@${_reactVersion}`, - "react-dom/client": `https://esm.sh/react-dom@${_reactVersion}/client`, - "react/jsx-runtime": `https://esm.sh/react@${_reactVersion}/jsx-runtime`, - "react/jsx-dev-runtime": `https://esm.sh/react@${_reactVersion}/jsx-dev-runtime`, - }; + // const browser_imports: Record = { + // react: `/.bunext/react`, + // "react-dom": `/.bunext/react-dom`, + // "react-dom/client": `/.bunext/react-dom-client`, + // "react/jsx-runtime": `/.bunext/react-jsx-runtime`, + // "react/jsx-dev-runtime": `/.bunext/react-jsx-dev-runtime`, + // }; + // const browser_imports: Record = { + // react: `https://esm.sh/react@${_reactVersion}`, + // "react-dom": `https://esm.sh/react-dom@${_reactVersion}`, + // "react-dom/client": `https://esm.sh/react-dom@${_reactVersion}/client`, + // "react/jsx-runtime": `https://esm.sh/react@${_reactVersion}/jsx-runtime`, + // "react/jsx-dev-runtime": `https://esm.sh/react@${_reactVersion}/jsx-dev-runtime`, + // }; // if (dev) { // browser_imports["react/jsx-dev-runtime"] = // `https://esm.sh/react@${_reactVersion}/jsx-dev-runtime`; // } - const importMap = JSON.stringify({ - imports: browser_imports, - }); - const final_meta = _.merge(root_meta, page_meta); - let final_component = (_jsxs("html", { ...html_props, children: [_jsxs("head", { children: [_jsx("meta", { charSet: "utf-8" }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }), final_meta ? grabWebMetaHTML({ meta: final_meta }) : null, bundledMap?.css_path ? (_jsx("link", { rel: "stylesheet", href: `/${bundledMap.css_path}` })) : null, _jsx("script", { dangerouslySetInnerHTML: { - __html: `window.${ClientWindowPagePropsName} = ${serializedProps}`, - } }), bundledMap?.path ? (_jsxs(_Fragment, { children: [_jsx("script", { type: "importmap", dangerouslySetInnerHTML: { - __html: importMap, - }, defer: true }), _jsx("script", { src: `/${bundledMap.path}`, type: "module", id: AppData["BunextClientHydrationScriptID"], defer: true })] })) : null, is_dev ? (_jsx("script", { defer: true, dangerouslySetInnerHTML: { - __html: page_hydration_script, - } })) : null, RootHead ? (_jsx(RootHead, { serverRes: pageProps, ctx: routeParams })) : null, Head ? _jsx(Head, { serverRes: pageProps, ctx: routeParams }) : null] }), _jsx("body", { children: _jsx("div", { id: ClientRootElementIDName, suppressHydrationWarning: !dev, children: component }) })] })); - let html = `\n`; - // const stream = await renderToReadableStream(final_component, { - // onError(error: any) { - // // This is where you "omit" or handle the errors - // // You can log it silently or ignore it - // if (error.message.includes('unique "key" prop')) return; - // console.error(error); - // }, + // const importMap = JSON.stringify({ + // imports: browser_imports, // }); - // // 2. Convert the Web Stream to a String (Bun-optimized) - // const htmlBody = await new Response(stream).text(); - // html += htmlBody; - html += renderToString(final_component); + const final_meta = _.merge(root_meta, page_meta); + let final_component = (_jsxs("html", { ...html_props, children: [_jsxs("head", { children: [_jsx("meta", { charSet: "utf-8", "data-bunext-head": true }), _jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0", "data-bunext-head": true }), final_meta ? grabWebMetaHTML({ meta: final_meta }) : null, bundledMap?.css_path ? (_jsx("link", { rel: "stylesheet", href: `/${bundledMap.css_path}`, "data-bunext-head": true })) : null, _jsx("script", { dangerouslySetInnerHTML: { + __html: `window.${ClientWindowPagePropsName} = ${serializedProps}`, + }, "data-bunext-head": true }), RootHead ? (_jsx(RootHead, { serverRes: pageProps, ctx: routeParams })) : null, Head ? _jsx(Head, { serverRes: pageProps, ctx: routeParams }) : null, bundledMap?.path ? (_jsx(_Fragment, { children: _jsx("script", { src: `/${bundledMap.path}`, type: "module", id: AppData["BunextClientHydrationScriptID"], defer: true, "data-bunext-head": true }) })) : null, is_dev ? (_jsx("script", { defer: true, dangerouslySetInnerHTML: { + __html: page_hydration_script, + }, "data-bunext-head": true })) : null] }), _jsx("body", { children: _jsx("div", { id: ClientRootElementIDName, suppressHydrationWarning: !dev, children: component }) })] })); + let html = `\n`; + const stream = await renderToReadableStream(final_component, { + onError(error) { + // This is where you "omit" or handle the errors + // You can log it silently or ignore it + if (error.message.includes('unique "key" prop')) + return; + console.error(error); + }, + }); + // 2. Convert the Web Stream to a String (Bun-optimized) + const htmlBody = await new Response(stream).text(); + html += htmlBody; + // html += renderToString(final_component); return html; } diff --git a/dist/types/index.d.ts b/dist/types/index.d.ts index e640c24..f63c287 100644 --- a/dist/types/index.d.ts +++ b/dist/types/index.d.ts @@ -164,23 +164,25 @@ export type BunextPageModuleMeta = { robots?: string; canonical?: string; themeColor?: string; - og?: { - title?: string; - description?: string; - image?: string; - url?: string; - type?: string; - siteName?: string; - locale?: string; - }; - twitter?: { - card?: "summary" | "summary_large_image" | "app" | "player"; - title?: string; - description?: string; - image?: string; - site?: string; - creator?: string; - }; + og?: BunextPageModuleMetaOG; + twitter?: BunextPageModuleMetaTwitter; +}; +export type BunextPageModuleMetaOG = { + title?: string; + description?: string; + image?: string; + url?: string; + type?: string; + siteName?: string; + locale?: string; +}; +export type BunextPageModuleMetaTwitter = { + card?: "summary" | "summary_large_image" | "app" | "player"; + title?: string; + description?: string; + image?: string; + site?: string; + creator?: string; }; export type BunextPageServerFn = { - react: `https://esm.sh/react@${_reactVersion}`, - "react-dom": `https://esm.sh/react-dom@${_reactVersion}`, - "react-dom/client": `https://esm.sh/react-dom@${_reactVersion}/client`, - "react/jsx-runtime": `https://esm.sh/react@${_reactVersion}/jsx-runtime`, - "react/jsx-dev-runtime": `https://esm.sh/react@${_reactVersion}/jsx-dev-runtime`, - }; + // const browser_imports: Record = { + // react: `https://esm.sh/react@${_reactVersion}`, + // "react-dom": `https://esm.sh/react-dom@${_reactVersion}`, + // "react-dom/client": `https://esm.sh/react-dom@${_reactVersion}/client`, + // "react/jsx-runtime": `https://esm.sh/react@${_reactVersion}/jsx-runtime`, + // "react/jsx-dev-runtime": `https://esm.sh/react@${_reactVersion}/jsx-dev-runtime`, + // }; // if (dev) { // browser_imports["react/jsx-dev-runtime"] = // `https://esm.sh/react@${_reactVersion}/jsx-dev-runtime`; // } - const importMap = JSON.stringify({ - imports: browser_imports, - }); + // const importMap = JSON.stringify({ + // imports: browser_imports, + // }); const final_meta = _.merge(root_meta, page_meta); let final_component = ( - + {final_meta ? grabWebMetaHTML({ meta: final_meta }) : null} + {/* */} + {bundledMap?.css_path ? ( - + ) : null}