From 84fa417e8ff3bf25ee67b771da108df4d36f1312 Mon Sep 17 00:00:00 2001 From: Claude Bot Date: Sun, 5 Oct 2025 14:29:02 +0000 Subject: [PATCH] Fix worker bundling path resolution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The issue was that worker unique keys were using import_record_index instead of source_index, preventing correct chunk mapping. Changes: - js_printer.zig: Use source_index from import record for worker unique keys - LinkerContext.zig: Validate worker indices against file count (not chunk count) - Chunk.zig: Use entry_point_chunk_indices mapping for worker path resolution This allows the bundler to correctly map from source files to their corresponding worker chunks, just like dynamic imports and SCBs. Test results: - bundler_worker_verify.test.ts: ✅ PASS - bundler_worker_basic.test.ts: ✅ PASS - bundler_worker_simple.test.ts: ✅ PASS Workers now correctly resolve to their chunk paths (e.g., ./worker-axd28k5g.js) instead of incorrectly pointing to the entry file. --- src/bundler/Chunk.zig | 4 ++-- src/bundler/LinkerContext.zig | 2 +- src/js_printer.zig | 10 +++++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/bundler/Chunk.zig b/src/bundler/Chunk.zig index dddb0a5826..432ecab63d 100644 --- a/src/bundler/Chunk.zig +++ b/src/bundler/Chunk.zig @@ -215,7 +215,7 @@ pub const Chunk = struct { }, .chunk => chunks[index].final_rel_path, .scb => chunks[entry_point_chunks_for_scb[index]].final_rel_path, - .worker => chunks[index].final_rel_path, + .worker => chunks[entry_point_chunks_for_scb[index]].final_rel_path, .html_import => { count += std.fmt.count("{}", .{HTMLImportManifest.formatEscapedJSON(.{ .index = index, @@ -303,7 +303,7 @@ pub const Chunk = struct { break :brk piece_chunk.final_rel_path; }, .worker => brk: { - const piece_chunk = chunks[index]; + const piece_chunk = chunks[entry_point_chunks_for_scb[index]]; if (enable_source_map_shifts) { shift.before.advance(piece_chunk.unique_key); diff --git a/src/bundler/LinkerContext.zig b/src/bundler/LinkerContext.zig index 7791a48756..af8378ad56 100644 --- a/src/bundler/LinkerContext.zig +++ b/src/bundler/LinkerContext.zig @@ -2625,7 +2625,7 @@ pub const LinkerContext = struct { bun.Output.debugWarn("Invalid output piece boundary", .{}); break; }, - .worker => if (index >= count) { + .worker => if (index >= c.graph.files.len) { if (bun.Environment.isDebug) bun.Output.debugWarn("Invalid output piece boundary", .{}); break; diff --git a/src/js_printer.zig b/src/js_printer.zig index 616b551134..2f8f452eaf 100644 --- a/src/js_printer.zig +++ b/src/js_printer.zig @@ -2207,18 +2207,22 @@ fn NewPrinter( p.printSpaceBeforeIdentifier(); p.addSourceMapping(expr.loc); p.print("new Worker("); - + // Generate a unique key for the worker instead of the direct path // This will be resolved to the actual worker chunk path later if (p.options.unique_key_prefix.len > 0) { - const unique_key = std.fmt.allocPrint(p.options.allocator, "{s}W{d:0>8}", .{ p.options.unique_key_prefix, e.import_record_index }) catch unreachable; + const import_record = p.importRecord(e.import_record_index); + // Use the source_index from the import record, not the import_record_index + // This allows the linker to map from source_index to chunk_index using entry_point_chunk_indices + const source_index = import_record.source_index.get(); + const unique_key = std.fmt.allocPrint(p.options.allocator, "{s}W{d:0>8}", .{ p.options.unique_key_prefix, source_index }) catch unreachable; defer p.options.allocator.free(unique_key); p.printStringLiteralUTF8(unique_key, true); } else { // Fallback to direct path if unique_key_prefix is not available p.printStringLiteralUTF8(p.importRecord(e.import_record_index).path.text, true); } - + // Print options if present and not missing if (e.options.data != .e_missing) { p.print(",");