From c6e880adf148e5d00eddc655038bf9e53b20015c Mon Sep 17 00:00:00 2001 From: Evan Wallace Date: Wed, 9 Nov 2022 09:44:20 -0500 Subject: [PATCH] fix #2661: avoid extra rebuilds with debug logging --- CHANGELOG.md | 8 ++++++++ internal/fs/fs.go | 11 +++++++++++ internal/resolver/resolver.go | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9531171630b..72a416a045c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## Unreleased + +* Avoid unnecessary watch mode rebuilds when debug logging is enabled ([#2661](https://github.com/evanw/esbuild/issues/2661)) + + When debug-level logs are enabled (such as with `--log-level=debug`), esbuild's path resolution subsystem generates debug log messages that say something like "Read 20 entries for directory /home/user" to help you debug what esbuild's path resolution is doing. This caused esbuild's watch mode subsystem to add a dependency on the full list of entries in that directory since if that changes, the generated log message would also have to be updated. However, meant that on systems where a parent directory undergoes constant directory entry churn, esbuild's watch mode would continue to rebuild if `--log-level=debug` was passed. + + With this release, these debug log messages are now generated by "peeking" at the file system state while bypassing esbuild's watch mode dependency tracking. So now watch mode doesn't consider the count of directory entries in these debug log messages to be a part of the build that needs to be kept up to date when the file system state changes. + ## 0.15.13 * Add support for the TypeScript 4.9 `satisfies` operator ([#2509](https://github.com/evanw/esbuild/pull/2509)) diff --git a/internal/fs/fs.go b/internal/fs/fs.go index 353df7650e6..dcba844234f 100644 --- a/internal/fs/fs.go +++ b/internal/fs/fs.go @@ -112,6 +112,17 @@ func (entries DirEntries) Get(query string) (*Entry, *DifferentCase) { return nil, nil } +// This function lets you "peek" at the number of entries without watch mode +// considering the number of entries as having been observed. This is used when +// generating debug log messages to log the number of entries without causing +// watch mode to rebuild when the number of entries has been changed. +func (entries DirEntries) PeekEntryCount() int { + if entries.data != nil { + return len(entries.data) + } + return 0 +} + func (entries DirEntries) SortedKeys() (keys []string) { if entries.data != nil { keys = make([]string, 0, len(entries.data)) diff --git a/internal/resolver/resolver.go b/internal/resolver/resolver.go index ae7b879d5d3..eb05f7d0a6f 100644 --- a/internal/resolver/resolver.go +++ b/internal/resolver/resolver.go @@ -915,7 +915,7 @@ func (r resolverQuery) dirInfoCached(path string) *dirInfo { if cached == nil { r.debugLogs.addNote(fmt.Sprintf("Failed to read directory %q", path)) } else { - count := len(cached.entries.SortedKeys()) + count := cached.entries.PeekEntryCount() entries := "entries" if count == 1 { entries = "entry"