- Server functions can return not_found: true to render the 404 page with status 404. - Page components and window.__PAGE_PROPS__ (and HMR updates) only get props, query, url and error. response_options, redirect, cache settings and res_transform stay on the server, so cookies and private headers no longer end up in the HTML. BunextPageProps is narrowed to match (breaking for code that read server-only fields from component props). - response_options headers go through a Headers object, so repeated headers such as several Set-Cookie survive. - Redirects: status_code wins over permanent; response_options headers and res_transform apply to redirects too. - Gzip for compressible text responses; compress: false to turn it off. - Files the router matches but never bundles (.server.ts, __root, excluded paths and directories) return 404 instead of looping through dev rebuild retries. - Missing public files return 404 rather than 403, so dotted page paths like /users/john.doe fall through to pages again. - importFresh detects rewrites within the filesystem's mtime granularity. - README: self-hosted React (not esm.sh), snake_case option names, static file serving, cache headers, the new options. Co-Authored-By: Claude Opus 5.5 <[email protected]>
161 lines
6.0 KiB
JavaScript
161 lines
6.0 KiB
JavaScript
import path from "path";
|
|
import { DistDirEnvName, resolveDistDir } from "./grab-dist-dir";
|
|
let cached;
|
|
/**
|
|
* # Project and artifact paths
|
|
* The dist directory comes from `BUNEXT_DIST_DIR`, which `setupDistDir()`
|
|
* sets from `--dist-dir` / `dist_dir` in the config. Call this where the
|
|
* paths are used, not at module load: a module loaded before
|
|
* `setupDistDir()` runs would keep the default directory.
|
|
*/
|
|
export default function grabDirNames() {
|
|
if (global.BUNEXT_DIR_NAMES)
|
|
return global.BUNEXT_DIR_NAMES;
|
|
const key = `${process.cwd()}\0${process.env[DistDirEnvName] || ""}`;
|
|
if (cached?.key !== key) {
|
|
cached = { key, dir_names: computeDirNames() };
|
|
}
|
|
return cached.dir_names;
|
|
}
|
|
function computeDirNames() {
|
|
const ROOT_DIR = process.cwd();
|
|
const SRC_DIR = path.join(ROOT_DIR, "src");
|
|
const PAGES_DIR = path.join(SRC_DIR, "pages");
|
|
const API_DIR = path.join(PAGES_DIR, "api");
|
|
const PUBLIC_DIR = path.join(ROOT_DIR, "public");
|
|
const CONFIG_FILE = path.join(ROOT_DIR, "bunext.config.ts");
|
|
const BUNX_CWD_DIR = resolveDistDir({
|
|
dist_dir: process.env[DistDirEnvName],
|
|
root_dir: ROOT_DIR,
|
|
});
|
|
const BUNX_CWD_MODULE_CACHE_DIR = path.resolve(BUNX_CWD_DIR, "module-cache");
|
|
const BUNX_CWD_PAGES_REWRITE_DIR = path.resolve(BUNX_CWD_DIR, "pages");
|
|
const BUNX_TMP_DIR = path.resolve(BUNX_CWD_DIR, ".tmp");
|
|
const BUNX_BUNDLER_ERROR_EXIT_FILE = path.resolve(BUNX_TMP_DIR, "BUNDLER_EXIT.txt");
|
|
const BUNX_HYDRATION_SRC_DIR = path.resolve(BUNX_CWD_DIR, "client", "hydration-src");
|
|
const BUNX_LOGS_DIR = path.resolve(BUNX_CWD_DIR, "logs");
|
|
const BUNX_ERROR_LOGS_DIR = path.resolve(BUNX_LOGS_DIR, "error");
|
|
const BUNEXT_PUBLIC_DIR = path.join(BUNX_CWD_DIR, "public");
|
|
const HYDRATION_DST_DIR = path.join(BUNEXT_PUBLIC_DIR, "pages");
|
|
const BUNEXT_VENDOR_DIR = path.join(BUNEXT_PUBLIC_DIR, "vendor");
|
|
// Kept outside BUNEXT_PUBLIC_DIR: that directory is served over HTTP.
|
|
const BUNEXT_CACHE_DIR = path.join(BUNX_CWD_DIR, "cache");
|
|
const HYDRATION_DST_DIR_MAP_JSON_FILE_NAME = "map.json";
|
|
const HYDRATION_DST_DIR_MAP_JSON_FILE = path.join(HYDRATION_DST_DIR, HYDRATION_DST_DIR_MAP_JSON_FILE_NAME);
|
|
const BUNX_ROOT_DIR = path.resolve(__dirname, "../../");
|
|
const BUNX_ROOT_SRC_DIR = path.join(BUNX_ROOT_DIR, "src");
|
|
const BUNX_ROOT_PRESETS_DIR = path.join(BUNX_ROOT_SRC_DIR, "presets");
|
|
const BUNX_ROOT_500_FILE_NAME = `server-error`;
|
|
const BUNX_ROOT_500_PRESET_COMPONENT = path.join(BUNX_ROOT_PRESETS_DIR, `${BUNX_ROOT_500_FILE_NAME}.tsx`);
|
|
const BUNX_ROOT_404_FILE_NAME = `not-found`;
|
|
const BUNX_ROOT_404_PRESET_COMPONENT = path.join(BUNX_ROOT_PRESETS_DIR, `${BUNX_ROOT_404_FILE_NAME}.tsx`);
|
|
const BUNDLER_CTX_MAP_JSON = path.join(BUNX_CWD_DIR, "bundler-ctx-map.json");
|
|
const SSR_BUNDLER_CTX_MAP_JSON = path.join(BUNX_CWD_DIR, "ssr-bundler-ctx-map.json");
|
|
const BUILD_INFO_JSON = path.join(BUNX_CWD_DIR, "build-info.json");
|
|
const PAGE_LASTMOD_JSON = path.join(BUNX_CWD_DIR, "page-lastmod.json");
|
|
return {
|
|
ROOT_DIR,
|
|
SRC_DIR,
|
|
PAGES_DIR,
|
|
API_DIR,
|
|
PUBLIC_DIR,
|
|
HYDRATION_DST_DIR,
|
|
BUNX_CWD_DIR,
|
|
BUNX_ROOT_DIR,
|
|
CONFIG_FILE,
|
|
BUNX_TMP_DIR,
|
|
BUNX_HYDRATION_SRC_DIR,
|
|
BUNX_ROOT_SRC_DIR,
|
|
BUNX_ROOT_PRESETS_DIR,
|
|
BUNX_ROOT_500_PRESET_COMPONENT,
|
|
BUNX_ROOT_500_FILE_NAME,
|
|
BUNX_ROOT_404_PRESET_COMPONENT,
|
|
BUNX_ROOT_404_FILE_NAME,
|
|
HYDRATION_DST_DIR_MAP_JSON_FILE,
|
|
BUNEXT_CACHE_DIR,
|
|
BUNX_CWD_MODULE_CACHE_DIR,
|
|
BUNX_CWD_PAGES_REWRITE_DIR,
|
|
HYDRATION_DST_DIR_MAP_JSON_FILE_NAME,
|
|
BUNEXT_VENDOR_DIR,
|
|
BUNEXT_PUBLIC_DIR,
|
|
BUNX_BUNDLER_ERROR_EXIT_FILE,
|
|
BUNX_ERROR_LOGS_DIR,
|
|
BUNX_LOGS_DIR,
|
|
BUNDLER_CTX_MAP_JSON,
|
|
SSR_BUNDLER_CTX_MAP_JSON,
|
|
BUILD_INFO_JSON,
|
|
PAGE_LASTMOD_JSON,
|
|
};
|
|
}
|
|
// const NODE_MODULES_DIR = path.resolve(
|
|
// existsSync(path.join(BUNX_ROOT_DIR, "source.md"))
|
|
// ? BUNX_ROOT_DIR
|
|
// : ROOT_DIR,
|
|
// "node_modules",
|
|
// );
|
|
// const REACT_MODULE_DIR = path.join(NODE_MODULES_DIR, "react");
|
|
// const REACT_DOM_MODULE_DIR = path.join(NODE_MODULES_DIR, "react-dom");
|
|
// const REACT_PRODUCTION_MODULE = path.join(
|
|
// REACT_MODULE_DIR,
|
|
// "cjs",
|
|
// "react.production.js",
|
|
// );
|
|
// const REACT_DEVELOPMENT_MODULE = path.join(
|
|
// REACT_MODULE_DIR,
|
|
// "cjs",
|
|
// "react.development.js",
|
|
// );
|
|
// const REACT_JSX_RUNTIME_PRODUCTION_MODULE = path.join(
|
|
// REACT_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-jsx-runtime.production.js",
|
|
// );
|
|
// const REACT_JSX_RUNTIME_DEVELOPMENT_MODULE = path.join(
|
|
// REACT_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-jsx-runtime.development.js",
|
|
// );
|
|
// const REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE = path.join(
|
|
// REACT_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-jsx-dev-runtime.production.js",
|
|
// );
|
|
// const REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE = path.join(
|
|
// REACT_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-jsx-dev-runtime.development.js",
|
|
// );
|
|
// const REACT_DOM_PRODUCTION_MODULE = path.join(
|
|
// REACT_DOM_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-dom.production.js",
|
|
// );
|
|
// const REACT_DOM_DEVELOPMENT_MODULE = path.join(
|
|
// REACT_DOM_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-dom.development.js",
|
|
// );
|
|
// const REACT_DOM_CLIENT_PRODUCTION_MODULE = path.join(
|
|
// REACT_DOM_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-dom-client.production.js",
|
|
// );
|
|
// const REACT_DOM_CLIENT_DEVELOPMENT_MODULE = path.join(
|
|
// REACT_DOM_MODULE_DIR,
|
|
// "cjs",
|
|
// "react-dom-client.development.js",
|
|
// );
|
|
// NODE_MODULES_DIR,
|
|
// REACT_MODULE_DIR,
|
|
// REACT_DOM_MODULE_DIR,
|
|
// REACT_PRODUCTION_MODULE,
|
|
// REACT_DEVELOPMENT_MODULE,
|
|
// REACT_JSX_RUNTIME_PRODUCTION_MODULE,
|
|
// REACT_JSX_RUNTIME_DEVELOPMENT_MODULE,
|
|
// REACT_JSX_DEVELOPMENT_RUNTIME_PRODUCTION_MODULE,
|
|
// REACT_JSX_DEVELOPMENT_RUNTIME_DEVELOPMENT_MODULE,
|
|
// REACT_DOM_PRODUCTION_MODULE,
|
|
// REACT_DOM_DEVELOPMENT_MODULE,
|
|
// REACT_DOM_CLIENT_PRODUCTION_MODULE,
|
|
// REACT_DOM_CLIENT_DEVELOPMENT_MODULE,
|