Skip to content

unplugin webpack: never strand a Session when a compile ends without done or failed - #397

Merged
codecaaron merged 3 commits into
mainfrom
wc/unplugin-webpack-leak
Oct 11, 2026
Merged

codecaaron merged 3 commits into
mainfrom
wc/unplugin-webpack-leak

Conversation

@codecaaron

@codecaaron codecaaron commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Teardown audit gap A (ticket 12, coordinated teardown). Released: v0.1.25 (0f29eec) already closed unplugin's webpack Session only on done.

The bug

unplugin's webpack/rspack path closes its Session (and its claim) only on done or failed. webpack fires neither when:

  • an edit invalidates a running compile: Watching._done sees this.invalid and restarts with _go() (webpack Watching.js:285-300, 436);
  • a watch is closed mid-compile: _done becomes the final callback, which fires only watchClose (:480-487, :520-525).

The stranded Session stays joined with its claim. On the edit path the next make builds a new Session for the same build and throws on every later compile: [animus] "animus-unplugin:…" started an analysis of build …, which "animus-unplugin:…" publishes. On the watchClose path the build, its claim and its session directory stay until the process exits.

Fix

  • Under webpack and rspack, a run retires a Session the previous compile left open (dispose its directory, close it) before it claims the build. The Rollup family keeps its Session across buildStart, since Vite and Rollup can start environments in parallel.
  • watchClose retires the build as done and failed do.

Witnesses

unplugin/tests/failed-load-watch.test.ts › a webpack compile that ends without done or failed, with a fake webpack compiler (the plugin's buildStart is webpack's make):

  • an edit that restarts the compile never strands its Session: two makes with no done; red on main a5d1f49 with the claim error above.
  • a watch closed mid-compile retires its build: after watchClose, no session directory remains; red on main.

Not in this PR

Under unplugin's Vite adapter, buildEnd per environment closes the one active Session; with environments built in parallel (the #395 case for vite-plugin) that may close it under a running environment. Not probed yet; a follow-up for ticket 12.

Checks

macOS: unplugin 34/34, lint and fmt clean. Linux CI at efde7d2: run 38175229684, every job green.

🤖 Generated with Claude Code

codecaaron and others added 2 commits October 11, 2026 17:09
…done or failed

Teardown audit gap A (released in v0.1.25). unplugin closed its Session
only on done or failed, and webpack fires neither when an edit
invalidates a running compile (Watching._done restarts it) or when a
watch closes mid-compile (only watchClose). The stranded Session stayed
joined with its claim, so every later compile threw ("… started an
analysis of build …, which … publishes"). Under webpack and rspack, a run
now retires a Session the previous compile left open before it claims the
build; a watchClose retires the build too. The Rollup family keeps its
Session across buildStart, since it can start environments in parallel.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
A fake webpack compiler wires the plugin; its buildStart is webpack's
make. 'an edit that restarts the compile never strands its Session' (two
makes with no done) and 'a watch closed mid-compile retires its build'
(watchClose leaves no session directory). Both red on main a5d1f49.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
@codecaaron
codecaaron merged commit aa66943 into main Oct 11, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant