fix: node-side CSS HMR and node-target workers for universal builds#21217
Conversation
Apply CSS hot updates on the node side of a universal build by refreshing the SSR style registry from the re-emitted CSS, rewrite the global new Worker(new URL(...)) to worker_threads on the node target, and document the intentional web-only prefetch/preload no-op on node.
🦋 Changeset detectedLatest commit: d8d9113 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
|
This PR is packaged and the instant preview is available (eef17e3). Install it locally:
npm i -D webpack@https://pkg.pr.new/webpack@eef17e3
yarn add -D webpack@https://pkg.pr.new/webpack@eef17e3
pnpm add -D webpack@https://pkg.pr.new/webpack@eef17e3 |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #21217 +/- ##
=======================================
Coverage 92.75% 92.76%
=======================================
Files 591 591
Lines 64366 64369 +3
Branches 17884 17886 +2
=======================================
+ Hits 59703 59710 +7
+ Misses 4663 4659 -4
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The node side now runs the SSR style-registry HMR path, which uses globalThis; skip on Node 10 like the sibling universal css cases.
Merging this PR will improve performance by 62.76%
|
| Mode | Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|---|
| ❌ | Memory | benchmark "wasm-modules-sync", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
140.3 KB | 358.9 KB | -60.91% |
| ⚡ | Memory | benchmark "lodash", scenario '{"name":"mode-development-rebuild","mode":"development","watch":true}' |
858.8 KB | 126.7 KB | ×6.8 |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing claude/universal-target-problems-yzc0hw (d8d9113) with main (4b00f6e)
Summary
Closes several remaining
target: "universal"gaps. (1) CSS hot updates were skipped on the Node side of a universal build — the.cssHMR handler bailed when there was no DOM, so the SSR style registry kept the stale CSS. It now refreshes the registry from the re-emitted CSS viafs(mirroring the existing initial-SSR collection), and falls back to a no-op whenpublicPathis not a readablefile:URL. (2) The globalnew Worker(new URL(...))syntax was only rewritten to theworker_threadsresolver for universal, so plaintarget: "node"emitted a barenew Workerand threwReferenceError(no globalWorkeron Node) — the rewrite now also covers node-only targets. (3) The web-only prefetch/preload no-op on Node is now documented in code as intentional.A small test-harness fix is included: the universal hot runner picked the trailing entry asset for the Node run, which is the
.cssfile for CSS entries, so the Node side of universal CSS cases never executed; it now selects the JS entry.What kind of change does this PR introduce?
fix
Did you add tests for your changes?
Yes —
test/hotCases/universal/css-ssr-update/(asserts the Node SSR registry is refreshed on CSS hot update) andtest/configCases/worker/node-global-worker/(globalnew Worker(new URL(...))ontarget: "node"). Verified the full universal hot suite, all hot suites, and the worker/CSS/universal config cases stay green.Does this PR introduce a breaking change?
No.
If relevant, what needs to be documented once your changes are merged or what have you already documented?
The universal-target docs (webpack.js.org) should note that CSS hot updates now apply on the Node side, that
new Worker(new URL(...))works ontarget: "node", and that prefetch/preload are intentional no-ops on Node. No in-repo docs exist for this.Use of AI
Yes. Implemented and verified with Claude Code (Claude Opus) — it wrote the runtime/dependency changes and tests, ran the affected Jest suites, and empirically confirmed the gating (no universal-only code is generated for known
web/nodetargets) and that Node'sfetchcannot readfile:URLs (sofsis required on the Node side). All changes were reviewed before committing.Generated by Claude Code