fix(FR-2157): prevent double rebuild on config.toml change#5749
Merged
graphite-app[bot] merged 1 commit intomainfrom Mar 10, 2026
Merged
fix(FR-2157): prevent double rebuild on config.toml change#5749graphite-app[bot] merged 1 commit intomainfrom
graphite-app[bot] merged 1 commit intomainfrom
Conversation
Contributor
Author
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has required the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
99024cd to
872f52c
Compare
Contributor
There was a problem hiding this comment.
Pull request overview
Adjusts the React dev-server / webpack watcher configuration to stop config.toml edits from triggering redundant rebuild + reload cycles during development, especially with editors that use atomic-save semantics.
Changes:
- Consolidates dev-server reload signaling behind a shared debounce to coalesce rapid watcher events.
- Switches per-file watching from
fs.watchtofs.watchFile(polling) to survive atomic-save inode replacement. - Replaces
watchOptions.ignoredstring-array configuration with a single RegExp intended to ignore project-root files (and temp files) to prevent webpack rebuilds.
872f52c to
80b6a20
Compare
Merge activity
|
Resolves #5621 ([FR-2157](https://lablup.atlassian.net/browse/FR-2157)) ## Summary When `config.toml` is modified during development, the browser was reloading **twice** instead of once. This was caused by two independent mechanisms both triggering reloads: 1. **webpack context dependency**: When webpack resolves aliases outside `react/` (e.g. `backend.ai-client-esm` → `../dist/lib/...`), `enhanced-resolve` walks up the directory tree and adds the project root as a context dependency. This causes webpack to detect `config.toml` changes → recompile → HMR finds no module updates → falls back to full page reload. 2. **`fs.watch` dying on atomic save**: IDEs like VS Code use atomic save (write temp → rename), which replaces the file's inode. `fs.watch` watches the old inode and stops detecting changes, leaving only the webpack-triggered reload (which itself fires twice due to temp file + rename events). ### Changes - **`watchOptions.ignored`: string array → RegExp** — Ignore all files directly in the project root (`[^/]+$` pattern) to catch both config files AND editor temp files. `dist/` and `packages/` subdirectories remain watched for HMR. - **`fs.watch` → `fs.watchFile` for individual files** — Polling-based watching (500ms interval) survives file replacements from atomic save. Directories (`resources/i18n`) still use `fs.watch`. - **Shared debounce timer (300ms)** — All watchers share a single timer to coalesce rapid events into one reload signal. ## Verification `scripts/verify.sh`: ALL PASS (Relay, Lint, Format, TypeScript) Tested with Chrome DevTools monitoring: - Server sends exactly 1 `static-changed` WebSocket message per config.toml edit - webpack does NOT recompile (no "Compiling..." in terminal) - Browser reloads exactly once ## Test plan - [x] Run dev server and modify `config.toml` from IDE — verify only ONE reload occurs - [ ] Verify HMR still works for React source changes - [ ] Verify `dist/lib/backend.ai-client-esm.js` changes still trigger HMR - [ ] Verify `index.html` changes still trigger a page reload - [ ] Verify i18n translation file changes still trigger a page reload - [ ] Verify `resources/theme.json` changes still trigger a page reload - [ ] Production build (`pnpm run build`) completes successfully 🤖 Generated with [Claude Code](https://claude.com/claude-code) [FR-2157]: https://lablup.atlassian.net/browse/FR-2157?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
80b6a20 to
6927758
Compare
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.

Resolves #5621 (FR-2157)
Summary
When
config.tomlis modified during development, the browser was reloading twice instead of once. This was caused by two independent mechanisms both triggering reloads:webpack context dependency: When webpack resolves aliases outside
react/(e.g.backend.ai-client-esm→../dist/lib/...),enhanced-resolvewalks up the directory tree and adds the project root as a context dependency. This causes webpack to detectconfig.tomlchanges → recompile → HMR finds no module updates → falls back to full page reload.fs.watchdying on atomic save: IDEs like VS Code use atomic save (write temp → rename), which replaces the file's inode.fs.watchwatches the old inode and stops detecting changes, leaving only the webpack-triggered reload (which itself fires twice due to temp file + rename events).Changes
watchOptions.ignored: string array → RegExp — Ignore all files directly in the project root ([^/]+$pattern) to catch both config files AND editor temp files.dist/andpackages/subdirectories remain watched for HMR.fs.watch→fs.watchFilefor individual files — Polling-based watching (500ms interval) survives file replacements from atomic save. Directories (resources/i18n) still usefs.watch.Verification
scripts/verify.sh: ALL PASS (Relay, Lint, Format, TypeScript)Tested with Chrome DevTools monitoring:
static-changedWebSocket message per config.toml editTest plan
config.tomlfrom IDE — verify only ONE reload occursdist/lib/backend.ai-client-esm.jschanges still trigger HMRindex.htmlchanges still trigger a page reloadresources/theme.jsonchanges still trigger a page reloadpnpm run build) completes successfully🤖 Generated with Claude Code