Compare commits

...

1 Commits

Author SHA1 Message Date
Claude Bot
cdb1f4b5e6 fix(bundler): reject splitting with non-esm formats instead of crashing
When `splitting: true` was combined with `format: "iife"` (or "cjs"),
the bundler would crash with a null pointer dereference in
`sortedCrossChunkImports` because `exports_to_other_chunks` is only
populated for ESM format, while `imports_from_other_chunks` is populated
for all formats. This matches esbuild's behavior of rejecting this
combination with a clear error message.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-02-26 09:12:21 +00:00
3 changed files with 27 additions and 0 deletions

View File

@@ -1045,6 +1045,10 @@ pub const JSBundler = struct {
}
}
if (this.code_splitting and this.format != .esm) {
return globalThis.throwInvalidArguments("Splitting currently only works with the \"esm\" format", .{});
}
// ESM bytecode requires compile because module_info (import/export metadata)
// is only available in compiled binaries. Without it, JSC must parse the file
// twice (once for module analysis, once for bytecode), which is a deopt.

View File

@@ -91,6 +91,12 @@ pub const BuildCommand = struct {
this_transpiler.options.output_dir = ctx.bundler_options.outdir;
this_transpiler.options.output_format = ctx.bundler_options.output_format;
if (ctx.bundler_options.code_splitting and ctx.bundler_options.output_format != .esm) {
Output.prettyErrorln("<r><red>error<r><d>:<r> Splitting currently only works with the \"esm\" format", .{});
Global.exit(1);
return;
}
if (ctx.bundler_options.output_format == .internal_bake_dev) {
this_transpiler.options.tree_shaking = false;
}

View File

@@ -134,6 +134,23 @@ describe("Bun.build", () => {
).toThrow();
});
test("splitting with non-esm format throws", async () => {
expect(() =>
Bun.build({
entrypoints: ["hello.js"],
splitting: true,
format: "iife",
}),
).toThrow('Splitting currently only works with the "esm" format');
expect(() =>
Bun.build({
entrypoints: ["hello.js"],
splitting: true,
format: "cjs",
}),
).toThrow('Splitting currently only works with the "esm" format');
});
test("returns errors properly", async () => {
Bun.gc(true);
const build = await buildNoThrow({