fix(build): watch publicDir files in build watch mode - #23245
Open
ValentinYoushkevich wants to merge 1 commit into
Open
fix(build): watch publicDir files in build watch mode#23245ValentinYoushkevich wants to merge 1 commit into
ValentinYoushkevich wants to merge 1 commit into
Conversation
Files in `publicDir` are copied to `outDir` instead of going through the bundler, so they are not part of the module graph and were never watched. `vite build --watch` copied them once at startup and never again. Register them with `this.addWatchFile()` in `buildStart`, so that editing or removing one triggers a rebuild. The rebuild clears the `rendered` guard via `watchChange` and `renderStart` re-copies `publicDir`, so no separate copy path is needed. Closes vitejs#18655
7 tasks
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.
What this solves
vite build --watchdoesn't rebuild when you change a file inpublicDir. Rolldown watches the module graph plus whatever plugins register viaaddWatchFile(), and public assets are in neither — they're just copied once inrenderStart.The fix is small, because
prepareOutDirPluginalready re-copiespublicDiron every rebuild (watchChange()clears therenderedguard). All that was missing was making a change underpublicDirtrigger a rebuild at all, sobuildStartnow registers each public file withthis.addWatchFile(). No copying logic added.Closes #18655
Why this slipped past the existing tests:
playground/assetsdoes editstatic/foo.txtunder build watch and passes — but that file is imported as?rawfromindex.html, so it's in the module graph, and the assertion reads the bundle rather thanoutDir.Alternatives
#22667 (closed by its author) synced files straight into
outDirwithout rebuilding. Faster, but in buildcheckPublicFilefalls back totryStatSync, so whether a public file exists changes the bundle itself —<img src="/icon.png">,@import '/foo.css'. A plain copy can't re-resolve those, andoutDirdrifts from a real build. Rebuilding keeps them identical for free.I also tried registering the directory instead of each file. rolldown accepts it and then fires nothing, not even
change:One thing I'd like your call on
A newly added public file doesn't rebuild immediately. It didn't exist at
buildStart, andWatcherhas noinvalidate(), so there's nothing to hook into. It does land on the next rebuild, sincebuildStartre-readspublicDireach time. Covering it eagerly would mean a chokidar watcher copying files directly — two different consistency guarantees in one feature, which is why I left it out. Glad to add it if you'd rather.The other trade-off: every public edit now costs a full rebuild,
emptyDir(outDir)included.Tests
Two tests in the existing build-watch block in
playground/assets, usingstatic/bar— a public file nothing imports — asserting ondist/foo/baron disk rather than through the page. Without the patch both time out after 30s, waiting on a rebuild that never comes; with it they pass in 1.5s. No test for the added-file case, since it's knowingly not covered.