mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 18:38:55 +00:00
## Summary - Fixed lazy-loaded chunks from dynamic imports not appearing in `frontend.files` when using `--splitting` with `--compile` in fullstack builds - Updated `computeChunks.zig` to mark non-entry-point chunks as browser chunks when they contain browser-targeted files - Updated `HTMLImportManifest.zig` to include browser chunks from server builds in the files manifest Fixes #25628 ## Test plan - [ ] Added regression test `test/regression/issue/25628.test.ts` that verifies lazy chunks appear in `frontend.files` - [ ] Manually verified: system bun reports `CHUNK_COUNT:1` (bug), debug bun reports `CHUNK_COUNT:2` (fix) 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
90 lines
2.7 KiB
TypeScript
90 lines
2.7 KiB
TypeScript
import { expect, test } from "bun:test";
|
|
import { bunEnv, bunExe, isWindows, tempDir } from "harness";
|
|
|
|
// https://github.com/oven-sh/bun/issues/25628
|
|
// Bug: Lazy code-splitting chunks are not accessible via frontend.files in fullstack builds
|
|
// when using --splitting with --compile. The chunks are physically written to disk and embedded
|
|
// in the executable, but they're filtered out when accessing the embedded files array.
|
|
|
|
test("lazy chunks from code splitting should appear in frontend.files", { timeout: 60000 }, async () => {
|
|
using dir = tempDir("issue-25628", {
|
|
// Server entry that prints frontend.files and exits
|
|
"server.ts": `
|
|
import frontend from "./client.html";
|
|
|
|
// Get all file paths from frontend.files
|
|
const filePaths = frontend.files?.map((f: any) => f.path) ?? [];
|
|
|
|
// Count the number of chunk files (lazy chunks are named chunk-xxx.js)
|
|
const chunkCount = filePaths.filter((p: string) =>
|
|
p.includes("chunk-")
|
|
).length;
|
|
|
|
// There should be at least 2 chunks:
|
|
// 1. The main app entry chunk
|
|
// 2. The lazy-loaded chunk from the dynamic import
|
|
console.log("CHUNK_COUNT:" + chunkCount);
|
|
console.log("FILES:" + filePaths.join(","));
|
|
|
|
// Exit immediately after printing
|
|
process.exit(0);
|
|
`,
|
|
"client.html": `<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<script type="module" src="./main.js"></script>
|
|
</head>
|
|
<body></body>
|
|
</html>`,
|
|
"main.js": `
|
|
// Dynamic import creates a lazy chunk
|
|
const lazyMod = () => import("./lazy.js");
|
|
lazyMod().then(m => m.hello());
|
|
`,
|
|
"lazy.js": `
|
|
export function hello() {
|
|
console.log("Hello from lazy module!");
|
|
}
|
|
`,
|
|
});
|
|
|
|
// Build with splitting and compile
|
|
await using buildProc = Bun.spawn({
|
|
cmd: [bunExe(), "build", "--compile", "server.ts", "--splitting", "--outfile", "server"],
|
|
cwd: String(dir),
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [buildStdout, buildStderr, buildExitCode] = await Promise.all([
|
|
buildProc.stdout.text(),
|
|
buildProc.stderr.text(),
|
|
buildProc.exited,
|
|
]);
|
|
|
|
expect(buildStderr).not.toContain("error:");
|
|
expect(buildExitCode).toBe(0);
|
|
|
|
// Run the compiled executable
|
|
const serverPath = isWindows ? "server.exe" : "./server";
|
|
await using runProc = Bun.spawn({
|
|
cmd: [serverPath],
|
|
cwd: String(dir),
|
|
env: bunEnv,
|
|
stdout: "pipe",
|
|
stderr: "pipe",
|
|
});
|
|
|
|
const [runStdout, runStderr, runExitCode] = await Promise.all([
|
|
runProc.stdout.text(),
|
|
runProc.stderr.text(),
|
|
runProc.exited,
|
|
]);
|
|
|
|
// There should be at least 2 chunk files in frontend.files:
|
|
// one for the main entry and one for the lazy-loaded module
|
|
expect(runStdout).toMatch(/CHUNK_COUNT:[2-9]/);
|
|
expect(runExitCode).toBe(0);
|
|
});
|