mirror of
https://github.com/oven-sh/bun
synced 2026-02-16 05:42:43 +00:00
Add sourcemap support to Bun's bundler plugin system
Co-authored-by: jarred <jarred@bun.sh>
This commit is contained in:
19
packages/bun-types/bun.d.ts
vendored
19
packages/bun-types/bun.d.ts
vendored
@@ -794,7 +794,6 @@ declare module "bun" {
|
||||
path?: string | undefined;
|
||||
syscall?: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenate an array of typed arrays into a single `ArrayBuffer`. This is a fast path.
|
||||
*
|
||||
@@ -1419,7 +1418,6 @@ declare module "bun" {
|
||||
* @param sql Function to execute SQL queries within the savepoint
|
||||
*/
|
||||
type SQLSavepointContextCallback = (sql: SavepointSQL) => Promise<any> | Array<SQLQuery>;
|
||||
|
||||
/**
|
||||
* Main SQL client interface providing connection and transaction management
|
||||
*/
|
||||
@@ -2129,7 +2127,6 @@ declare module "bun" {
|
||||
path: string;
|
||||
kind: ImportKind;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see [Bun.build API docs](https://bun.sh/docs/bundler#api)
|
||||
*/
|
||||
@@ -2853,7 +2850,6 @@ declare module "bun" {
|
||||
* @link https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/readyState
|
||||
*/
|
||||
type WebSocketReadyState = 0 | 1 | 2 | 3;
|
||||
|
||||
/**
|
||||
* A fast WebSocket designed for servers.
|
||||
*
|
||||
@@ -3654,7 +3650,6 @@ declare module "bun" {
|
||||
errno?: number;
|
||||
syscall?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for TLS connections
|
||||
*/
|
||||
@@ -4437,7 +4432,6 @@ declare module "bun" {
|
||||
* This can be 3.5x faster than `new Uint8Array(size)`, but if you send uninitialized memory to your users (even unintentionally), it can potentially leak anything recently in memory.
|
||||
*/
|
||||
function allocUnsafe(size: number): Uint8Array;
|
||||
|
||||
/**
|
||||
* Options for `Bun.inspect`
|
||||
*/
|
||||
@@ -5222,7 +5216,6 @@ declare module "bun" {
|
||||
* Internally, it calls [nanosleep(2)](https://man7.org/linux/man-pages/man2/nanosleep.2.html)
|
||||
*/
|
||||
function sleepSync(ms: number): void;
|
||||
|
||||
/**
|
||||
* Hash `input` using [SHA-2 512/256](https://en.wikipedia.org/wiki/SHA-2#Comparison_of_SHA_functions)
|
||||
*
|
||||
@@ -5549,6 +5542,10 @@ declare module "bun" {
|
||||
* The source code of the module
|
||||
*/
|
||||
contents: string | ArrayBufferView | ArrayBuffer | SharedArrayBuffer;
|
||||
/**
|
||||
* Optional sourcemap (as a string) for the generated contents.
|
||||
*/
|
||||
sourcemap?: string;
|
||||
/**
|
||||
* The loader to use for this file
|
||||
*
|
||||
@@ -5883,7 +5880,6 @@ declare module "bun" {
|
||||
interface HTMLBundle {
|
||||
index: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a TCP or TLS socket connection used for network communication.
|
||||
* This interface provides methods for reading, writing, managing the connection state,
|
||||
@@ -6625,7 +6621,6 @@ declare module "bun" {
|
||||
* @category HTTP & Networking
|
||||
*/
|
||||
function listen<Data = undefined>(options: UnixSocketOptions<Data>): UnixSocketListener<Data>;
|
||||
|
||||
/**
|
||||
* @category HTTP & Networking
|
||||
*/
|
||||
@@ -7247,7 +7242,7 @@ declare module "bun" {
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const subprocess = Bun.spawn(["echo", "hello"]);
|
||||
* const subprocess = Bun.spawn({ cmd: ["echo", "hello"] });
|
||||
* ```
|
||||
*/
|
||||
cmd: string[]; // to support dynamically constructed commands
|
||||
@@ -7365,7 +7360,7 @@ declare module "bun" {
|
||||
type WritableSubprocess = Subprocess<"pipe", any, any>;
|
||||
/** Utility type for any process from {@link Bun.spawn()} with stdin, stdout, stderr all set to `"pipe"`. A combination of {@link ReadableSubprocess} and {@link WritableSubprocess} */
|
||||
type PipedSubprocess = Subprocess<"pipe", "pipe", "pipe">;
|
||||
/** Utility type for any process from {@link Bun.spawn()} with stdin, stdout, stderr all set to `null` or similar. */
|
||||
/** Utility type for any process from {@link Bun.spawn()} with stdin, stdout, stderr all set to `null` or similar */
|
||||
type NullSubprocess = Subprocess<
|
||||
"ignore" | "inherit" | null | undefined,
|
||||
"ignore" | "inherit" | null | undefined,
|
||||
@@ -8042,4 +8037,4 @@ declare module "bun" {
|
||||
*/
|
||||
[Symbol.iterator](): IterableIterator<[string, string]>;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,6 +729,7 @@ pub const JSBundler = struct {
|
||||
success: struct {
|
||||
source_code: []const u8 = "",
|
||||
loader: options.Loader = .file,
|
||||
sourcemap: ?[]const u8 = null,
|
||||
},
|
||||
pending,
|
||||
no_match,
|
||||
@@ -739,6 +740,9 @@ pub const JSBundler = struct {
|
||||
switch (this.*) {
|
||||
.success => |success| {
|
||||
bun.default_allocator.free(success.source_code);
|
||||
if (success.sourcemap) |sm| {
|
||||
bun.default_allocator.free(sm);
|
||||
}
|
||||
},
|
||||
.err => |*err| {
|
||||
err.deinit(bun.default_allocator);
|
||||
@@ -817,6 +821,7 @@ pub const JSBundler = struct {
|
||||
_: *anyopaque,
|
||||
source_code_value: JSValue,
|
||||
loader_as_int: JSValue,
|
||||
sourcemap_value: JSValue,
|
||||
) void {
|
||||
JSC.markBinding(@src());
|
||||
if (source_code_value.isEmptyOrUndefinedOrNull() or loader_as_int.isEmptyOrUndefinedOrNull()) {
|
||||
@@ -841,10 +846,18 @@ pub const JSBundler = struct {
|
||||
|
||||
@panic("Unexpected: source_code is not a string");
|
||||
};
|
||||
|
||||
var maybe_sourcemap: ?[]const u8 = null;
|
||||
if (!sourcemap_value.isEmptyOrUndefinedOrNull()) {
|
||||
if (sourcemap_value.isString()) {
|
||||
maybe_sourcemap = sourcemap_value.toSliceCloneWithAllocator(global, bun.default_allocator);
|
||||
}
|
||||
}
|
||||
this.value = .{
|
||||
.success = .{
|
||||
.loader = options.Loader.fromAPI(loader),
|
||||
.source_code = source_code,
|
||||
.sourcemap = maybe_sourcemap,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ extern "C" void OnBeforeParseResult__reset(OnBeforeParseResult* result);
|
||||
|
||||
/// These are callbacks defined in Zig and to be run after their associated JS version is run
|
||||
extern "C" void JSBundlerPlugin__addError(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
extern "C" void JSBundlerPlugin__onLoadAsync(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
extern "C" void JSBundlerPlugin__onLoadAsync(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
extern "C" void JSBundlerPlugin__onResolveAsync(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
extern "C" void JSBundlerPlugin__onVirtualModulePlugin(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
extern "C" JSC::EncodedJSValue JSBundlerPlugin__onDefer(void*, JSC::JSGlobalObject*);
|
||||
@@ -111,7 +111,7 @@ bool BundlerPlugin::anyMatchesCrossThread(JSC::VM& vm, const BunString* namespac
|
||||
static const HashTableValue JSBundlerPluginHashTable[] = {
|
||||
{ "addFilter"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_addFilter, 3 } },
|
||||
{ "addError"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_addError, 3 } },
|
||||
{ "onLoadAsync"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_onLoadAsync, 3 } },
|
||||
{ "onLoadAsync"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_onLoadAsync, 4 } },
|
||||
{ "onResolveAsync"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_onResolveAsync, 4 } },
|
||||
{ "onBeforeParse"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_onBeforeParse, 4 } },
|
||||
{ "generateDeferPromise"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete), NoIntrinsic, { HashTableValue::NativeFunctionType, jsBundlerPluginFunction_generateDeferPromise, 0 } },
|
||||
@@ -402,7 +402,8 @@ JSC_DEFINE_HOST_FUNCTION(jsBundlerPluginFunction_onLoadAsync, (JSC::JSGlobalObje
|
||||
UNWRAP_BUNDLER_PLUGIN(callFrame),
|
||||
thisObject->plugin.config,
|
||||
JSValue::encode(callFrame->argument(1)),
|
||||
JSValue::encode(callFrame->argument(2)));
|
||||
JSValue::encode(callFrame->argument(2)),
|
||||
JSValue::encode(callFrame->argument(3)));
|
||||
}
|
||||
|
||||
return JSC::JSValue::encode(JSC::jsUndefined());
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <JavaScriptCore/Yarr.h>
|
||||
|
||||
typedef void (*JSBundlerPluginAddErrorCallback)(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
typedef void (*JSBundlerPluginOnLoadAsyncCallback)(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
typedef void (*JSBundlerPluginOnLoadAsyncCallback)(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
typedef void (*JSBundlerPluginOnResolveAsyncCallback)(void*, void*, JSC::EncodedJSValue, JSC::EncodedJSValue, JSC::EncodedJSValue);
|
||||
typedef void (*JSBundlerPluginNativeOnBeforeParseCallback)(const OnBeforeParseArguments*, OnBeforeParseResult*);
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ interface BundlerPlugin {
|
||||
internalID,
|
||||
sourceCode: string | Uint8Array | ArrayBuffer | DataView | null,
|
||||
loaderKey: number | null,
|
||||
sourcemap: string | null,
|
||||
): void;
|
||||
/** Binding to `JSBundlerPlugin__onResolveAsync` */
|
||||
onResolveAsync(internalID, a, b, c): void;
|
||||
@@ -458,7 +459,7 @@ export function runOnLoadPlugins(
|
||||
var promiseResult = (async (internalID, path, namespace, isServerSide, defaultLoader, generateDefer) => {
|
||||
var results = this.onLoad.$get(namespace);
|
||||
if (!results) {
|
||||
this.onLoadAsync(internalID, null, null);
|
||||
this.onLoadAsync(internalID, null, null, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -490,7 +491,7 @@ export function runOnLoadPlugins(
|
||||
continue;
|
||||
}
|
||||
|
||||
var { contents, loader = defaultLoader } = result as any;
|
||||
var { contents, loader = defaultLoader, sourcemap } = result as any;
|
||||
if ((loader as any) === "object") {
|
||||
if (!("exports" in result)) {
|
||||
throw new TypeError('onLoad plugin returning loader: "object" must have "exports" property');
|
||||
@@ -516,12 +517,12 @@ export function runOnLoadPlugins(
|
||||
throw new TypeError(`Loader ${loader} is not supported.`);
|
||||
}
|
||||
|
||||
this.onLoadAsync(internalID, contents as any, chosenLoader);
|
||||
this.onLoadAsync(internalID, contents as any, chosenLoader, sourcemap ?? null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
this.onLoadAsync(internalID, null, null);
|
||||
this.onLoadAsync(internalID, null, null, null);
|
||||
return null;
|
||||
})(internalID, path, namespace, isServerSide, loaderName, generateDefer);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user