Skip to content

The dev server that died on every build

Rebuilding a package killed the running site until its cache was deleted, and the cause was four thousand deletions.

View as Markdown

For weeks the workflow had a superstition in it. Rebuild a package, and the running dev server would start returning 500s — Could not import ./CodeBlock.astro — and stay broken until you killed it, deleted node_modules/.vite, and started again.

What was actually happening

The build tool cleans before it writes, and its clean is a glob:

txt
Cleaning 4311 files

So a rebuild deletes every .js, .d.ts, .astro and .css in dist and puts them back a second later. The dev server watches that directory through the workspace symlink. It sees four thousand deletions, tries to re-resolve a module that no longer exists, fails — and caches the failure. The files returning a second later change nothing, because nothing invalidates the cached failure.

That is why deleting the cache was the only thing that ever worked.

The fix

Stop watching the directory that is guaranteed to churn:

js
vite: {
  server: { watch: { ignored: ["**/packages/*/dist/**"] } },
}

Verified by firing twenty-five requests at the previously-failing module during a rebuild. All 200.

What did not work

resolve.preserveSymlinks: true would have avoided the out-of-root path entirely, and it breaks the framework’s own module resolution under this package manager’s store layout.

Changing the build’s clean step was the other candidate, and it is worse than it looks: without the glob clean, a renamed output lingers in dist forever.

The trade-off, stated plainly

A package change now needs the dev server restarted before it appears. Before, it needed a restart and a cache deletion and it crashed first. The site’s own files still hot-reload.