From b30b1ab1a37a39a8e4de1777ddc8bbca98e76a35 Mon Sep 17 00:00:00 2001 From: Paul Bakaus Date: Wed, 8 Apr 2026 14:21:11 -0700 Subject: [PATCH] Scope chunk + asset naming by [dir] to avoid collisions on older Bun MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Bun shipped with Cloudflare Pages doesn't dedupe shared CSS chunks across HTML entrypoints — each entry tries to emit its own copy. With chunk: '[name]-[hash].[ext]', three sub-pages all named index.html (skills/, tutorials/, anti-patterns/) plus shared CSS content end up producing chunks with identical name+hash and the build aborts on 'Multiple files share the same output path'. Including [dir] in the chunk and asset templates scopes each chunk to its entry's source directory, so the per-entry copies land in unique paths even when dedupe is off. Local Bun (1.3.x) still emits a single shared chunk because [dir] is only used when there are multiple chunk candidates. Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/build.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/scripts/build.js b/scripts/build.js index fd2a00861..d55d1147b 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -298,15 +298,18 @@ async function buildStaticSite(extraEntrypoints = []) { outdir: outdir, minify: true, sourcemap: 'linked', - // Older Bun versions (e.g. the one Cloudflare Pages ships) emit shared - // CSS/JS chunks without a content hash in the filename, which collides - // when multiple HTML entries import the same CSS partial. Force the - // chunk + asset naming to always include [hash] so the build is - // reproducible across Bun versions. + // Older Bun versions (e.g. the one Cloudflare Pages ships) don't dedupe + // shared CSS/JS chunks across HTML entrypoints — every entry tries to + // emit its own copy, and three different sub-pages all named index.html + // (under skills/, tutorials/, anti-patterns/) collide on the same + // chunk filename. Including [dir] in the chunk template scopes each + // chunk to its entry's directory so the names stay unique even when + // dedupe is off. Local Bun still emits a single shared chunk; CF Bun + // emits one per entry but each lands in its own directory. naming: { entry: '[dir]/[name].[ext]', - chunk: '[name]-[hash].[ext]', - asset: '[name]-[hash].[ext]', + chunk: '[dir]/[name]-[hash].[ext]', + asset: '[dir]/[name]-[hash].[ext]', }, });