Make the dist directory configurable

Set it with `dist_dir` in bunext.config.ts or `--dist-dir` on any CLI
command (precedence: --dist-dir > BUNEXT_DIST_DIR > dist_dir > .bunext).
setupDistDir() resolves it in the CLI's preAction hook and at the start
of bunextInit(), so custom servers get the config value too.

- Read dist-derived paths from grabDirNames() inside functions instead of
  at import time; a guard test enforces this.
- Derive the client asset URL prefix from the dist dir instead of
  hard-coding /.bunext.
- Make the dev watcher ignore rules and probe follow the dist dir.
- Validate the dir: inside the project root, outside src/, public/ and
  node_modules/, URL-safe characters only.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-11-09 03:55:54 +01:00
co-authored by Claude Opus 5.5
parent 4d4a79a6dd
commit b410b92f9f
35 changed files with 601 additions and 80 deletions
+19 -3
View File
@@ -160,7 +160,7 @@ bun run dev
| Command | Description |
| -------------- | ------------------------------------------------------------------------------ |
| `bunext dev` | Start the development server with HMR and file watching. |
| `bunext build` | Bundle all pages for production. Outputs artifacts to `.bunext/public/pages/` using paths relative to the project root. |
| `bunext build` | Bundle all pages for production. Outputs artifacts to `.bunext/public/pages/` (or the [dist directory](#dist-directory)) using paths relative to the project root. |
| `bunext start` | Start the production server using pre-built artifacts. |
| `bunext sitemap` | Generate `public/sitemap.xml` and `public/robots.txt` from your pages, using the `sitemap` and `robots` options in `bunext.config.ts`. See [Sitemap](#sitemap). |
@@ -197,6 +197,19 @@ bunext start
> **Note:** `bunext start` will exit with an error if `.bunext/public/pages/map.json` does not exist. Always run `bunext build` (or `bun run build`) before `bunext start`.
### Dist Directory
Build artifacts go to `.bunext/` by default. To use another directory, set `dist_dir` in `bunext.config.ts` or pass `--dist-dir` to any command (the flag wins over the config):
```bash
bunext build --dist-dir build
bunext start --dist-dir build
```
Use the same directory for every command: `bunext start` serves what `bunext build` wrote there, and `bunext sitemap` reads `page-lastmod.json` from it. Setting `dist_dir` in the config keeps them in sync. [Custom servers](#custom-server) read it too, through `bunextInit()`.
The directory must be inside the project root and outside `src/`, `public/` and `node_modules/`. Its path is also the URL path of the client bundles (e.g. `/build/public/pages/...`), so it may only contain letters, digits, `.`, `_`, `-` and `/`.
---
## Project Structure
@@ -961,7 +974,7 @@ import type { BunextConfig } from "@moduletrace/bunext/types";
const config: BunextConfig = {
port: 3000, // default: 7000
origin: "https://example.com",
distDir: ".bunext", // directory for internal build artifacts
dist_dir: ".bunext", // directory for build artifacts
assetsPrefix: "_bunext/static",
globalVars: {
MY_API_URL: "https://api.example.com",
@@ -979,7 +992,7 @@ export default config;
| -------------------- | --------------------------------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------- |
| `port` | `number` | `7000` | HTTP server port |
| `origin` | `string` | — | Canonical origin URL |
| `distDir` | `string` | `.bunext` | Internal artifact directory |
| `dist_dir` | `string` | `.bunext` | Build artifact directory, relative to the project root — see [Dist Directory](#dist-directory) |
| `assetsPrefix` | `string` | `_bunext/static` | URL prefix for static assets |
| `globalVars` | `{ [k: string]: any }` | — | Variables injected globally at build time |
| `public_envs` | `Record<string, string>` | — | Public env vars exposed to the client via `window.process.env` (see [Environment Variables](#environment-variables)) |
@@ -1137,6 +1150,8 @@ bun run server.ts
> **Note:** When using a custom server, HMR and file watching are still driven by `bunextInit()`. Pass `development: true` in your `Bun.serve()` call to enable them.
> **Note:** `bunextInit()` reads `dist_dir` from `bunext.config.ts`, so a custom server uses the same directory as `bunext build`.
---
## Environment Variables
@@ -1144,6 +1159,7 @@ bun run server.ts
| Variable | Description |
| ---------------------- | ------------------------------------------------------------------------------------------------ |
| `PORT` | Override the server port (takes precedence over config) |
| `BUNEXT_DIST_DIR` | Build artifact directory. Overrides `dist_dir` in the config; `--dist-dir` overrides both |
| `BUNEXT_PUBLIC_*` | Any env var prefixed with `BUNEXT_PUBLIC_` is exposed to the client via `window.process.env` |
### Public Environment Variables