aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-02-18 02:48:20 -0800
committerGravatar Jarred Sumner <jarred@jarredsumner.com> 2022-02-18 02:48:20 -0800
commit90f1f326ca758bb45869d56ad50e97fa753074a5 (patch)
tree870cb5195e898d21a59e7b34cb0892a262b61acd
parent8383544bb57ba2cc804c047632e7013f07ff3cd3 (diff)
downloadbun-90f1f326ca758bb45869d56ad50e97fa753074a5.tar.gz
bun-90f1f326ca758bb45869d56ad50e97fa753074a5.tar.zst
bun-90f1f326ca758bb45869d56ad50e97fa753074a5.zip
[bun dev] Fix bug with importing `node:` namespace
-rw-r--r--src/linker.zig38
-rw-r--r--src/node_module_bundle.zig58
2 files changed, 94 insertions, 2 deletions
diff --git a/src/linker.zig b/src/linker.zig
index 278d57927..8ac15ddd7 100644
--- a/src/linker.zig
+++ b/src/linker.zig
@@ -287,6 +287,40 @@ pub const Linker = struct {
}
}
+ if (linker.options.node_modules_bundle) |node_modules_bundle| {
+ if (Resolver.isPackagePath(import_record.path.text)) {
+ const text = import_record.path.text;
+
+ var package_name = text;
+ if (text[0] == '@') {
+ if (std.mem.indexOfScalar(u8, text, '/')) |i| {
+ if (std.mem.indexOfScalar(u8, text[i + 1 ..], '/')) |j| {
+ package_name = text[0 .. i + 1 + j];
+ }
+ }
+ } else {
+ if (std.mem.indexOfScalar(u8, text, '/')) |i| {
+ package_name = text[0..i];
+ }
+ }
+ if (package_name.len != text.len) {
+ if (node_modules_bundle.getPackage(package_name)) |pkg| {
+ const import_path = text[@minimum(text.len, package_name.len + 1)..];
+ if (node_modules_bundle.findModuleIDInPackageIgnoringExtension(pkg, import_path)) |found_module| {
+ import_record.is_bundled = true;
+ node_module_bundle_import_path = node_module_bundle_import_path orelse
+ linker.nodeModuleBundleImportPath(origin);
+
+ import_record.path.text = node_module_bundle_import_path.?;
+ import_record.module_id = node_modules_bundle.bundle.modules[found_module].id;
+ needs_bundle = true;
+ continue :outer;
+ }
+ }
+ }
+ }
+ }
+
var resolved_import_ = brk: {
switch (import_record.tag) {
else => {},
@@ -632,8 +666,8 @@ pub const Linker = struct {
// assumption: already starts with "node:"
"{s}/{s}",
.{
- origin,
- source_path,
+ strings.withoutTrailingSlash(origin.href),
+ strings.withoutLeadingSlash(source_path),
},
));
} else {
diff --git a/src/node_module_bundle.zig b/src/node_module_bundle.zig
index 36de005b5..4181dd988 100644
--- a/src/node_module_bundle.zig
+++ b/src/node_module_bundle.zig
@@ -264,6 +264,64 @@ pub const NodeModuleBundle = struct {
) orelse return null) + package.modules_offset;
}
+ pub fn findModuleIDInPackageIgnoringExtension(
+ this: *const NodeModuleBundle,
+ package: *const Api.JavascriptBundledPackage,
+ _query: string,
+ ) ?u32 {
+ const ModuleFinder = struct {
+ const Self = @This();
+ ctx: *const NodeModuleBundle,
+ pkg: *const Api.JavascriptBundledPackage,
+ query: string,
+
+ // Since the module doesn't necessarily exist, we use an integer overflow as the module name
+ pub fn moduleName(context: *const Self, module: *const Api.JavascriptBundledModule) string {
+ return if (module.path.offset == context.ctx.bundle.manifest_string.len) context.query else context.ctx.str(.{
+ .offset = module.path.offset,
+ .length = module.path.length - @as(u32, module.path_extname_length),
+ });
+ }
+
+ pub fn cmpAsc(context: Self, lhs: Api.JavascriptBundledModule, rhs: Api.JavascriptBundledModule) std.math.Order {
+ // Comapre the module name
+ const lhs_name = context.moduleName(&lhs);
+ const rhs_name = context.moduleName(&rhs);
+
+ const traversal_length = std.math.min(lhs_name.len, rhs_name.len);
+
+ for (lhs_name[0..traversal_length]) |char, i| {
+ switch (std.math.order(char, rhs_name[i])) {
+ .lt, .gt => |order| {
+ return order;
+ },
+ .eq => {},
+ }
+ }
+
+ return std.math.order(lhs_name.len, rhs_name.len);
+ }
+ };
+ var to_find = Api.JavascriptBundledModule{
+ .package_id = 0,
+ .code = .{},
+ .path = .{
+ .offset = @truncate(u32, this.bundle.manifest_string.len),
+ },
+ };
+
+ var finder = ModuleFinder{ .ctx = this, .pkg = package, .query = _query[0 .. _query.len - std.fs.path.extension(_query).len] };
+
+ const modules = modulesIn(&this.bundle, package);
+ return @intCast(u32, std.sort.binarySearch(
+ Api.JavascriptBundledModule,
+ to_find,
+ modules,
+ finder,
+ ModuleFinder.cmpAsc,
+ ) orelse return null) + package.modules_offset;
+ }
+
pub fn init(container: Api.JavascriptBundleContainer, allocator: std.mem.Allocator) NodeModuleBundle {
return NodeModuleBundle{
.container = container,