fix(build): debounce webpack watch mode to avoid mid-write reads (#78) - #82
Open
MonaAghili wants to merge 1 commit into
Open
fix(build): debounce webpack watch mode to avoid mid-write reads (#78)#82MonaAghili wants to merge 1 commit into
MonaAghili wants to merge 1 commit into
Conversation
Signed-off-by: Mona Aghili <mona.laghili@gmail.com>
MonaAghili
requested review from
a user,
j-base64 and
moodyjmz
and removed request for
a team
August 27, 2026 11:04
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
npm run watch:cell(andwatch:word/watch:slide/watch:visio) could intermittently produce a truncatedsdk-all.js(<1KB) with aModule parse failederror, immediately followed by a correct rebuild.watchOptions.aggregateTimeoutis 20ms (confirmed in the installedwebpack@5.108.4source). Editors can flush a single save as multipleMODIFY/rename events, especially over a WSL2/9p filesystem boundary. If a rebuild starts inside that 20ms window,sdk-concat.cjsre-reads the file mid-write and concatenates a truncated fragment into the ~400+ file bundle, producing a syntax error at the tail of the generated module.watchOptions.aggregateTimeoutto500inchunkConfig()inbuild/webpack.sdk.factory.mjs, shared by all four SDK targets (word/cell/slide/visio) and both chunk variants (min/all).watchOptionsis a documented no-op for one-shot builds, sonpm run build/ CI are unaffected.WATCH_AGGREGATE_TIMEOUTenv override for tuning on a given machine/CI watcher, consistent with this file's other env-tunable knobs. Invalid input (non-numeric/negative) warns and falls back to the default instead of throwing, so a stray/typo'd env var can never break a plain build.Why 500ms
25x webpack's default, comfortably absorbing a multi-event editor flush, while staying small relative to this pipeline's warm incremental rebuild time (~5-8s dev). It's a debounce on the rebuild trigger, not a read-time stability check —
sdk-concat.cjsstill does a plainreadFileonce the timeout fires, so this narrows the race window rather than eliminating it structurally. A write that's still landing after 500ms of silence (very slow disk, network mount) could theoretically still race; a full fix would require content-stability polling or retry-on-parse-failure in the loader, which is out of scope for this issue.Testing
npm test --prefix build: 45/45 passing, including new coverage for:aggregateTimeout(500) on both chunks, all targets share the one factoryWATCH_AGGREGATE_TIMEOUToverride, including0(explicitly honored, not treated as unset)sdkConfig()itself (not just the parsing helper)npm run watch:cell-equivalent, then rewrote a config-listed source file in two staggered chunks (5-10ms apart) to simulate a multi-event editor save. Before the fix this pattern reliably races; with it, exactly one rebuild fired and the resultingsdk-all-min.jswas full-size and passednode --check.cellmodule confirmed unaffected:sdk-all.jsemitted at expected size (~19.8 MiB minified).Not in scope
sdk-concat.cjs— discussed and deliberately deferred; see comment inwebpack.sdk.factory.mjs.inotifyevents not firing at all (a separate, unrelated failure modewatchOptions.pollwould address) — not what webpack watch mode intermittently reads sdkjs source mid-write, breaking the concatenated bundle and increasing build times #78 reports.Close #78