mirror of
https://github.com/oven-sh/bun
synced 2026-02-05 00:18:53 +00:00
Compare commits
6 Commits
claude/imp
...
claude/imp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed00f377cd | ||
|
|
a0e4bd541d | ||
|
|
02e46e65eb | ||
|
|
ef8148f7f2 | ||
|
|
52c41ed931 | ||
|
|
1f06b43d30 |
@@ -1189,6 +1189,72 @@ pub fn transpileSourceCode(
|
||||
break :brk ResolvedSource.Tag.javascript;
|
||||
},
|
||||
};
|
||||
} else if (bun.sourcemap.JSSourceMap.@"--enable-source-maps") {
|
||||
// When --enable-source-maps is enabled and there's no cache entry (i.e., file wasn't transpiled),
|
||||
// check if the source has a user-provided sourceMappingURL and register it
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[ModuleLoader] --enable-source-maps is ON, checking for user sourcemap in: {s}", .{source.path.text});
|
||||
Output.flush();
|
||||
}
|
||||
const source_contents = source.contents;
|
||||
// Look for sourceMappingURL in the last ~500 characters of the file
|
||||
const search_start = if (source_contents.len > 500) source_contents.len - 500 else 0;
|
||||
const search_region = source_contents[search_start..];
|
||||
if (bun.strings.lastIndexOf(search_region, "//# sourceMappingURL=")) |url_idx| {
|
||||
const url_start = search_start + url_idx + "//# sourceMappingURL=".len;
|
||||
const url_end = bun.strings.indexOfAny(source_contents[url_start..], "\r\n") orelse
|
||||
(source_contents.len - url_start);
|
||||
const source_map_url = bun.strings.trim(source_contents[url_start..][0..url_end], " \r\t");
|
||||
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[ModuleLoader] Found sourceMappingURL: {s}", .{source_map_url});
|
||||
Output.flush();
|
||||
}
|
||||
|
||||
// Use a stack fallback allocator for temporary parsing
|
||||
var sfb = std.heap.stackFallback(8192, bun.default_allocator);
|
||||
const temp_alloc = sfb.get();
|
||||
|
||||
// If the URL is not a data: URL, resolve it relative to the source file
|
||||
const resolved_url = if (!bun.strings.startsWith(source_map_url, "data:"))
|
||||
bun.path.joinAbs(std.fs.path.dirname(source.path.text) orelse "/", .auto, source_map_url)
|
||||
else
|
||||
source_map_url;
|
||||
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[ModuleLoader] Resolved URL: {s}", .{resolved_url});
|
||||
Output.flush();
|
||||
}
|
||||
|
||||
// Try to parse the sourcemap URL (handles both inline and external)
|
||||
const parse = SourceMap.parseUrl(
|
||||
bun.default_allocator,
|
||||
temp_alloc,
|
||||
resolved_url,
|
||||
.mappings_only,
|
||||
) catch null;
|
||||
|
||||
if (parse) |p| {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[ModuleLoader] Parse result has map: {}", .{p.map != null});
|
||||
Output.flush();
|
||||
}
|
||||
if (p.map) |map| {
|
||||
// Register the parsed source map
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[ModuleLoader] Registering sourcemap for: {s}", .{source.path.text});
|
||||
Output.flush();
|
||||
}
|
||||
map.ref();
|
||||
jsc_vm.source_mappings.putValue(source.path.text, SavedSourceMap.Value.init(map)) catch {};
|
||||
}
|
||||
} else {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[ModuleLoader] Parse returned null!", .{});
|
||||
Output.flush();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const start_count = jsc_vm.transpiler.linker.import_counter;
|
||||
@@ -2510,6 +2576,42 @@ pub const RuntimeTranspilerStore = struct {
|
||||
};
|
||||
|
||||
return;
|
||||
} else if (bun.sourcemap.JSSourceMap.@"--enable-source-maps") {
|
||||
// When --enable-source-maps is enabled and there's no cache entry,
|
||||
// check if the source has a user-provided sourceMappingURL and register it
|
||||
const source_contents = parse_result.source.contents;
|
||||
// Look for sourceMappingURL in the last ~500 characters of the file
|
||||
const search_start = if (source_contents.len > 500) source_contents.len - 500 else 0;
|
||||
const search_region = source_contents[search_start..];
|
||||
if (bun.strings.lastIndexOf(search_region, "//# sourceMappingURL=")) |url_idx| {
|
||||
const url_start = search_start + url_idx + "//# sourceMappingURL=".len;
|
||||
const url_end = bun.strings.indexOfAny(source_contents[url_start..], "\r\n") orelse
|
||||
(source_contents.len - url_start);
|
||||
const source_map_url = bun.strings.trim(source_contents[url_start..][0..url_end], " \r\t");
|
||||
|
||||
var sfb = std.heap.stackFallback(8192, bun.default_allocator);
|
||||
const temp_alloc = sfb.get();
|
||||
|
||||
// If the URL is not a data: URL, resolve it relative to the source file
|
||||
const resolved_url = if (!bun.strings.startsWith(source_map_url, "data:"))
|
||||
bun.path.joinAbs(std.fs.path.dirname(parse_result.source.path.text) orelse "/", .auto, source_map_url)
|
||||
else
|
||||
source_map_url;
|
||||
|
||||
const parse = SourceMap.parseUrl(
|
||||
bun.default_allocator,
|
||||
temp_alloc,
|
||||
resolved_url,
|
||||
.mappings_only,
|
||||
) catch null;
|
||||
|
||||
if (parse) |p| {
|
||||
if (p.map) |map| {
|
||||
map.ref();
|
||||
vm.source_mappings.putValue(parse_result.source.path.text, SavedSourceMap.Value.init(map)) catch {};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (parse_result.already_bundled != .none) {
|
||||
@@ -3104,6 +3206,8 @@ const Arena = bun.allocators.MimallocArena;
|
||||
const api = bun.schema.api;
|
||||
|
||||
const jsc = bun.jsc;
|
||||
const SourceMap = bun.sourcemap;
|
||||
const SavedSourceMap = @import("./SavedSourceMap.zig");
|
||||
const JSGlobalObject = bun.jsc.JSGlobalObject;
|
||||
const JSValue = bun.jsc.JSValue;
|
||||
const ResolvedSource = bun.jsc.ResolvedSource;
|
||||
|
||||
@@ -3466,8 +3466,25 @@ pub fn resolveSourceMapping(
|
||||
column: Ordinal,
|
||||
source_handling: SourceMap.SourceContentHandling,
|
||||
) ?SourceMap.Mapping.Lookup {
|
||||
return this.source_mappings.resolveMapping(path, line, column, source_handling) orelse {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] resolveSourceMapping: path={s}, line={d}, col={d}, flag={}", .{
|
||||
path,
|
||||
line.zeroBased(),
|
||||
column.zeroBased(),
|
||||
bun.sourcemap.JSSourceMap.@"--enable-source-maps",
|
||||
});
|
||||
}
|
||||
|
||||
const result = this.source_mappings.resolveMapping(path, line, column, source_handling);
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] source_mappings.resolveMapping returned: {}", .{result != null});
|
||||
}
|
||||
|
||||
return result orelse {
|
||||
if (this.standalone_module_graph) |graph| {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Trying standalone module graph...", .{});
|
||||
}
|
||||
const file = graph.find(path) orelse return null;
|
||||
const map = file.sourcemap.load() orelse return null;
|
||||
|
||||
@@ -3486,10 +3503,166 @@ pub fn resolveSourceMapping(
|
||||
};
|
||||
}
|
||||
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] No standalone module graph, checking flag...", .{});
|
||||
}
|
||||
|
||||
// When --enable-source-maps is enabled, try to load external source maps
|
||||
if (bun.sourcemap.JSSourceMap.@"--enable-source-maps") {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Flag is enabled! Calling tryLoadExternalSourceMap...", .{});
|
||||
}
|
||||
return this.tryLoadExternalSourceMap(path, line, column, source_handling);
|
||||
}
|
||||
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Flag is NOT enabled, returning null", .{});
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
}
|
||||
|
||||
fn tryLoadExternalSourceMap(
|
||||
this: *VirtualMachine,
|
||||
path: []const u8,
|
||||
line: Ordinal,
|
||||
column: Ordinal,
|
||||
source_handling: SourceMap.SourceContentHandling,
|
||||
) ?SourceMap.Mapping.Lookup {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] tryLoadExternalSourceMap: path={s}, line={d}, col={d}", .{ path, line.zeroBased(), column.zeroBased() });
|
||||
}
|
||||
|
||||
const hint: SourceMap.ParseUrlResultHint = switch (source_handling) {
|
||||
.no_source_contents => .mappings_only,
|
||||
.source_contents => .{ .all = .{ .line = @max(line.zeroBased(), 0), .column = @max(column.zeroBased(), 0) } },
|
||||
};
|
||||
|
||||
// Use a stack fallback allocator for temporary allocations
|
||||
var sfb = std.heap.stackFallback(4096, bun.default_allocator);
|
||||
var arena = bun.ArenaAllocator.init(sfb.get());
|
||||
defer arena.deinit();
|
||||
const allocator = arena.allocator();
|
||||
|
||||
// First, try to read the source file and look for an inline source map
|
||||
const source_contents = switch (bun.sys.File.readFrom(std.fs.cwd(), path, allocator)) {
|
||||
.result => |contents| contents,
|
||||
.err => |e| {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Failed to read source file: {}", .{e});
|
||||
}
|
||||
// If we can't read the file, try external .map file
|
||||
return tryLoadExternalMapFile(this, path, line, column, hint, allocator);
|
||||
},
|
||||
};
|
||||
|
||||
// Look for sourceMappingURL comment
|
||||
const source_slice = source_contents;
|
||||
if (bun.strings.lastIndexOfChar(source_slice, '\n')) |last_newline_idx| {
|
||||
const last_lines = source_slice[last_newline_idx..];
|
||||
if (bun.strings.indexOf(last_lines, "//# sourceMappingURL=")) |url_start_idx| {
|
||||
const url_start = last_newline_idx + url_start_idx + "//# sourceMappingURL=".len;
|
||||
const url_end = bun.strings.indexOfChar(source_slice[url_start..], '\n') orelse
|
||||
(source_slice.len - url_start);
|
||||
const source_map_url = bun.strings.trim(source_slice[url_start..][0..url_end], " \r\t");
|
||||
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Found sourceMappingURL: {s}", .{source_map_url});
|
||||
}
|
||||
|
||||
// Try to parse as inline data: URL or external file
|
||||
const parse = SourceMap.parseUrl(
|
||||
bun.default_allocator,
|
||||
allocator,
|
||||
source_map_url,
|
||||
hint,
|
||||
) catch |err| {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Failed to parse URL: {}", .{err});
|
||||
}
|
||||
// If inline fails, try external .map file
|
||||
return tryLoadExternalMapFile(this, path, line, column, hint, allocator);
|
||||
};
|
||||
|
||||
if (parse.map) |map| {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Successfully parsed source map, looking for mapping...", .{});
|
||||
}
|
||||
const mapping = parse.mapping orelse map.mappings.find(line, column) orelse {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] No mapping found for line={d}, col={d}", .{ line.zeroBased(), column.zeroBased() });
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyErrorln("[sourcemap] Found mapping! original line={d}, col={d}", .{ mapping.original.lines, mapping.original.columns });
|
||||
}
|
||||
|
||||
// Cache the parsed source map for future lookups
|
||||
map.ref();
|
||||
this.source_mappings.putValue(path, SavedSourceMap.Value.init(map)) catch {};
|
||||
|
||||
return .{
|
||||
.mapping = mapping,
|
||||
.source_map = map,
|
||||
.prefetched_source_code = parse.source_contents,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back to external .map file
|
||||
return tryLoadExternalMapFile(this, path, line, column, hint, allocator);
|
||||
}
|
||||
|
||||
fn tryLoadExternalMapFile(
|
||||
this: *VirtualMachine,
|
||||
path: []const u8,
|
||||
line: Ordinal,
|
||||
column: Ordinal,
|
||||
hint: SourceMap.ParseUrlResultHint,
|
||||
allocator: std.mem.Allocator,
|
||||
) ?SourceMap.Mapping.Lookup {
|
||||
// Try to read and parse external source map from disk
|
||||
var buf: bun.PathBuffer = undefined;
|
||||
@memcpy(buf[0..path.len], path);
|
||||
@memcpy(buf[path.len..][0..4], ".map");
|
||||
const map_path = buf[0 .. path.len + 4];
|
||||
|
||||
const map_data = switch (bun.sys.File.readFrom(std.fs.cwd(), map_path, allocator)) {
|
||||
.result => |data| data,
|
||||
.err => {
|
||||
// No source map file found - this is not an error, just means no source map exists
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
const parse = SourceMap.parseJSON(
|
||||
bun.default_allocator,
|
||||
allocator,
|
||||
map_data,
|
||||
hint,
|
||||
) catch {
|
||||
// Invalid source map - ignore it
|
||||
return null;
|
||||
};
|
||||
|
||||
const map = parse.map orelse return null;
|
||||
const mapping = parse.mapping orelse map.mappings.find(line, column) orelse return null;
|
||||
|
||||
// Cache the parsed source map for future lookups
|
||||
map.ref();
|
||||
this.source_mappings.putValue(path, SavedSourceMap.Value.init(map)) catch {};
|
||||
|
||||
return .{
|
||||
.mapping = mapping,
|
||||
.source_map = map,
|
||||
.prefetched_source_code = parse.source_contents,
|
||||
};
|
||||
}
|
||||
|
||||
extern fn Process__emitMessageEvent(global: *JSGlobalObject, value: JSValue, handle: JSValue) void;
|
||||
extern fn Process__emitDisconnectEvent(global: *JSGlobalObject) void;
|
||||
pub extern fn Process__emitErrorEvent(global: *JSGlobalObject, value: JSValue) void;
|
||||
|
||||
@@ -113,6 +113,7 @@ pub const runtime_params_ = [_]ParamType{
|
||||
clap.parseParam("--unhandled-rejections <STR> One of \"strict\", \"throw\", \"warn\", \"none\", or \"warn-with-error-code\"") catch unreachable,
|
||||
clap.parseParam("--console-depth <NUMBER> Set the default depth for console.log object inspection (default: 2)") catch unreachable,
|
||||
clap.parseParam("--user-agent <STR> Set the default User-Agent header for HTTP requests") catch unreachable,
|
||||
clap.parseParam("--enable-source-maps Enable Source Map V3 support for stack traces") catch unreachable,
|
||||
};
|
||||
|
||||
pub const auto_or_run_params = [_]ParamType{
|
||||
@@ -581,6 +582,10 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C
|
||||
|
||||
// runtime commands
|
||||
if (cmd == .AutoCommand or cmd == .RunCommand or cmd == .TestCommand or cmd == .RunAsNodeCommand) {
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[arguments] Entered runtime commands block, cmd={s}", .{@tagName(cmd)});
|
||||
Output.flush();
|
||||
}
|
||||
{
|
||||
const preloads = args.options("--preload");
|
||||
const preloads2 = args.options("--require");
|
||||
@@ -713,6 +718,19 @@ pub fn parse(allocator: std.mem.Allocator, ctx: Command.Context, comptime cmd: C
|
||||
ctx.runtime_options.preconnect = args.options("--fetch-preconnect");
|
||||
ctx.runtime_options.expose_gc = args.flag("--expose-gc");
|
||||
|
||||
const enable_source_maps_flag = args.flag("--enable-source-maps");
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[arguments] Checking --enable-source-maps flag: {}", .{enable_source_maps_flag});
|
||||
Output.flush();
|
||||
}
|
||||
if (enable_source_maps_flag) {
|
||||
bun.sourcemap.JSSourceMap.@"--enable-source-maps" = true;
|
||||
if (bun.Environment.isDebug) {
|
||||
Output.prettyln("[arguments] --enable-source-maps flag set to true", .{});
|
||||
Output.flush();
|
||||
}
|
||||
}
|
||||
|
||||
if (args.option("--console-depth")) |depth_str| {
|
||||
const depth = std.fmt.parseInt(u16, depth_str, 10) catch {
|
||||
Output.errGeneric("Invalid value for --console-depth: \"{s}\". Must be a positive integer\n", .{depth_str});
|
||||
|
||||
176
test/cli/run/enable-source-maps.test.ts
Normal file
176
test/cli/run/enable-source-maps.test.ts
Normal file
@@ -0,0 +1,176 @@
|
||||
import { expect, test } from "bun:test";
|
||||
import { bunEnv, bunExe, tempDir } from "harness";
|
||||
|
||||
test("--enable-source-maps should use user-provided inline source maps in stack traces", async () => {
|
||||
// Create a transpiled file with an inline source map
|
||||
// Original source:
|
||||
// function throwError() {
|
||||
// throw new Error("original error");
|
||||
// }
|
||||
// throwError();
|
||||
|
||||
const originalSource = `function throwError() {
|
||||
throw new Error("original error");
|
||||
}
|
||||
throwError();`;
|
||||
|
||||
// Transpiled (minified) version with inline sourcemap
|
||||
const transpiledWithSourceMap = `function a(){throw new Error("original error")}a();
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImlucHV0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImZ1bmN0aW9uIHRocm93RXJyb3IoKSB7XG4gIHRocm93IG5ldyBFcnJvcihcIm9yaWdpbmFsIGVycm9yXCIpO1xufVxudGhyb3dFcnJvcigpOyJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBQUEsSUFDRSxNQUFNLElBQUksTUFBTSxnQkFDbEIsQ0FDQUEsR0FBQSIsIm5hbWVzIjpbInRocm93RXJyb3IiXX0=`;
|
||||
|
||||
using dir = tempDir("enable-source-maps", {
|
||||
"input.js": transpiledWithSourceMap,
|
||||
});
|
||||
|
||||
// Test WITHOUT --enable-source-maps: should show transpiled locations
|
||||
{
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "input.js"],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(exitCode).toBe(1);
|
||||
// Without --enable-source-maps, the error should reference the transpiled file
|
||||
// The error occurs at function 'a()' not 'throwError()'
|
||||
expect(stderr).toContain("input.js");
|
||||
// Stack trace should NOT show the original function name
|
||||
expect(stderr).not.toContain("throwError");
|
||||
}
|
||||
|
||||
// Test WITH --enable-source-maps: should show original source locations
|
||||
{
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "--enable-source-maps", "input.js"],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(exitCode).toBe(1);
|
||||
// With --enable-source-maps, the error should reference the original source
|
||||
expect(stderr).toContain("input.ts");
|
||||
// Stack trace SHOULD show the original function name
|
||||
expect(stderr).toContain("throwError");
|
||||
}
|
||||
});
|
||||
|
||||
test("--enable-source-maps should use external source map files", async () => {
|
||||
// Create a file with an external source map reference
|
||||
const transpiledCode = `function a(){throw new Error("test error")}a();
|
||||
//# sourceMappingURL=output.js.map`;
|
||||
|
||||
// Create the external source map file
|
||||
const sourceMap = {
|
||||
version: 3,
|
||||
sources: ["original.ts"],
|
||||
sourcesContent: ['function throwError() {\n throw new Error("test error");\n}\nthrowError();'],
|
||||
mappings: "AAAA,SAASA,IACE,MAAM,IAAI,MAAM,aAClB,CACAA,GAAA",
|
||||
names: ["throwError"],
|
||||
};
|
||||
|
||||
using dir = tempDir("enable-source-maps-external", {
|
||||
"output.js": transpiledCode,
|
||||
"output.js.map": JSON.stringify(sourceMap),
|
||||
});
|
||||
|
||||
// Test WITHOUT --enable-source-maps
|
||||
{
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "output.js"],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(exitCode).toBe(1);
|
||||
expect(stderr).toContain("output.js");
|
||||
expect(stderr).not.toContain("original.ts");
|
||||
}
|
||||
|
||||
// Test WITH --enable-source-maps
|
||||
{
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "--enable-source-maps", "output.js"],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stderr, exitCode] = await Promise.all([proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(exitCode).toBe(1);
|
||||
// With --enable-source-maps, should reference original source
|
||||
expect(stderr).toContain("original.ts");
|
||||
expect(stderr).toContain("throwError");
|
||||
}
|
||||
});
|
||||
|
||||
test("--enable-source-maps should work with findSourceMap from node:module", async () => {
|
||||
const code = `import { findSourceMap } from "node:module";
|
||||
|
||||
const sourceMap = findSourceMap(import.meta.path);
|
||||
|
||||
if (!sourceMap) {
|
||||
console.error("No source map found");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("Source map found!");
|
||||
console.log("Has payload:", !!sourceMap.payload);
|
||||
console.log("Has findEntry:", typeof sourceMap.findEntry === "function");
|
||||
process.exit(0);
|
||||
`;
|
||||
|
||||
const transpiledWithSourceMap = `import{findSourceMap as a}from"node:module";const b=a(import.meta.path);if(!b){console.error("No source map found");process.exit(1)}console.log("Source map found!");console.log("Has payload:",!!b.payload);console.log("Has findEntry:",typeof b.findEntry==="function");process.exit(0);
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZmluZFNvdXJjZU1hcCB9IGZyb20gXCJub2RlOm1vZHVsZVwiO1xuXG5jb25zdCBzb3VyY2VNYXAgPSBmaW5kU291cmNlTWFwKGltcG9ydC5tZXRhLnBhdGgpO1xuXG5pZiAoIXNvdXJjZU1hcCkge1xuICBjb25zb2xlLmVycm9yKFwiTm8gc291cmNlIG1hcCBmb3VuZFwiKTtcbiAgcHJvY2Vzcy5leGl0KDEpO1xufVxuXG5jb25zb2xlLmxvZyhcIlNvdXJjZSBtYXAgZm91bmQhXCIpO1xuY29uc29sZS5sb2coXCJIYXMgcGF5bG9hZDpcIiwgISFzb3VyY2VNYXAucGF5bG9hZCk7XG5jb25zb2xlLmxvZyhcIkhhcyBmaW5kRW50cnk6XCIsIHR5cGVvZiBzb3VyY2VNYXAuZmluZEVudHJ5ID09PSBcImZ1bmN0aW9uXCIpO1xucHJvY2Vzcy5leGl0KDApOyJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsT0FBQUEsZUFBQUEsS0FBQSxlQUFBLENBRVAsTUFBTUMsRUFBQUQsRUFBQUEsT0FBQUEsS0FBQUEsS0FBQSxLQUFBLENBRUEsR0FBQSxDQUFBQyxFQUFBLENBQ0EsUUFBQSxNQUFBLHFCQUFBLEVBQ0EsUUFBQSxLQUFBLEVBQUEsQ0FDQSxDQUVBLFFBQUEsSUFBQSxvQkFBQSxFQUNBLFFBQUEsSUFBQSxlQUFBLENBQUEsQ0FBQUEsRUFBQSxRQUFBLEVBQ0EsUUFBQSxJQUFBLGdCQUFBLE9BQU9BLEVBQUEsV0FBQSxXQUFBLEVBQ1AsUUFBQSxLQUFBLEVBQUEiLCJuYW1lcyI6WyJmaW5kU291cmNlTWFwIiwic291cmNlTWFwIl19`;
|
||||
|
||||
using dir = tempDir("enable-source-maps-api", {
|
||||
"test.js": transpiledWithSourceMap,
|
||||
});
|
||||
|
||||
// Test WITHOUT --enable-source-maps: should not find source map
|
||||
{
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "test.js"],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(exitCode).toBe(1);
|
||||
expect(stderr).toContain("No source map found");
|
||||
}
|
||||
|
||||
// Test WITH --enable-source-maps: should find source map
|
||||
{
|
||||
await using proc = Bun.spawn({
|
||||
cmd: [bunExe(), "--enable-source-maps", "test.js"],
|
||||
env: bunEnv,
|
||||
cwd: String(dir),
|
||||
stderr: "pipe",
|
||||
stdout: "pipe",
|
||||
});
|
||||
|
||||
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
|
||||
|
||||
expect(exitCode).toBe(0);
|
||||
expect(stdout).toContain("Source map found!");
|
||||
expect(stdout).toContain("Has payload: true");
|
||||
expect(stdout).toContain("Has findEntry: function");
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user