Skip to content

Bun.build does not update hash/etag for HTML entrypoint when dependencies/assets change #23009

@brw

Description

@brw

What version of Bun is running?

1.2.22+6bafe2602

What platform is your computer?

Linux 6.16.8-2-cachyos x86_64 unknown

What steps can reproduce the bug?

When bundling as a single file app/SFA, Bun.build does not seem to change the hash or etag header of the HTML entrypoint even though its dependencies did in fact change. This causes the browser to load the cached HTML file containing the old asset names, leading to 404s until you hard refresh.

I'm guessing that the HTML entrypoint hash gets generated before the asset URLs get injected into it, so asset filename/hash changes do not cause the HTML entrypoint hash to change.

First spotted at NDC-Tourney/stream-overlay#40 and #22807 was created to fix it but later closed.

Minimal repro:

build.ts

await Bun.build({
  entrypoints: ["./server.ts"],
  compile: {
    outfile: "dist/app",
  },
});

server.ts

import { serve } from "bun";
import index from "./index.html";

const server = serve({
  routes: {
    "/": index,
  },
});

console.log(`Server started at ${server.url}`);

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
  </head>
  <body>
    <script type="module" src="./index.js"></script>
  </body>
</html>

index.js

console.log("1");
  1. bun run build.ts
  2. ./dist/app
  3. Open http://localhost:3000
  4. Open devtools network tab, observe everything loading fine
  5. Stop ./dist/app process
  6. Modify index.js (e.g. incrementing 1 to 2)
  7. bun run build.ts
  8. ./dist/app
  9. Open http://localhost:3000
  10. Open devtools network tab, see that the HTML is loaded from cache and observe 404 error when the browser tries to load the JS file using its previous name

You can also reproduce this without compiling as SFA using naming: "[name]-[hash].[ext]", but generally people wouldn't add a hash to the HTML entrypoint filename i imagine so i figured i'd show the most common situation here (and how i ran into it as well).

What is the expected behavior?

The HTML entrypoint hash/etag header should update when the assets it depends on are updated, so that the browser fetches the new HTML with the new asset filenames, and doesn't try to load the old ones.

What do you see instead?

The browser loads the cached HTML which contains the old asset filenames, leading to 404s.

Additional information

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions