If addWatchFile() is called by a Vite plugin after the server is closed, the
watcher will be set, preventing Node.js process from exiting.
For example, if vite:css was in the middle of transforming a file when the
server is closed, vite:css may call addWatchFile() , which will hang the
process.
-
Clone this repository
git clone https://github.com/maxpatiiuk/vite-watcher-hangs
-
Install dependencies
cd vite-watcher-hangs cd vite-app npm install
-
Run the Vite server
npx vite
-
See that the Node.js process does not exit after the server is closed
- Comment out line 27 in
vite.config.tsand see that the server exists correctly as this way the watcher is set before the server is closed.
- Comment out line 27 in
Multiple built-in Vite plugins are setting watchers for files. For example,
vite:css plugin:
These watchers are set even if server.watcher.close() was called.
These watchers in turn prevent the Node.js process from exiting, hanging it.
Solutions:
- In
server.close(), if there are pending requests, after the requests are processed, close all watchers again if any were open. - OR Make
PluginContext.addWatchFile()a noop after the watcher is closed - OR Add a check for watcher being closed before calling addWatchFile (error prone)
I am starting Vite dev server inside Vitest global setup file. (Vite dev server is used for Puppeteer)
The Vite dev server is closed in the global teardown file.
If some test fails, the teardown is called early, while Vite dev server might still be in the process of transforming a CSS file.
The vite:css plugin may set a file watcher, prevent Vitest from exiting. Vitest prints this message:
close timed out after 10000ms
Tests closed successfully but something prevents Vite server from exiting
You can try to identify the cause by enabling "hanging-process" reporter. See https://vitest.dev/config/#reporters
The hanging-process reporter points to file system watchers set by vite:css
plugin.