diff options
author | 2023-04-28 14:21:18 -0700 | |
---|---|---|
committer | 2023-04-28 14:21:18 -0700 | |
commit | 26d81fc5ba442d60ce2c5203196f4f0343b75f35 (patch) | |
tree | 0ac71554650aee819c5febf914bab8cf38750e30 /src/resolver | |
parent | 396416a91fed5166f3c4e9c340a3f2af5367bb78 (diff) | |
download | bun-26d81fc5ba442d60ce2c5203196f4f0343b75f35.tar.gz bun-26d81fc5ba442d60ce2c5203196f4f0343b75f35.tar.zst bun-26d81fc5ba442d60ce2c5203196f4f0343b75f35.zip |
[resolver] Propagate module type from package.json `"exports"` when possible
Diffstat (limited to '')
-rw-r--r-- | src/resolver/package_json.zig | 23 | ||||
-rw-r--r-- | src/resolver/resolver.zig | 15 |
2 files changed, 33 insertions, 5 deletions
diff --git a/src/resolver/package_json.zig b/src/resolver/package_json.zig index ce9695008..75b7a9e00 100644 --- a/src/resolver/package_json.zig +++ b/src/resolver/package_json.zig @@ -1247,6 +1247,7 @@ pub const ESModule = struct { debug_logs: ?*resolver.DebugLogs = null, conditions: ConditionsMap, allocator: std.mem.Allocator, + module_type: *options.ModuleType = undefined, pub const Resolution = struct { status: Status = Status.Undefined, @@ -1769,18 +1770,28 @@ pub const ESModule = struct { const slice = object.list.slice(); const keys = slice.items(.key); for (keys, 0..) |key, i| { - if (strings.eqlComptime(key, "default") or r.conditions.contains(key)) { + if (r.conditions.contains(key)) { if (r.debug_logs) |log| { log.addNoteFmt("The key \"{s}\" matched", .{key}); } + var prev_module_type = r.module_type.*; var result = r.resolveTarget(package_url, slice.items(.value)[i], subpath, internal, pattern); if (result.status.isUndefined()) { did_find_map_entry = true; last_map_entry_i = i; + r.module_type.* = prev_module_type; continue; } + if (strings.eqlComptime(key, "import")) { + r.module_type.* = .esm; + } + + if (strings.eqlComptime(key, "require")) { + r.module_type.* = .cjs; + } + return result; } @@ -1865,6 +1876,7 @@ pub const ESModule = struct { for (array) |targetValue| { // Let resolved be the result, continuing the loop on any Invalid Package Target error. + var prev_module_type = r.module_type.*; const result = r.resolveTarget(package_url, targetValue, subpath, internal, pattern); if (result.status == .InvalidPackageTarget or result.status == .Null) { last_debug = result.debug; @@ -1872,6 +1884,7 @@ pub const ESModule = struct { } if (result.status.isUndefined()) { + r.module_type.* = prev_module_type; continue; } @@ -2007,8 +2020,14 @@ pub const ESModule = struct { const slice = map.list.slice(); const keys = slice.items(.key); for (keys, 0..) |map_key, i| { - if (strings.eqlComptime(map_key, "default") or r.conditions.contains(map_key)) { + if (r.conditions.contains(map_key)) { if (r.resolveTargetReverse(query, key, slice.items(.value)[i], kind)) |result| { + if (strings.eqlComptime(map_key, "import")) { + r.module_type.* = .esm; + } else if (strings.eqlComptime(map_key, "require")) { + r.module_type.* = .cjs; + } + return result; } } diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index 380992436..61717ada9 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -354,6 +354,7 @@ pub const MatchResult = struct { package_json: ?*PackageJSON = null, diff_case: ?Fs.FileSystem.Entry.Lookup.DifferentCase = null, dir_info: ?*DirInfo = null, + module_type: options.ModuleType = .unknown, pub const Union = union(enum) { not_found: void, @@ -1157,6 +1158,7 @@ pub const Resolver = struct { .dirname_fd = _result.dirname_fd, .package_json = pkg, .jsx = r.opts.jsx, + .module_type = _result.module_type, }; check_relative = false; check_package = false; @@ -1307,6 +1309,7 @@ pub const Resolver = struct { result.diff_case = res.diff_case; result.is_from_node_modules = result.is_from_node_modules or res.is_node_module; result.jsx = r.opts.jsx; + result.module_type = res.module_type; if (res.path_pair.primary.is_disabled and res.path_pair.secondary == null) { return .{ .success = result }; @@ -1331,6 +1334,7 @@ pub const Resolver = struct { result.file_fd = remapped.file_fd; result.package_json = remapped.package_json; result.diff_case = remapped.diff_case; + result.module_type = remapped.module_type; result.is_from_node_modules = result.is_from_node_modules or remapped.is_node_module; return .{ .success = result }; @@ -1532,14 +1536,15 @@ pub const Resolver = struct { if (package_json.exports) |exports_map| { // The condition set is determined by the kind of import - - const esmodule = ESModule{ + var module_type = options.ModuleType.unknown; + var esmodule = ESModule{ .conditions = switch (kind) { ast.ImportKind.require, ast.ImportKind.require_resolve => r.opts.conditions.require, else => r.opts.conditions.import, }, .allocator = r.allocator, .debug_logs = if (r.debug_logs) |*debug| debug else null, + .module_type = &module_type, }; // Resolve against the path "/", then join it with the absolute @@ -1554,6 +1559,7 @@ pub const Resolver = struct { if (r.handleESMResolution(esm_resolution, abs_package_path, kind, package_json, esm.subpath)) |result| { var result_copy = result; result_copy.is_node_module = true; + result_copy.module_type = module_type; return .{ .success = result_copy }; } } @@ -1578,7 +1584,10 @@ pub const Resolver = struct { if (strings.eqlComptime(extname, ".js") and esm.subpath.len > 3) { const esm_resolution = esmodule.resolve("/", esm.subpath[0 .. esm.subpath.len - 3], exports_map.root); if (r.handleESMResolution(esm_resolution, abs_package_path, kind, package_json, esm.subpath)) |result| { - return .{ .success = result }; + var result_copy = result; + result_copy.is_node_module = true; + result_copy.module_type = module_type; + return .{ .success = result_copy }; } } |