diff options
author | 2022-04-13 21:44:01 -0700 | |
---|---|---|
committer | 2022-04-13 21:46:02 -0700 | |
commit | 1788503892d27027b584542c2966daac06308c93 (patch) | |
tree | faa2dd545957bb40ca39d9ae96959d6c34ff7fe5 | |
parent | 95aa76b9fae3747a72c2db460d42c38b7faaee2a (diff) | |
download | bun-1788503892d27027b584542c2966daac06308c93.tar.gz bun-1788503892d27027b584542c2966daac06308c93.tar.zst bun-1788503892d27027b584542c2966daac06308c93.zip |
[bun dev] Fix CSS HMR bug
-rw-r--r-- | src/bundler.zig | 79 | ||||
-rw-r--r-- | src/css_scanner.zig | 30 | ||||
-rw-r--r-- | src/runtime/hmr.ts | 29 |
3 files changed, 67 insertions, 71 deletions
diff --git a/src/bundler.zig b/src/bundler.zig index 486d38595..307ab3c97 100644 --- a/src/bundler.zig +++ b/src/bundler.zig @@ -2374,38 +2374,40 @@ pub const Bundler = struct { import_path_format, ); + const written = brk: { + if (bundler.options.hot_module_reloading) { + break :brk (try CSSBundlerHMR.bundle( + file_path.text, + bundler.fs, + writer, + watcher, + &bundler.resolver.caches.fs, + filepath_hash, + file_descriptor, + allocator, + bundler.log, + &bundler.linker, + origin, + )).written; + } else { + break :brk (try CSSBundler.bundle( + file_path.text, + bundler.fs, + writer, + watcher, + &bundler.resolver.caches.fs, + filepath_hash, + file_descriptor, + allocator, + bundler.log, + &bundler.linker, + origin, + )).written; + } + }; + return BuildResolveResultPair{ - .written = brk: { - if (bundler.options.hot_module_reloading) { - break :brk (try CSSBundlerHMR.bundle( - file_path.text, - bundler.fs, - writer, - watcher, - &bundler.resolver.caches.fs, - filepath_hash, - file_descriptor, - allocator, - bundler.log, - &bundler.linker, - origin, - )).written; - } else { - break :brk (try CSSBundler.bundle( - file_path.text, - bundler.fs, - writer, - watcher, - &bundler.resolver.caches.fs, - filepath_hash, - file_descriptor, - allocator, - bundler.log, - &bundler.linker, - origin, - )).written; - } - }, + .written = written, .input_fd = file_descriptor, }; }, @@ -2603,12 +2605,18 @@ pub const Bundler = struct { origin: URL, }; var build_ctx = CSSBuildContext{ .origin = bundler.options.origin }; + + const BufferedWriter = std.io.CountingWriter(std.io.BufferedWriter(8096, std.fs.File.Writer)); const CSSWriter = Css.NewWriter( - std.fs.File, + BufferedWriter.Writer, @TypeOf(&bundler.linker), import_path_format, CSSBuildContext, ); + var buffered_writer = BufferedWriter{ + .child_stream = .{ .unbuffered_writer = file.writer() }, + .bytes_written = 0, + }; const entry = bundler.resolver.caches.fs.readFile( bundler.fs, file_path.text, @@ -2620,16 +2628,19 @@ pub const Bundler = struct { const _file = Fs.File{ .path = file_path, .contents = entry.contents }; var source = try logger.Source.initFile(_file, bundler.allocator); source.contents_is_recycled = !cache_files; + var css_writer = CSSWriter.init( &source, - file, + buffered_writer.writer(), &bundler.linker, bundler.log, ); + css_writer.buildCtx = build_ctx; try css_writer.run(bundler.log, bundler.allocator); - output_file.size = css_writer.written; + try css_writer.ctx.context.child_stream.flush(); + output_file.size = css_writer.ctx.context.bytes_written; var file_op = options.OutputFile.FileOperation.fromFile(file.handle, file_path.pretty); file_op.fd = file.handle; diff --git a/src/css_scanner.zig b/src/css_scanner.zig index 8d89a9cfd..19b1dcaa8 100644 --- a/src/css_scanner.zig +++ b/src/css_scanner.zig @@ -874,7 +874,6 @@ pub fn NewWriter( ctx: WriterType, linker: LinkerType, source: *const logger.Source, - written: usize = 0, buildCtx: BuildContextType = undefined, log: *logger.Log, @@ -888,7 +887,6 @@ pub fn NewWriter( .ctx = ctx, .linker = linker, .source = source, - .written = 0, .log = log, }; } @@ -944,24 +942,22 @@ pub fn NewWriter( switch (quote) { .none => { try writer.ctx.writeAll(str); - writer.written += str.len; + return; }, .single => { try writer.ctx.writeAll("'"); - writer.written += 1; + try writer.ctx.writeAll(str); - writer.written += str.len; + try writer.ctx.writeAll("'"); - writer.written += 1; }, .double => { try writer.ctx.writeAll("\""); - writer.written += 1; + try writer.ctx.writeAll(str); - writer.written += str.len; + try writer.ctx.writeAll("\""); - writer.written += 1; }, } } @@ -970,31 +966,25 @@ pub fn NewWriter( switch (text.quote) { .none => { try writer.ctx.writeAll("url("); - writer.written += "url(".len; }, .single => { try writer.ctx.writeAll("url('"); - writer.written += "url('".len; }, .double => { try writer.ctx.writeAll("url(\""); - writer.written += "url(\"".len; }, } try writer.ctx.writeAll(url_str); - writer.written += url_str.len; + switch (text.quote) { .none => { try writer.ctx.writeAll(")"); - writer.written += ")".len; }, .single => { try writer.ctx.writeAll("')"); - writer.written += "')".len; }, .double => { try writer.ctx.writeAll("\")"); - writer.written += "\")".len; }, } } @@ -1074,7 +1064,6 @@ pub fn NewWriter( ); try writer.ctx.writeAll("@import "); - writer.written += "@import ".len; if (import.url) { try writer.writeURL(url_str, import.text); @@ -1083,14 +1072,10 @@ pub fn NewWriter( } try writer.ctx.writeAll(import.suffix); - writer.written += import.suffix.len; try writer.ctx.writeAll("\n"); - - writer.written += 1; } }, .t_verbatim => { - defer writer.written += @intCast(usize, chunk.range.len); if (comptime std.meta.trait.hasFn("copyFileRange")(WriterType)) { try writer.ctx.copyFileRange( @intCast(usize, chunk.range.loc.start), @@ -1162,6 +1147,7 @@ pub fn NewBundler( linker: Linker, origin: URL, ) !CodeCount { + const start_count = writer.written; if (!has_set_global_queue) { global_queued = QueuedList.init(default_allocator); global_import_queud = ImportQueueFifo.init(default_allocator); @@ -1247,7 +1233,7 @@ pub fn NewBundler( try this.writer.done(); return CodeCount{ - .written = css.written, + .written = @intCast(usize, @maximum(this.writer.written - start_count, 0)), .approximate_newline_count = lines_of_code, }; } diff --git a/src/runtime/hmr.ts b/src/runtime/hmr.ts index afffc4847..4e62afa0f 100644 --- a/src/runtime/hmr.ts +++ b/src/runtime/hmr.ts @@ -7,6 +7,7 @@ if (typeof window !== "undefined") { // We add a scope here to minimize chances of namespace collisions var runOnce = false; var clientStartTime = 0; + var empty: Uint8Array; function formatDuration(duration: number) { return Math.round(duration * 1000) / 1000; @@ -355,21 +356,15 @@ if (typeof window !== "undefined") { } handleBuildSuccess( - buffer: ByteBuffer, + bytes: Uint8Array, build: API.WebsocketMessageBuildSuccess, timestamp: number ) { - debugger; const start = performance.now(); var update = this.findCSSLinkTag(build.id); // The last 4 bytes of the build message are the hash of the module // Currently, this hash is only used for ensuring we reload the source-map - let bytes = new Uint8Array(buffer.data.buffer, buffer.index); - if (bytes.length > 4) { - bytes = bytes.subarray(0, bytes.length - 4); - } - if (update === null) { __hmrlog.debug("Skipping unused CSS."); return; @@ -446,7 +441,6 @@ if (typeof window !== "undefined") { } } - buffer = null; bytes = null; } @@ -834,6 +828,15 @@ if (typeof window !== "undefined") { } return; } + var bytes = + buffer.data.byteOffset + buffer.index + build.blob_length <= + buffer.data.buffer.byteLength + ? new Uint8Array( + buffer.data.buffer, + buffer.data.byteOffset + buffer.index, + build.blob_length + ) + : (empty ||= new Uint8Array(0)); if (build.loader === API.Loader.css) { BunError.clear(); @@ -841,7 +844,7 @@ if (typeof window !== "undefined") { console.clear(); this.needsConsoleClear = false; } - return this.loaders.css.handleBuildSuccess(buffer, build, timestamp); + return this.loaders.css.handleBuildSuccess(bytes, build, timestamp); } const id = build.id; @@ -879,20 +882,16 @@ if (typeof window !== "undefined") { } // These are the bytes!! - const fileBytes = - buffer.data.length > buffer.index - ? buffer.data.subarray(buffer.index, end) - : new Uint8Array(0); var reload = new HotReload( build.id, index, build, - fileBytes, + bytes, ReloadBehavior.hotReload, hash || 0 ); - + bytes = null; reload.timings.notify = timestamp - build.from_timestamp; BunError.clear(); |