mirror of
https://github.com/oven-sh/bun
synced 2026-02-09 10:28:47 +00:00
Fix(bundler): use different alias mappings based on the target. (#4163)
* Fix(bundler): use different alias mappings based on the target. Close: #3844 * chore: reduce duplicated code. * chore: split to two separate ComptimeStringMap.
This commit is contained in:
@@ -1592,7 +1592,7 @@ pub const VirtualMachine = struct {
|
||||
}
|
||||
}
|
||||
|
||||
if (JSC.HardcodedModule.Aliases.getWithEql(specifier, bun.String.eqlComptime)) |hardcoded| {
|
||||
if (JSC.HardcodedModule.Aliases.getWithEql(specifier, bun.String.eqlComptime, jsc_vm.bundler.options.target)) |hardcoded| {
|
||||
if (hardcoded.tag == .none) {
|
||||
resolveMaybeNeedsTrailingSlash(
|
||||
res,
|
||||
|
||||
@@ -484,7 +484,7 @@ pub const RuntimeTranspilerStore = struct {
|
||||
for (parse_result.ast.import_records.slice()) |*import_record_| {
|
||||
var import_record: *bun.ImportRecord = import_record_;
|
||||
|
||||
if (JSC.HardcodedModule.Aliases.get(import_record.path.text)) |replacement| {
|
||||
if (JSC.HardcodedModule.Aliases.get(import_record.path.text, bundler.options.target)) |replacement| {
|
||||
import_record.path.text = replacement.path;
|
||||
import_record.tag = replacement.tag;
|
||||
continue;
|
||||
@@ -2338,20 +2338,15 @@ pub const HardcodedModule = enum {
|
||||
.{ "utf-8-validate", HardcodedModule.@"utf-8-validate" },
|
||||
},
|
||||
);
|
||||
|
||||
pub const Alias = struct {
|
||||
path: string,
|
||||
tag: ImportRecord.Tag = ImportRecord.Tag.hardcoded,
|
||||
};
|
||||
pub const Aliases = bun.ComptimeStringMap(
|
||||
Alias,
|
||||
.{
|
||||
.{ "bun", .{ .path = "bun", .tag = .bun } },
|
||||
.{ "bun:ffi", .{ .path = "bun:ffi" } },
|
||||
.{ "bun:jsc", .{ .path = "bun:jsc" } },
|
||||
.{ "bun:sqlite", .{ .path = "bun:sqlite" } },
|
||||
.{ "bun:wrap", .{ .path = "bun:wrap" } },
|
||||
.{ "ffi", .{ .path = "bun:ffi" } },
|
||||
|
||||
pub const Aliases = struct {
|
||||
// Used by both Bun and Node.
|
||||
const common_alias_kvs = .{
|
||||
.{ "node:assert", .{ .path = "node:assert" } },
|
||||
.{ "node:assert/strict", .{ .path = "node:assert/strict" } },
|
||||
.{ "node:async_hooks", .{ .path = "node:async_hooks" } },
|
||||
@@ -2461,7 +2456,7 @@ pub const HardcodedModule = enum {
|
||||
// It implements the same interface
|
||||
.{ "sys", .{ .path = "node:util" } },
|
||||
.{ "node:sys", .{ .path = "node:util" } },
|
||||
.{ "inspector/promises", .{ .path = "node:inspector" } },
|
||||
// .{ "inspector/promises", .{ .path = "node:inspector" } },
|
||||
.{ "node:inspector/promises", .{ .path = "node:inspector" } },
|
||||
|
||||
// These are returned in builtinModules, but probably not many packages use them
|
||||
@@ -2486,6 +2481,15 @@ pub const HardcodedModule = enum {
|
||||
// .{ "readable-stream", .{ .path = "node:stream" } },
|
||||
// .{ "readable-stream/consumer", .{ .path = "node:stream/consumers" } },
|
||||
// .{ "readable-stream/web", .{ .path = "node:stream/web" } },
|
||||
};
|
||||
|
||||
const bun_extra_alias_kvs = .{
|
||||
.{ "bun", .{ .path = "bun", .tag = .bun } },
|
||||
.{ "bun:ffi", .{ .path = "bun:ffi" } },
|
||||
.{ "bun:jsc", .{ .path = "bun:jsc" } },
|
||||
.{ "bun:sqlite", .{ .path = "bun:sqlite" } },
|
||||
.{ "bun:wrap", .{ .path = "bun:wrap" } },
|
||||
.{ "ffi", .{ .path = "bun:ffi" } },
|
||||
|
||||
// Thirdparty packages we override
|
||||
.{ "@vercel/fetch", .{ .path = "@vercel/fetch" } },
|
||||
@@ -2497,6 +2501,36 @@ pub const HardcodedModule = enum {
|
||||
.{ "utf-8-validate", .{ .path = "utf-8-validate" } },
|
||||
.{ "ws", .{ .path = "ws" } },
|
||||
.{ "ws/lib/websocket", .{ .path = "ws" } },
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
const NodeAliases = bun.ComptimeStringMap(Alias, common_alias_kvs);
|
||||
const BunAliases = bun.ComptimeStringMap(Alias, common_alias_kvs ++ bun_extra_alias_kvs);
|
||||
|
||||
pub fn has(name: []const u8, target: options.Target) bool {
|
||||
if (target.isBun()) {
|
||||
return BunAliases.has(name);
|
||||
} else if (target.isNode()) {
|
||||
return NodeAliases.has(name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn get(name: []const u8, target: options.Target) ?Alias {
|
||||
if (target.isBun()) {
|
||||
return BunAliases.get(name);
|
||||
} else if (target.isNode()) {
|
||||
return NodeAliases.get(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
pub fn getWithEql(name: anytype, comptime eql: anytype, target: options.Target) ?Alias {
|
||||
if (target.isBun()) {
|
||||
return BunAliases.getWithEql(name, eql);
|
||||
} else if (target.isNode()) {
|
||||
return NodeAliases.getWithEql(name, eql);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1854,7 +1854,7 @@ pub const BundleV2 = struct {
|
||||
}
|
||||
|
||||
if (ast.target.isBun()) {
|
||||
if (JSC.HardcodedModule.Aliases.get(import_record.path.text)) |replacement| {
|
||||
if (JSC.HardcodedModule.Aliases.get(import_record.path.text, options.Target.bun)) |replacement| {
|
||||
import_record.path.text = replacement.path;
|
||||
import_record.tag = replacement.tag;
|
||||
import_record.source_index = Index.invalid;
|
||||
|
||||
@@ -247,7 +247,7 @@ pub const Linker = struct {
|
||||
}
|
||||
|
||||
if (comptime is_bun) {
|
||||
if (JSC.HardcodedModule.Aliases.get(import_record.path.text)) |replacement| {
|
||||
if (JSC.HardcodedModule.Aliases.get(import_record.path.text, linker.options.target)) |replacement| {
|
||||
import_record.path.text = replacement.path;
|
||||
import_record.tag = replacement.tag;
|
||||
if (replacement.tag != .none) {
|
||||
|
||||
@@ -467,6 +467,13 @@ pub const Target = enum {
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn isNode(this: Target) bool {
|
||||
return switch (this) {
|
||||
.node => true,
|
||||
else => false,
|
||||
};
|
||||
}
|
||||
|
||||
pub inline fn supportsBrowserField(this: Target) bool {
|
||||
return switch (this) {
|
||||
.browser => true,
|
||||
|
||||
@@ -588,7 +588,7 @@ pub const Resolver = struct {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bun.JSC.HardcodedModule.Aliases.has(import_path)) {
|
||||
if (bun.JSC.HardcodedModule.Aliases.has(import_path, r.opts.target)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1273,7 +1273,7 @@ pub const Resolver = struct {
|
||||
// "fs"
|
||||
// "fs/*"
|
||||
// These are disabled!
|
||||
} else if (had_node_prefix and !JSC.HardcodedModule.Aliases.has(import_path_without_node_prefix)) {
|
||||
} else if (had_node_prefix and !JSC.HardcodedModule.Aliases.has(import_path_without_node_prefix, r.opts.target)) {
|
||||
return .{ .not_found = {} };
|
||||
} else if (had_node_prefix or
|
||||
(strings.hasPrefixComptime(import_path_without_node_prefix, "fs") and
|
||||
|
||||
@@ -262,4 +262,32 @@ describe("Bun.build", () => {
|
||||
expect(x.logs[0].name).toBe("BuildMessage");
|
||||
expect(x.logs[0].position).toBeTruthy();
|
||||
});
|
||||
|
||||
test("test bun target", async () => {
|
||||
const x = await Bun.build({
|
||||
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
|
||||
target: "bun",
|
||||
});
|
||||
expect(x.success).toBe(true);
|
||||
const [blob] = x.outputs;
|
||||
const content = await blob.text();
|
||||
|
||||
// use bun's ws
|
||||
expect(content).toContain('import {WebSocket} from "ws"');
|
||||
expect(content).not.toContain("var websocket = __toESM(require_websocket(), 1);");
|
||||
});
|
||||
|
||||
test("test node target, issue #3844", async () => {
|
||||
const x = await Bun.build({
|
||||
entrypoints: [join(import.meta.dir, "./fixtures/trivial/bundle-ws.ts")],
|
||||
target: "node",
|
||||
});
|
||||
expect(x.success).toBe(true);
|
||||
const [blob] = x.outputs;
|
||||
const content = await blob.text();
|
||||
|
||||
expect(content).not.toContain('import {WebSocket} from "ws"');
|
||||
// depends on the ws package in the test/node_modules.
|
||||
expect(content).toContain("var websocket = __toESM(require_websocket(), 1);");
|
||||
});
|
||||
});
|
||||
|
||||
3
test/bundler/fixtures/trivial/bundle-ws.ts
Normal file
3
test/bundler/fixtures/trivial/bundle-ws.ts
Normal file
@@ -0,0 +1,3 @@
|
||||
import { WebSocket } from "ws";
|
||||
|
||||
console.log(WebSocket);
|
||||
Reference in New Issue
Block a user