Compare commits

...

5 Commits

Author SHA1 Message Date
Jarred Sumner
6c0a0f6c08 Merge branch 'main' into claude/fix-sourcemap-root-3332 2026-01-23 00:45:35 -08:00
Claude Bot
6d681fb1f3 test: strengthen sourcemap test with positive assertions
Add explicit assertions to verify the sourcemap source path ends with
"index.ts" and that there is exactly one source file, rather than just
checking for the absence of "../" prefix.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 04:30:41 +00:00
autofix-ci[bot]
b64e8c1f57 [autofix.ci] apply automated fixes 2026-01-15 03:18:15 +00:00
Jarred Sumner
2a4988486f Merge branch 'main' into claude/fix-sourcemap-root-3332 2026-01-14 19:16:37 -08:00
Claude Bot
792ee03e75 fix(bundler): sourcemap sources should be relative to root, not output dir
When using `Bun.build()` with a `root` option and external sourcemaps,
the sourcemap `sources` paths were incorrectly relative to the output
directory instead of the specified root directory.

For example, with `root: "."` and `outdir: "./dist"`, source paths were
being generated as `"../src/index.ts"` (relative to `dist/src/`) instead
of `"src/index.ts"` (relative to root).

The fix changes both JS and CSS sourcemap generation to use `root_dir`
instead of `output_dir` when relativizing source file paths.

Fixes #3332

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-15 01:06:42 +00:00
3 changed files with 75 additions and 2 deletions

View File

@@ -105,7 +105,7 @@ pub fn postProcessCSSChunk(ctx: GenerateChunkCtx, worker: *ThreadPool.Worker, ch
chunk.isolated_hash,
worker,
compile_results_for_source_map,
c.resolver.opts.output_dir,
c.resolver.opts.root_dir,
can_have_shifts,
);
}

View File

@@ -429,7 +429,7 @@ pub fn postProcessJSChunk(ctx: GenerateChunkCtx, worker: *ThreadPool.Worker, chu
chunk.isolated_hash,
worker,
compile_results_for_source_map,
c.resolver.opts.output_dir,
c.resolver.opts.root_dir,
can_have_shifts,
);
}

View File

@@ -0,0 +1,73 @@
import { describe, expect, test } from "bun:test";
import { tempDir } from "harness";
import path from "path";
describe("issue #3332 - sourcemap sources should be relative to root", () => {
test("JS sourcemap sources are relative to root, not output directory", async () => {
using dir = tempDir("issue-3332-js", {
"src/index.ts": `import { helper } from './nested/helper';
console.log(helper());`,
"src/nested/helper.ts": `export function helper() {
return 'hello';
}`,
});
const result = await Bun.build({
entrypoints: [path.join(String(dir), "src/index.ts")],
outdir: path.join(String(dir), "dist"),
root: String(dir),
sourcemap: "external",
});
expect(result.success).toBe(true);
// Find the sourcemap output
const sourcemapOutput = result.outputs.find(o => o.kind === "sourcemap");
expect(sourcemapOutput).toBeDefined();
// Parse the sourcemap
const mapContent = await sourcemapOutput!.text();
const map = JSON.parse(mapContent);
// Sources should be relative to root (the project directory), not output directory
// Expected: ["src/nested/helper.ts", "src/index.ts"] (or similar)
// Bug behavior: ["../src/nested/helper.ts", "../src/index.ts"] (relative to dist/src/)
for (const source of map.sources) {
expect(source).not.toMatch(/^\.\.\//);
expect(source).toMatch(/^src\//);
}
expect(map.sources).toContain("src/index.ts");
expect(map.sources).toContain("src/nested/helper.ts");
});
test("sourcemap sources without explicit root use cwd", async () => {
using dir = tempDir("issue-3332-no-root", {
"index.ts": `console.log('hello');`,
});
const result = await Bun.build({
entrypoints: [path.join(String(dir), "index.ts")],
outdir: path.join(String(dir), "dist"),
sourcemap: "external",
});
expect(result.success).toBe(true);
const sourcemapOutput = result.outputs.find(o => o.kind === "sourcemap");
expect(sourcemapOutput).toBeDefined();
const mapContent = await sourcemapOutput!.text();
const map = JSON.parse(mapContent);
// Sources should contain just the filename or a relative path, not "../"
for (const source of map.sources) {
expect(source).not.toMatch(/^\.\.\//);
// Verify the source path ends with "index.ts"
expect(source).toEndWith("index.ts");
}
// Verify we have exactly one source file
expect(map.sources).toHaveLength(1);
});
});