Repository navigation
fix(vite-dev-server): serve public files given to the runtime from the Service Worker - #64
Merged
Merged
Conversation
The Service Worker's dev server read the public directory once when it started, when only /public/.gitkeep existed, and never updated the list. The project files arrive through V_FS_* messages after that, so servePublicMiddleware skipped every public file and the request got the SPA fallback index.html. syncPublicFiles() updates the list on the watcher's add and unlink events, as Vite does in the watcher handlers of _createServer(). It runs synchronously in the event, so the list is current before the Service Worker acknowledges a file change. Unlike Vite, it checks the public directory with a trailing slash, so that a sibling such as /publicity.js is not taken for a public file.
The playground now passes a public file to ready(). The tests read through the Service Worker from the host page and check that a public file given to ready() is served with its content and Content-Type, and that public files added, updated and deleted with the file methods are served, or no longer served, as soon as the promises resolve. They also check that binary public files keep their bytes, and that a public file is served instead of a module with the same path. All four tests fail when the Service Worker does not keep its public file list in sync. The file operation helper of the #42 tests is shared as runFileOperation().
Public files given to ready() or added with the file methods are now served by the Service Worker, so the README and the JSDoc of addFile() no longer describe them as a limitation. The API references are regenerated.
This was referenced Oct 1, 2026
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.
Closes #62
The Service Worker now serves public files (
/public/…) that are passed toready()or added with the file methods.Cause
The Service Worker's dev server read the public directory once, when it started. At that point its virtual filesystem held only
/public/.gitkeep, because the project files arrive later throughV_FS_*messages. The list was never updated afterwards, soservePublicMiddlewareskipped every public file, and the request got the SPA fallbackindex.html.Fix
syncPublicFiles()(public-files-sync.ts) updates the list on the watcher'saddandunlinkevents. Vite does the same in the watcher handlers of_createServer(), and the Web Worker already did it insetupHMR().addFile(),updateFile()ordeleteFile()resolves, the change is visible for public files too./publicity.jsis not taken for a public file.addFile()no longer describe this as a limitation.Behavior change
A public file now wins over a module with the same path, as in Vite. If both
/public/x.jsand/x.jsexist, a request for/x.jsgets the public file, without any transform. Before, public files were never served, so the module was returned.Not included
ready()waits until the Service Worker's dev server has started before it sends any file.ready(): both Workers write them as the string[object ArrayBuffer], because they are sent and written as text.ready(), which are now served with that content.addFile()are not affected.console.log. This will be cleaned up separately.Tests
Unit tests:
public-files-sync.test.tscovers:/publicity.jsand/public/../secret.txt;notify()returns.These tests failed before the change, because the function did not exist.
static.test.ts: the middleware follows changes to the list after it has been created. This test passed before the change. It records that the middleware itself needs no change.Integration tests in the shared playground, which read through the Service Worker from the host page:
ready()is served with its content andContent-Type;All four tests fail when the Service Worker does not call
syncPublicFiles().Validated locally with:
vp run test:unit: 119 files, 1,907 testsvp run test:integration:vrowzer: 64 passed and 1 conditional skip, in two consecutive runs and once more after the docs changevp run test:e2e: 46 passed, 6 existingtest.skip