Vite dependency cache does not invalidate on nested module changes during HMR
0 reputation · 29 Aug 2022, 17:20 UTC
0 reputation · 29 Aug 2022, 17:20 UTC
When developing with Vite, the persistent dependency cache in node_modules/.vite is intended to speed up restarts by preserving esbuild‑prebundled packages. The goal is to guarantee that any modification to a nested dependency inside an already‑cached package triggers a cache invalidation so that HMR delivers the updated module without manual intervention.
Currently it is unclear whether Vite’s file‑system watcher detects changes that occur deep within the cached dependency tree, or if the cache assumes immutability of the pre‑bundled content after the initial build. This uncertainty can leave the browser with stale module references when a sub‑dependency is altered or unlinked while the dev server is running.
--force restart?Vite’s persistent dependency cache in node_modules/.vite is only invalidated when a package’s entry file or its package.json changes. Modifications to files deeper in the dependency tree are not watched, so HMR will not pick them up automatically.
During the initial pre‑bundling step, Vite runs esbuild on a package’s entry point and writes the resulting bundle to .vite. The file‑system watcher that drives HMR is configured to monitor only the source files that are part of the current build pipeline (your source code and the entry points of cached deps). Nested modules are treated as part of the pre‑bundled artifact, and Vite deliberately does not set up watchers inside node_modules/.vite for performance reasons.
vite --force or delete node_modules/.vite whenever you know a nested dependency has changed. This forces a full re‑optimization of all cached packages.
node_modules for changes and clears the cache before the server restarts. This keeps HMR working without a manual restart.
chokidar) outside of Vite and trigger a --force restart programmatically.
import { defineConfig } from 'vite';
import chokidar from 'chokidar';
export default defineConfig({
plugins: [
{
name: 'watch-node-modules',
apply: 'serve',
configureServer(server) {
const watcher = chokidar.watch('node_modules', {
ignoreInitial: true,
depth: 3, // adjust depth as needed
});
watcher.on('change', () => {
console.log('[vite] Detected change in node_modules – clearing cache');
server.restart(); // restarts dev server, triggering --force logic
});
},
},
],
});
1. Start the dev server normally.
2. Edit a file in a nested dependency (e.g., node_modules/some-lib/lib/utils.js).
3. Observe that the console logs a cache clear and the browser reloads with the updated code. If nothing happens, the cache was not invalidated.
Which Vite version are you running? The cache invalidation logic has changed across minor releases, and the behavior described here applies to Vite 4.x and 5.x as of the latest stable releases.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.