Bundler
Client-side asset bundler — produces content-hashed dist/ files plus a manifest.json mapping logical name to hashed filename. Designed to drop into a static server (b.static) so cache-busting lives at the filename layer and HTML can long-cache hashed paths.
No-build-step fallback: the default engine.passthrough reads each entry from disk verbatim, hashes it, and writes the hashed copy. Operators with no module-graph need ship their source files directly through the bundler and skip the toolchain entirely.
Module-graph / tree-shake / minify / sourcemaps: operators supply esbuild (devDependency, never vendored) and adapt it via engine.fromEsbuild(esbuild, opts) — the framework owns the integration seam, the operator brings the heavy machinery. The ~10 MB esbuild-wasm blob is intentionally not vendored.
Hashes are SHA3-512, first 16 hex chars by default (operators override via opts.hashLen between 4 and 64). Source maps written by an engine land as siblings.
Watch mode: bundler.watch(callback) arms fs.watch on each entry's directory, debounces bursts via opts.graceMs (default 100 ms), and rebuilds the entire entry set on change.
Manifest format:
{ "app": "app.4a8c2f1d9e3b7062.js", "styles": "styles.b29f1e7c.css" }
Integrates with lib/static.js: serve outdir as a static directory; b.static's hashed-path detection sets long-cache headers on files that look hashed, and integrity() reads the manifest to emit Subresource Integrity attributes.
b.bundler.create(opts) #
{
entries: { [name: string]: string }, // logical name → source path
outdir: string, // dist directory (created if missing, mode 0o755)
cwd: string, // resolves relative entries / outdir; defaults to process.cwd()
engine: { name: string, transform: async (entryPath, contentBuf) => { content, sourceMap?, imports? } },
// defaults to engine.passthrough
manifest: string | false, // manifest filename ("manifest.json"), or false to skip
hash: boolean, // emit ..; default true
hashLen: number, // hex chars in the hash, 4..64; default 16
graceMs: number, // watch-mode debounce ms; default 100
log: object, // structured logger ({ info, warn, error })
}
Build a content-hashed asset pipeline for a fixed set of named entries. The returned object exposes build() (one-shot rebuild, resolves to { outputs, manifestPath, manifest, durationMs }), watch(callback) (arm fs.watch and debounce-rebuild on change), and close() (drop watchers and pending timers).
Throws BundlerError at config time on missing / malformed entries, missing outdir, an out-of-range hashLen, or an engine that does not implement { name, transform }.
var bundler = b.bundler.create({
entries: { app: "./src/app.js", styles: "./src/styles.css" },
outdir: "./public/dist",
hashLen: 16,
});
// bundler.build() returns a Promise resolving to:
// { outputs: [...], manifest: { app: "app..js", styles: "styles..css" },
// manifestPath: ".../public/dist/manifest.json", durationMs: }
// Watch mode — rebuild on edits.
bundler.watch(function (err, result) {
if (err) return;
// result.manifest is the freshly-written name→hashed-filename map
});
// Operator-supplied esbuild for module-graph + tree-shake + minify.
// var esbuild = require("esbuild");
// var modGraph = b.bundler.create({
// entries: { app: "./src/app.js" },
// outdir: "./public/dist",
// engine: b.bundler.engine.fromEsbuild(esbuild, { minify: true, sourcemap: true }),
// });
Last updated 2026-08-08T16:39:49.652Z by seeder.