diff options
author | 2023-07-04 12:09:58 +0300 | |
---|---|---|
committer | 2023-07-04 02:09:58 -0700 | |
commit | 3d0ffc48cb2608ed696581e10cb082c68b56c6b9 (patch) | |
tree | 72bb50ad2491b4b7f1b0e0ee5de172cd59fbba1f /src | |
parent | bc7b5165beba1388a39215ccfa8e848e4982f1ed (diff) | |
download | bun-3d0ffc48cb2608ed696581e10cb082c68b56c6b9.tar.gz bun-3d0ffc48cb2608ed696581e10cb082c68b56c6b9.tar.zst bun-3d0ffc48cb2608ed696581e10cb082c68b56c6b9.zip |
[install] fix run-time module loading (#3510)
- fix version buffer confusion
- improve workaround to handle cached modules
fixes #3507
Diffstat (limited to 'src')
-rw-r--r-- | src/install/install.zig | 84 | ||||
-rw-r--r-- | src/js/out/modules/node/http.js | 2 | ||||
-rw-r--r-- | src/resolver/resolver.zig | 46 |
3 files changed, 62 insertions, 70 deletions
diff --git a/src/install/install.zig b/src/install/install.zig index 87f931291..f6133afce 100644 --- a/src/install/install.zig +++ b/src/install/install.zig @@ -1742,55 +1742,51 @@ pub const PackageManager = struct { pub fn enqueueDependencyToRoot( this: *PackageManager, name: []const u8, - version_buf: []const u8, version: *const Dependency.Version, + version_buf: []const u8, behavior: Dependency.Behavior, ) DependencyToEnqueue { - const str_buf = this.lockfile.buffers.string_bytes.items; - for (this.lockfile.buffers.dependencies.items, 0..) |dependency, dependency_id| { - if (!strings.eqlLong(dependency.name.slice(str_buf), name, true)) continue; - if (!dependency.version.eql(version, str_buf, version_buf)) continue; - return switch (this.lockfile.buffers.resolutions.items[dependency_id]) { - invalid_package_id => .{ - .pending = @truncate(DependencyID, dependency_id), - }, - else => |resolution_id| .{ - .resolution = .{ - .resolution = this.lockfile.packages.items(.resolution)[resolution_id], - .package_id = resolution_id, - }, - }, + const dep_id = @truncate(DependencyID, brk: { + const str_buf = this.lockfile.buffers.string_bytes.items; + for (this.lockfile.buffers.dependencies.items, 0..) |dep, id| { + if (!strings.eqlLong(dep.name.slice(str_buf), name, true)) continue; + if (!dep.version.eql(version, str_buf, version_buf)) continue; + break :brk id; + } + + var builder = this.lockfile.stringBuilder(); + const dummy = Dependency{ + .name = String.init(name, name), + .name_hash = String.Builder.stringHash(name), + .version = version.*, + .behavior = behavior, }; - } + dummy.countWithDifferentBuffers(name, version_buf, @TypeOf(&builder), &builder); - var builder = this.lockfile.stringBuilder(); - const dependency = Dependency{ - .name = String.init(name, name), - .name_hash = String.Builder.stringHash(name), - .version = version.*, - .behavior = behavior, - }; - dependency.countWithDifferentBuffers(name, version_buf, @TypeOf(&builder), &builder); - - builder.allocate() catch |err| return .{ .failure = err }; - - const cloned_dependency = dependency.cloneWithDifferentBuffers(name, version_buf, @TypeOf(&builder), &builder) catch unreachable; - builder.clamp(); - const index = @truncate(DependencyID, this.lockfile.buffers.dependencies.items.len); - this.lockfile.buffers.dependencies.append(this.allocator, cloned_dependency) catch unreachable; - this.lockfile.buffers.resolutions.append(this.allocator, invalid_package_id) catch unreachable; - if (comptime Environment.allow_assert) std.debug.assert(this.lockfile.buffers.dependencies.items.len == this.lockfile.buffers.resolutions.items.len); - this.enqueueDependencyWithMainAndSuccessFn( - index, - &cloned_dependency, - invalid_package_id, - assignRootResolution, - failRootResolution, - ) catch |err| { - return .{ .failure = err }; - }; + builder.allocate() catch |err| return .{ .failure = err }; + + const dep = dummy.cloneWithDifferentBuffers(name, version_buf, @TypeOf(&builder), &builder) catch unreachable; + builder.clamp(); + const index = this.lockfile.buffers.dependencies.items.len; + this.lockfile.buffers.dependencies.append(this.allocator, dep) catch unreachable; + this.lockfile.buffers.resolutions.append(this.allocator, invalid_package_id) catch unreachable; + if (comptime Environment.allow_assert) std.debug.assert(this.lockfile.buffers.dependencies.items.len == this.lockfile.buffers.resolutions.items.len); + break :brk index; + }); + + if (this.lockfile.buffers.resolutions.items[dep_id] == invalid_package_id) { + this.enqueueDependencyWithMainAndSuccessFn( + dep_id, + &this.lockfile.buffers.dependencies.items[dep_id], + invalid_package_id, + assignRootResolution, + failRootResolution, + ) catch |err| { + return .{ .failure = err }; + }; + } - const resolution_id = switch (this.lockfile.buffers.resolutions.items[index]) { + const resolution_id = switch (this.lockfile.buffers.resolutions.items[dep_id]) { invalid_package_id => brk: { this.drainDependencyList(); @@ -1815,7 +1811,7 @@ pub const PackageManager = struct { }, } - break :brk this.lockfile.buffers.resolutions.items[index]; + break :brk this.lockfile.buffers.resolutions.items[dep_id]; }, // we managed to synchronously resolve the dependency else => |pkg_id| pkg_id, diff --git a/src/js/out/modules/node/http.js b/src/js/out/modules/node/http.js index 955c83642..f07dcc2e0 100644 --- a/src/js/out/modules/node/http.js +++ b/src/js/out/modules/node/http.js @@ -1085,6 +1085,8 @@ var tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/, METHODS = [ debug(`${NODE_HTTP_WARNING}\n`, "setMaxIdleHTTPParsers() is a no-op"); }, globalAgent, + ClientRequest, + OutgoingMessage, [Symbol.for("CommonJS")]: 0 }, http_default = defaultObject; export { diff --git a/src/resolver/resolver.zig b/src/resolver/resolver.zig index e1e83ba4f..409df85af 100644 --- a/src/resolver/resolver.zig +++ b/src/resolver/resolver.zig @@ -1256,14 +1256,8 @@ pub const Resolver = struct { if (check_package) { if (r.opts.polyfill_node_globals) { - var import_path_without_node_prefix = import_path; - const had_node_prefix = import_path_without_node_prefix.len > "node:".len and - strings.eqlComptime(import_path_without_node_prefix[0.."node:".len], "node:"); - - import_path_without_node_prefix = if (had_node_prefix) - import_path_without_node_prefix["node:".len..] - else - import_path_without_node_prefix; + const had_node_prefix = strings.hasPrefixComptime(import_path, "node:"); + const import_path_without_node_prefix = if (had_node_prefix) import_path["node:".len..] else import_path; if (NodeFallbackModules.Map.get(import_path_without_node_prefix)) |*fallback_module| { result.path_pair.primary = fallback_module.path; @@ -1278,7 +1272,7 @@ pub const Resolver = struct { } else if (had_node_prefix or (strings.hasPrefixComptime(import_path_without_node_prefix, "fs") and (import_path_without_node_prefix.len == 2 or - import_path_without_node_prefix[3] == '/'))) + import_path_without_node_prefix[2] == '/'))) { result.path_pair.primary.namespace = "node"; result.path_pair.primary.text = import_path_without_node_prefix; @@ -1698,8 +1692,9 @@ pub const Resolver = struct { // If the source directory doesn't have a node_modules directory, we can // check the global cache directory for a package.json file. var manager = r.getPackageManager(); - var dependency_version: Dependency.Version = .{}; + var dependency_version = Dependency.Version{}; var dependency_behavior = @enumFromInt(Dependency.Behavior, Dependency.Behavior.normal); + var string_buf = esm.version; // const initial_pending_tasks = manager.pending_tasks; var resolved_package_id: Install.PackageID = brk: { @@ -1707,7 +1702,6 @@ pub const Resolver = struct { // and try to look up the dependency from there if (dir_info.package_json_for_dependencies) |package_json| { var dependencies_list: []const Dependency = &[_]Dependency{}; - var string_buf: []const u8 = ""; const resolve_from_lockfile = package_json.package_manager_package_id != Install.invalid_package_id; if (resolve_from_lockfile) { @@ -1723,24 +1717,21 @@ pub const Resolver = struct { } for (dependencies_list, 0..) |dependency, dependency_id| { - const dep_name = dependency.name.slice(string_buf); - if (dep_name.len == esm.name.len) { - if (!strings.eqlLong(dep_name, esm.name, false)) { - continue; - } + if (!strings.eqlLong(dependency.name.slice(string_buf), esm.name, true)) { + continue; + } - dependency_version = dependency.version; - dependency_behavior = dependency.behavior; + dependency_version = dependency.version; + dependency_behavior = dependency.behavior; - if (resolve_from_lockfile) { - const resolutions = &manager.lockfile.packages.items(.resolutions)[package_json.package_manager_package_id]; + if (resolve_from_lockfile) { + const resolutions = &manager.lockfile.packages.items(.resolutions)[package_json.package_manager_package_id]; - // found it! - break :brk resolutions.get(manager.lockfile.buffers.resolutions.items)[dependency_id]; - } - - break; + // found it! + break :brk resolutions.get(manager.lockfile.buffers.resolutions.items)[dependency_id]; } + + break; } } @@ -1770,6 +1761,7 @@ pub const Resolver = struct { if (esm_.?.version.len > 0 and dir_info.enclosing_package_json != null and global_cache.allowVersionSpecifier()) { return .{ .failure = error.VersionSpecifierNotAllowedHere }; } + string_buf = esm.version; dependency_version = Dependency.parse( r.allocator, Semver.String.init(esm.name, esm.name), @@ -1795,6 +1787,7 @@ pub const Resolver = struct { dependency_behavior, &resolved_package_id, dependency_version, + string_buf, )) { .resolution => |res| break :brk res, .pending => |pending| return .{ .pending = pending }, @@ -2073,6 +2066,7 @@ pub const Resolver = struct { behavior: Dependency.Behavior, input_package_id_: *Install.PackageID, version: Dependency.Version, + version_buf: []const u8, ) DependencyToResolve { if (r.debug_logs) |*debug| { debug.addNoteFmt("Enqueueing pending dependency \"{s}@{s}\"", .{ esm.name, esm.version }); @@ -2135,7 +2129,7 @@ pub const Resolver = struct { // All packages are enqueued to the root // because we download all the npm package dependencies - switch (pm.enqueueDependencyToRoot(esm.name, esm.version, &version, behavior)) { + switch (pm.enqueueDependencyToRoot(esm.name, &version, version_buf, behavior)) { .resolution => |result| { input_package_id_.* = result.package_id; return .{ .resolution = result.resolution }; |