mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
Refactor: Extract ModuleLoader components into separate files (#24083)
## Summary Split `ModuleLoader.zig` into smaller, more focused modules for better code organization and maintainability: - `AsyncModule` → `src/bun.js/AsyncModule.zig` (lines 69-806) - `RuntimeTranspilerStore` → `src/bun.js/RuntimeTranspilerStore.zig` (lines 2028-2606) - `HardcodedModule` → `src/bun.js/HardcodedModule.zig` (lines 2618-3040) ## Changes - Extracted three large components from `ModuleLoader.zig` into separate files - Updated imports in all affected files - Made necessary functions/constants public (`dumpSource`, `dumpSourceString`, `setBreakPointOnFirstLine`, `bun_aliases`) - Updated `ModuleLoader.zig` to import the new modules ## Testing - Build passes successfully (`bun bd`) - Basic module loading verified with smoke tests - Existing resolve tests continue to pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Bot <claude-bot@bun.sh> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
431
src/bun.js/HardcodedModule.zig
Normal file
431
src/bun.js/HardcodedModule.zig
Normal file
@@ -0,0 +1,431 @@
|
||||
const string = []const u8;
|
||||
|
||||
pub const HardcodedModule = enum {
|
||||
bun,
|
||||
@"abort-controller",
|
||||
@"bun:app",
|
||||
@"bun:ffi",
|
||||
@"bun:jsc",
|
||||
@"bun:main",
|
||||
@"bun:test",
|
||||
@"bun:wrap",
|
||||
@"bun:sqlite",
|
||||
@"node:assert",
|
||||
@"node:assert/strict",
|
||||
@"node:async_hooks",
|
||||
@"node:buffer",
|
||||
@"node:child_process",
|
||||
@"node:console",
|
||||
@"node:constants",
|
||||
@"node:crypto",
|
||||
@"node:dns",
|
||||
@"node:dns/promises",
|
||||
@"node:domain",
|
||||
@"node:events",
|
||||
@"node:fs",
|
||||
@"node:fs/promises",
|
||||
@"node:http",
|
||||
@"node:https",
|
||||
@"node:module",
|
||||
@"node:net",
|
||||
@"node:os",
|
||||
@"node:path",
|
||||
@"node:path/posix",
|
||||
@"node:path/win32",
|
||||
@"node:perf_hooks",
|
||||
@"node:process",
|
||||
@"node:querystring",
|
||||
@"node:readline",
|
||||
@"node:readline/promises",
|
||||
@"node:stream",
|
||||
@"node:stream/consumers",
|
||||
@"node:stream/promises",
|
||||
@"node:stream/web",
|
||||
@"node:string_decoder",
|
||||
@"node:test",
|
||||
@"node:timers",
|
||||
@"node:timers/promises",
|
||||
@"node:tls",
|
||||
@"node:tty",
|
||||
@"node:url",
|
||||
@"node:util",
|
||||
@"node:util/types",
|
||||
@"node:vm",
|
||||
@"node:wasi",
|
||||
@"node:zlib",
|
||||
@"node:worker_threads",
|
||||
@"node:punycode",
|
||||
undici,
|
||||
ws,
|
||||
@"isomorphic-fetch",
|
||||
@"node-fetch",
|
||||
vercel_fetch,
|
||||
@"utf-8-validate",
|
||||
@"node:v8",
|
||||
@"node:trace_events",
|
||||
@"node:repl",
|
||||
@"node:inspector",
|
||||
@"node:http2",
|
||||
@"node:diagnostics_channel",
|
||||
@"node:dgram",
|
||||
@"node:cluster",
|
||||
@"node:_stream_duplex",
|
||||
@"node:_stream_passthrough",
|
||||
@"node:_stream_readable",
|
||||
@"node:_stream_transform",
|
||||
@"node:_stream_wrap",
|
||||
@"node:_stream_writable",
|
||||
@"node:_tls_common",
|
||||
@"node:_http_agent",
|
||||
@"node:_http_client",
|
||||
@"node:_http_common",
|
||||
@"node:_http_incoming",
|
||||
@"node:_http_outgoing",
|
||||
@"node:_http_server",
|
||||
/// This is gated behind '--expose-internals'
|
||||
@"bun:internal-for-testing",
|
||||
|
||||
/// The module loader first uses `Aliases` to get a single string during
|
||||
/// resolution, then maps that single string to the actual module.
|
||||
/// Do not include aliases here; Those go in `Aliases`.
|
||||
pub const map = bun.ComptimeStringMap(HardcodedModule, [_]struct { []const u8, HardcodedModule }{
|
||||
// Bun
|
||||
.{ "bun", .bun },
|
||||
.{ "bun:app", .@"bun:app" },
|
||||
.{ "bun:ffi", .@"bun:ffi" },
|
||||
.{ "bun:jsc", .@"bun:jsc" },
|
||||
.{ "bun:main", .@"bun:main" },
|
||||
.{ "bun:test", .@"bun:test" },
|
||||
.{ "bun:sqlite", .@"bun:sqlite" },
|
||||
.{ "bun:wrap", .@"bun:wrap" },
|
||||
.{ "bun:internal-for-testing", .@"bun:internal-for-testing" },
|
||||
// Node.js
|
||||
.{ "node:assert", .@"node:assert" },
|
||||
.{ "node:assert/strict", .@"node:assert/strict" },
|
||||
.{ "node:async_hooks", .@"node:async_hooks" },
|
||||
.{ "node:buffer", .@"node:buffer" },
|
||||
.{ "node:child_process", .@"node:child_process" },
|
||||
.{ "node:cluster", .@"node:cluster" },
|
||||
.{ "node:console", .@"node:console" },
|
||||
.{ "node:constants", .@"node:constants" },
|
||||
.{ "node:crypto", .@"node:crypto" },
|
||||
.{ "node:dgram", .@"node:dgram" },
|
||||
.{ "node:diagnostics_channel", .@"node:diagnostics_channel" },
|
||||
.{ "node:dns", .@"node:dns" },
|
||||
.{ "node:dns/promises", .@"node:dns/promises" },
|
||||
.{ "node:domain", .@"node:domain" },
|
||||
.{ "node:events", .@"node:events" },
|
||||
.{ "node:fs", .@"node:fs" },
|
||||
.{ "node:fs/promises", .@"node:fs/promises" },
|
||||
.{ "node:http", .@"node:http" },
|
||||
.{ "node:http2", .@"node:http2" },
|
||||
.{ "node:https", .@"node:https" },
|
||||
.{ "node:inspector", .@"node:inspector" },
|
||||
.{ "node:module", .@"node:module" },
|
||||
.{ "node:net", .@"node:net" },
|
||||
.{ "node:readline", .@"node:readline" },
|
||||
.{ "node:test", .@"node:test" },
|
||||
.{ "node:os", .@"node:os" },
|
||||
.{ "node:path", .@"node:path" },
|
||||
.{ "node:path/posix", .@"node:path/posix" },
|
||||
.{ "node:path/win32", .@"node:path/win32" },
|
||||
.{ "node:perf_hooks", .@"node:perf_hooks" },
|
||||
.{ "node:process", .@"node:process" },
|
||||
.{ "node:punycode", .@"node:punycode" },
|
||||
.{ "node:querystring", .@"node:querystring" },
|
||||
.{ "node:readline/promises", .@"node:readline/promises" },
|
||||
.{ "node:repl", .@"node:repl" },
|
||||
.{ "node:stream", .@"node:stream" },
|
||||
.{ "node:stream/consumers", .@"node:stream/consumers" },
|
||||
.{ "node:stream/promises", .@"node:stream/promises" },
|
||||
.{ "node:stream/web", .@"node:stream/web" },
|
||||
.{ "node:string_decoder", .@"node:string_decoder" },
|
||||
.{ "node:timers", .@"node:timers" },
|
||||
.{ "node:timers/promises", .@"node:timers/promises" },
|
||||
.{ "node:tls", .@"node:tls" },
|
||||
.{ "node:trace_events", .@"node:trace_events" },
|
||||
.{ "node:tty", .@"node:tty" },
|
||||
.{ "node:url", .@"node:url" },
|
||||
.{ "node:util", .@"node:util" },
|
||||
.{ "node:util/types", .@"node:util/types" },
|
||||
.{ "node:v8", .@"node:v8" },
|
||||
.{ "node:vm", .@"node:vm" },
|
||||
.{ "node:wasi", .@"node:wasi" },
|
||||
.{ "node:worker_threads", .@"node:worker_threads" },
|
||||
.{ "node:zlib", .@"node:zlib" },
|
||||
.{ "node:_stream_duplex", .@"node:_stream_duplex" },
|
||||
.{ "node:_stream_passthrough", .@"node:_stream_passthrough" },
|
||||
.{ "node:_stream_readable", .@"node:_stream_readable" },
|
||||
.{ "node:_stream_transform", .@"node:_stream_transform" },
|
||||
.{ "node:_stream_wrap", .@"node:_stream_wrap" },
|
||||
.{ "node:_stream_writable", .@"node:_stream_writable" },
|
||||
.{ "node:_tls_common", .@"node:_tls_common" },
|
||||
.{ "node:_http_agent", .@"node:_http_agent" },
|
||||
.{ "node:_http_client", .@"node:_http_client" },
|
||||
.{ "node:_http_common", .@"node:_http_common" },
|
||||
.{ "node:_http_incoming", .@"node:_http_incoming" },
|
||||
.{ "node:_http_outgoing", .@"node:_http_outgoing" },
|
||||
.{ "node:_http_server", .@"node:_http_server" },
|
||||
|
||||
.{ "node-fetch", HardcodedModule.@"node-fetch" },
|
||||
.{ "isomorphic-fetch", HardcodedModule.@"isomorphic-fetch" },
|
||||
.{ "undici", HardcodedModule.undici },
|
||||
.{ "ws", HardcodedModule.ws },
|
||||
.{ "@vercel/fetch", HardcodedModule.vercel_fetch },
|
||||
.{ "utf-8-validate", HardcodedModule.@"utf-8-validate" },
|
||||
.{ "abort-controller", HardcodedModule.@"abort-controller" },
|
||||
});
|
||||
|
||||
/// Contains the list of built-in modules from the perspective of the module
|
||||
/// loader. This logic is duplicated for `isBuiltinModule` and the like.
|
||||
pub const Alias = struct {
|
||||
path: [:0]const u8,
|
||||
tag: ImportRecord.Tag = .builtin,
|
||||
node_builtin: bool = false,
|
||||
node_only_prefix: bool = false,
|
||||
|
||||
fn nodeEntry(comptime path: [:0]const u8) struct { string, Alias } {
|
||||
return .{
|
||||
path,
|
||||
.{
|
||||
.path = if (path.len > 5 and std.mem.eql(u8, path[0..5], "node:")) path else "node:" ++ path,
|
||||
.node_builtin = true,
|
||||
},
|
||||
};
|
||||
}
|
||||
fn nodeEntryOnlyPrefix(comptime path: [:0]const u8) struct { string, Alias } {
|
||||
return .{
|
||||
path,
|
||||
.{
|
||||
.path = if (path.len > 5 and std.mem.eql(u8, path[0..5], "node:")) path else "node:" ++ path,
|
||||
.node_builtin = true,
|
||||
.node_only_prefix = true,
|
||||
},
|
||||
};
|
||||
}
|
||||
fn entry(comptime path: [:0]const u8) struct { string, Alias } {
|
||||
return .{ path, .{ .path = path } };
|
||||
}
|
||||
|
||||
// Applied to both --target=bun and --target=node
|
||||
const common_alias_kvs = [_]struct { string, Alias }{
|
||||
nodeEntry("node:assert"),
|
||||
nodeEntry("node:assert/strict"),
|
||||
nodeEntry("node:async_hooks"),
|
||||
nodeEntry("node:buffer"),
|
||||
nodeEntry("node:child_process"),
|
||||
nodeEntry("node:cluster"),
|
||||
nodeEntry("node:console"),
|
||||
nodeEntry("node:constants"),
|
||||
nodeEntry("node:crypto"),
|
||||
nodeEntry("node:dgram"),
|
||||
nodeEntry("node:diagnostics_channel"),
|
||||
nodeEntry("node:dns"),
|
||||
nodeEntry("node:dns/promises"),
|
||||
nodeEntry("node:domain"),
|
||||
nodeEntry("node:events"),
|
||||
nodeEntry("node:fs"),
|
||||
nodeEntry("node:fs/promises"),
|
||||
nodeEntry("node:http"),
|
||||
nodeEntry("node:http2"),
|
||||
nodeEntry("node:https"),
|
||||
nodeEntry("node:inspector"),
|
||||
nodeEntry("node:module"),
|
||||
nodeEntry("node:net"),
|
||||
nodeEntry("node:os"),
|
||||
nodeEntry("node:path"),
|
||||
nodeEntry("node:path/posix"),
|
||||
nodeEntry("node:path/win32"),
|
||||
nodeEntry("node:perf_hooks"),
|
||||
nodeEntry("node:process"),
|
||||
nodeEntry("node:punycode"),
|
||||
nodeEntry("node:querystring"),
|
||||
nodeEntry("node:readline"),
|
||||
nodeEntry("node:readline/promises"),
|
||||
nodeEntry("node:repl"),
|
||||
nodeEntry("node:stream"),
|
||||
nodeEntry("node:stream/consumers"),
|
||||
nodeEntry("node:stream/promises"),
|
||||
nodeEntry("node:stream/web"),
|
||||
nodeEntry("node:string_decoder"),
|
||||
nodeEntry("node:timers"),
|
||||
nodeEntry("node:timers/promises"),
|
||||
nodeEntry("node:tls"),
|
||||
nodeEntry("node:trace_events"),
|
||||
nodeEntry("node:tty"),
|
||||
nodeEntry("node:url"),
|
||||
nodeEntry("node:util"),
|
||||
nodeEntry("node:util/types"),
|
||||
nodeEntry("node:v8"),
|
||||
nodeEntry("node:vm"),
|
||||
nodeEntry("node:wasi"),
|
||||
nodeEntry("node:worker_threads"),
|
||||
nodeEntry("node:zlib"),
|
||||
// New Node.js builtins only resolve from the prefixed one.
|
||||
nodeEntryOnlyPrefix("node:test"),
|
||||
|
||||
nodeEntry("assert"),
|
||||
nodeEntry("assert/strict"),
|
||||
nodeEntry("async_hooks"),
|
||||
nodeEntry("buffer"),
|
||||
nodeEntry("child_process"),
|
||||
nodeEntry("cluster"),
|
||||
nodeEntry("console"),
|
||||
nodeEntry("constants"),
|
||||
nodeEntry("crypto"),
|
||||
nodeEntry("dgram"),
|
||||
nodeEntry("diagnostics_channel"),
|
||||
nodeEntry("dns"),
|
||||
nodeEntry("dns/promises"),
|
||||
nodeEntry("domain"),
|
||||
nodeEntry("events"),
|
||||
nodeEntry("fs"),
|
||||
nodeEntry("fs/promises"),
|
||||
nodeEntry("http"),
|
||||
nodeEntry("http2"),
|
||||
nodeEntry("https"),
|
||||
nodeEntry("inspector"),
|
||||
nodeEntry("module"),
|
||||
nodeEntry("net"),
|
||||
nodeEntry("os"),
|
||||
nodeEntry("path"),
|
||||
nodeEntry("path/posix"),
|
||||
nodeEntry("path/win32"),
|
||||
nodeEntry("perf_hooks"),
|
||||
nodeEntry("process"),
|
||||
nodeEntry("punycode"),
|
||||
nodeEntry("querystring"),
|
||||
nodeEntry("readline"),
|
||||
nodeEntry("readline/promises"),
|
||||
nodeEntry("repl"),
|
||||
nodeEntry("stream"),
|
||||
nodeEntry("stream/consumers"),
|
||||
nodeEntry("stream/promises"),
|
||||
nodeEntry("stream/web"),
|
||||
nodeEntry("string_decoder"),
|
||||
nodeEntry("timers"),
|
||||
nodeEntry("timers/promises"),
|
||||
nodeEntry("tls"),
|
||||
nodeEntry("trace_events"),
|
||||
nodeEntry("tty"),
|
||||
nodeEntry("url"),
|
||||
nodeEntry("util"),
|
||||
nodeEntry("util/types"),
|
||||
nodeEntry("v8"),
|
||||
nodeEntry("vm"),
|
||||
nodeEntry("wasi"),
|
||||
nodeEntry("worker_threads"),
|
||||
nodeEntry("zlib"),
|
||||
|
||||
nodeEntry("node:_http_agent"),
|
||||
nodeEntry("node:_http_client"),
|
||||
nodeEntry("node:_http_common"),
|
||||
nodeEntry("node:_http_incoming"),
|
||||
nodeEntry("node:_http_outgoing"),
|
||||
nodeEntry("node:_http_server"),
|
||||
|
||||
nodeEntry("_http_agent"),
|
||||
nodeEntry("_http_client"),
|
||||
nodeEntry("_http_common"),
|
||||
nodeEntry("_http_incoming"),
|
||||
nodeEntry("_http_outgoing"),
|
||||
nodeEntry("_http_server"),
|
||||
|
||||
// sys is a deprecated alias for util
|
||||
.{ "sys", .{ .path = "node:util", .node_builtin = true } },
|
||||
.{ "node:sys", .{ .path = "node:util", .node_builtin = true } },
|
||||
|
||||
// These are returned in builtinModules, but probably not many
|
||||
// packages use them so we will just alias them.
|
||||
.{ "node:_stream_duplex", .{ .path = "node:_stream_duplex", .node_builtin = true } },
|
||||
.{ "node:_stream_passthrough", .{ .path = "node:_stream_passthrough", .node_builtin = true } },
|
||||
.{ "node:_stream_readable", .{ .path = "node:_stream_readable", .node_builtin = true } },
|
||||
.{ "node:_stream_transform", .{ .path = "node:_stream_transform", .node_builtin = true } },
|
||||
.{ "node:_stream_wrap", .{ .path = "node:_stream_wrap", .node_builtin = true } },
|
||||
.{ "node:_stream_writable", .{ .path = "node:_stream_writable", .node_builtin = true } },
|
||||
.{ "node:_tls_wrap", .{ .path = "node:tls", .node_builtin = true } },
|
||||
.{ "node:_tls_common", .{ .path = "node:_tls_common", .node_builtin = true } },
|
||||
.{ "_stream_duplex", .{ .path = "node:_stream_duplex", .node_builtin = true } },
|
||||
.{ "_stream_passthrough", .{ .path = "node:_stream_passthrough", .node_builtin = true } },
|
||||
.{ "_stream_readable", .{ .path = "node:_stream_readable", .node_builtin = true } },
|
||||
.{ "_stream_transform", .{ .path = "node:_stream_transform", .node_builtin = true } },
|
||||
.{ "_stream_wrap", .{ .path = "node:_stream_wrap", .node_builtin = true } },
|
||||
.{ "_stream_writable", .{ .path = "node:_stream_writable", .node_builtin = true } },
|
||||
.{ "_tls_wrap", .{ .path = "node:tls", .node_builtin = true } },
|
||||
.{ "_tls_common", .{ .path = "node:_tls_common", .node_builtin = true } },
|
||||
};
|
||||
|
||||
const bun_extra_alias_kvs = [_]struct { string, Alias }{
|
||||
.{ "bun", .{ .path = "bun", .tag = .bun } },
|
||||
.{ "bun:test", .{ .path = "bun:test" } },
|
||||
.{ "bun:app", .{ .path = "bun:app" } },
|
||||
.{ "bun:ffi", .{ .path = "bun:ffi" } },
|
||||
.{ "bun:jsc", .{ .path = "bun:jsc" } },
|
||||
.{ "bun:sqlite", .{ .path = "bun:sqlite" } },
|
||||
.{ "bun:wrap", .{ .path = "bun:wrap" } },
|
||||
.{ "bun:internal-for-testing", .{ .path = "bun:internal-for-testing" } },
|
||||
.{ "ffi", .{ .path = "bun:ffi" } },
|
||||
|
||||
// inspector/promises is not implemented, it is an alias of inspector
|
||||
.{ "node:inspector/promises", .{ .path = "node:inspector", .node_builtin = true } },
|
||||
.{ "inspector/promises", .{ .path = "node:inspector", .node_builtin = true } },
|
||||
|
||||
// Thirdparty packages we override
|
||||
.{ "@vercel/fetch", .{ .path = "@vercel/fetch" } },
|
||||
.{ "isomorphic-fetch", .{ .path = "isomorphic-fetch" } },
|
||||
.{ "node-fetch", .{ .path = "node-fetch" } },
|
||||
.{ "undici", .{ .path = "undici" } },
|
||||
.{ "utf-8-validate", .{ .path = "utf-8-validate" } },
|
||||
.{ "ws", .{ .path = "ws" } },
|
||||
.{ "ws/lib/websocket", .{ .path = "ws" } },
|
||||
|
||||
// Polyfills we force to native
|
||||
.{ "abort-controller", .{ .path = "abort-controller" } },
|
||||
.{ "abort-controller/polyfill", .{ .path = "abort-controller" } },
|
||||
|
||||
// To force Next.js to not use bundled dependencies.
|
||||
.{ "next/dist/compiled/ws", .{ .path = "ws" } },
|
||||
.{ "next/dist/compiled/node-fetch", .{ .path = "node-fetch" } },
|
||||
.{ "next/dist/compiled/undici", .{ .path = "undici" } },
|
||||
};
|
||||
|
||||
const bun_test_extra_alias_kvs = [_]struct { string, Alias }{
|
||||
.{ "@jest/globals", .{ .path = "bun:test" } },
|
||||
.{ "vitest", .{ .path = "bun:test" } },
|
||||
};
|
||||
|
||||
const node_extra_alias_kvs = [_]struct { string, Alias }{
|
||||
nodeEntry("node:inspector/promises"),
|
||||
nodeEntry("inspector/promises"),
|
||||
};
|
||||
|
||||
const node_aliases = bun.ComptimeStringMap(Alias, common_alias_kvs ++ node_extra_alias_kvs);
|
||||
pub const bun_aliases = bun.ComptimeStringMap(Alias, common_alias_kvs ++ bun_extra_alias_kvs);
|
||||
const bun_test_aliases = bun.ComptimeStringMap(Alias, common_alias_kvs ++ bun_extra_alias_kvs ++ bun_test_extra_alias_kvs);
|
||||
|
||||
const Cfg = struct { rewrite_jest_for_tests: bool = false };
|
||||
pub fn has(name: []const u8, target: options.Target, cfg: Cfg) bool {
|
||||
return get(name, target, cfg) != null;
|
||||
}
|
||||
|
||||
pub fn get(name: []const u8, target: options.Target, cfg: Cfg) ?Alias {
|
||||
if (target.isBun()) {
|
||||
if (cfg.rewrite_jest_for_tests) {
|
||||
return bun_test_aliases.get(name);
|
||||
} else {
|
||||
return bun_aliases.get(name);
|
||||
}
|
||||
} else if (target.isNode()) {
|
||||
return node_aliases.get(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const bun = @import("bun");
|
||||
const options = @import("../options.zig");
|
||||
const std = @import("std");
|
||||
|
||||
const ast = @import("../import_record.zig");
|
||||
const ImportRecord = ast.ImportRecord;
|
||||
Reference in New Issue
Block a user