Skip to content

feat: add hot option for hot module replacement - #2322

Merged
alexander-akait merged 43 commits into
mainfrom
hot-middleware
Sep 1, 2026
Merged

feat: add hot option for hot module replacement#2322
alexander-akait merged 43 commits into
mainfrom
hot-middleware

Conversation

@bjohansebas

@bjohansebas bjohansebas commented May 16, 2026

Copy link
Copy Markdown
Member

Summary

PR — Server-side HMR core (serve-logic)

Integrates the SSE endpoint into the existing middleware behind a new hot: true | { path, heartbeat, log, statsOptions } option. Available at webpack-dev-middleware(compiler, { hot: true }) with no separate app.use().

PR — Browser client runtime (client-runtime)

Ports the browser client into client-src/, mirroring the layout webpack-dev-server uses (client-src/client/).

PR — End-to-end integration tests

What kind of change does this PR introduce?

Did you add tests for your changes?

Does this PR introduce a breaking change?

If relevant, what needs to be documented once your changes are merged or what have you already documented?

Use of AI

Summary by CodeRabbit

  • New Features
    • Added built-in hot module replacement through the hot option.
    • Supports configurable event paths, heartbeats, progress reporting, build statistics, reload behavior, and client logging.
    • Added browser error overlays and rebuild progress indicators, including multi-compiler support.
  • Documentation
    • Added configuration details, migration guidance, API references, and working hot-reload examples.
  • Tests
    • Added comprehensive coverage for hot reloading, overlays, client behavior, validation, and browser compatibility.

@changeset-bot

changeset-bot Bot commented May 16, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c4798c1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
webpack-dev-middleware Minor

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

@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.44681% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 94.19%. Comparing base (11ea5b0) to head (c4798c1).

Files with missing lines Patch % Lines
src/index.js 89.36% 5 Missing ⚠️
src/hot.js 99.44% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2322      +/-   ##
==========================================
+ Coverage   92.73%   94.19%   +1.45%     
==========================================
  Files           3        4       +1     
  Lines        1005     1240     +235     
  Branches      312      380      +68     
==========================================
+ Hits          932     1168     +236     
+ Misses         65       64       -1     
  Partials        8        8              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@bjohansebas
bjohansebas marked this pull request as ready for review June 16, 2026 22:50

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds first-class Hot Module Replacement support to webpack-dev-middleware by introducing a hot option that serves an SSE endpoint and shipping a bundled browser client runtime (webpack-dev-middleware/client) to consume it.

Changes:

  • Add server-side HMR SSE endpoint and wire it into the middleware via a new hot option (with schema + TypeScript types).
  • Add a browser client runtime (overlay + update application) under client-src/, built to client/ and exported as ./client.
  • Add unit + integration tests (SSE helpers, overlay/client tests, middleware E2E), plus a runnable example.

Reviewed changes

Copilot reviewed 32 out of 37 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
types/index.d.ts Exposes hot option + context.hot typings.
types/hot.d.ts Declares public typings for the hot/SSE helper module.
tsconfig.client.json Adds type-checking config for client-src/.
test/validation-options.test.js Adds validation cases for hot options.
test/overlay.test.js Adds jsdom tests for the error overlay UI.
test/middleware.test.js Adds end-to-end tests for SSE endpoint behavior.
test/hot.test.js Adds unit tests for hot server primitives and payload logic.
test/helpers/sse.js Adds helper utilities for SSE handshake/event collection in tests.
test/fixtures/webpack.array.warning.config.js Fixes output path for a fixture used by tests.
test/client.test.js Adds jsdom tests for the browser HMR client runtime.
test/snapshots/validation-options.test.js.snap.webpack5 Updates snapshots for new hot option validation errors.
test/snapshots/client.test.js.snap.webpack5 Adds snapshots for client logging behavior.
src/options.json Adds schema definition for hot option.
src/middleware.js Intercepts SSE requests and routes them to the hot handler.
src/index.js Creates/closes hot instance and adds Hono-specific SSE shims.
src/hot.js Implements SSE event stream + compiler hook publishing logic.
README.md Documents hot server option and the bundled client runtime + options.
package.json Adds ./client export, client build script, new deps, and tooling tweaks.
lint-staged.config.js Updates cspell config usage and eslint invocation flags.
examples/hot/webpack.config.js Adds minimal webpack config demonstrating client entry + HMR plugin.
examples/hot/src/render.js Adds demo module to show HMR updates.
examples/hot/src/index.js Adds demo entry accepting HMR updates.
examples/hot/server.js Adds Express example server mounting middleware with hot: true.
examples/hot/README.md Documents how to run the HMR example.
examples/hot/public/index.html Adds example HTML page loading the in-memory bundle.
eslint.config.mjs Adds ignores for built/example dirs and config for client-src.
cspell.config.json Adds centralized cspell config and ignore paths.
client-src/utils/log.js Adds client-side logger wrapper using webpack runtime logging.
client-src/process-update.js Adds client-side HMR update application logic.
client-src/overlay.js Adds client-side error/warning overlay implementation.
client-src/index.js Adds client runtime entry (EventSource, parsing, overlay, subscriptions).
client-src/globals.d.ts Adds local typing shims for client-src TS checking.
babel.config.js Updates Babel preset-env targeting and test env config.
.gitignore Ignores generated client/ output.
.github/workflows/nodejs.yml Enables workflow triggers on hot-middleware branch.
.changeset/hot-middleware-migration.md Adds a changeset entry describing the new feature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/hot.js
Comment thread src/hot.js
Comment thread src/hot.js
Comment thread babel.config.js Outdated
Comment thread .changeset/hot-middleware-migration.md Outdated
Copilot AI review requested due to automatic review settings July 14, 2026 02:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 20, 2026 17:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 20, 2026 17:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 20, 2026 20:15

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 20, 2026 20:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 20, 2026 22:07

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 21, 2026 01:58

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 21, 2026 02:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

bjohansebas and others added 18 commits September 1, 2026 15:07
…ource (#2368)

* feat(client): share the overlay across bundled copies and report by source

The overlay DOM and problem state now live in a window singleton, so a
second bundled copy of the module (e.g. the webpack-dev-server client
once it adopts this overlay) renders into the same iframe instead of
stacking a duplicate. Fields missing from a state created by an older
copy are filled in place, and the Trusted Types policy moves into the
shared state too — creating two policies with the same name throws
under an enforced CSP.

* test(overlay): prevent re-rendering when clearing a source that reported nothing
The building payload now carries the name of the compilation that
invalidated (tapped per child compiler, since the MultiCompiler hook
does not say which one fired), so clients can pair it with the built or
sync that follows — without it the building indicator registered every
build under "" and could never be hidden for named compilations.

On the client, the inactivity watchdog is restarted inside init(), so it
survives a reconnect instead of dying with the first clearInterval, and
the reconnect timeout handle is now stored and cleared by close(), so
disconnect() during the reconnect window no longer resurrects an
orphaned, uncloseable connection.

All three defects were inherited from webpack-hot-middleware.
…tener

The handshake now ends a response whose headers were already sent
instead of crashing on writeHead, and the middleware routes handshake
errors to next() — an exception there previously became an unhandled
rejection that killed the process.

The overlay's Escape listener on the host document is now attached
lazily inside ensureOverlay (once per page, through the shared state),
matching how webpack-dev-server registers it inside createOverlay, so
importing the client in a non-DOM environment (SSR bundle, worker) no
longer throws at evaluation time.
…ate-name bundles by occurrence

statsOptions now accepts only the object form everywhere: the schema
rejected string presets the types allowed, and booleans validated but
were silently ignored since toBundles only merges objects over the
middleware's base stats options. Schema, JSDoc, and generated types all
agree now, so invalid forms fail validation instead of at runtime.

heartbeat: 0 was schema-valid but silently replaced with the 10s
default by a falsy check — the schema now requires >= 1 and the code
uses ?? so the option and its validation tell the same story.
…shes once

A path without a leading slash validated but could never match a
request, since URL pathnames always start with one — the schema now
enforces it. publish() also serializes the payload once per event
instead of once per connected client.
writeHead semantics replace a header an earlier middleware may have
left on the response — appending merged both values into one
comma-joined header (e.g. "max-age=100, no-cache, no-transform" for
Cache-Control, which intermediaries may treat as cacheable).
…igration guide

The changeset advertised a `log` option that fails validation (it is
`progress`), `hot.statsOptions` documented the boolean form the schema
no longer accepts, `hot.path` now notes the required leading slash, and
the launch-editor sentence that had landed inside the `paginate`
parenthetical is back with `openEditorEndpoint`, where it belongs.

Also adds a "Migrating from webpack-hot-middleware" section: server and
webpack-config before/after, an option mapping table, and the
programmatic API equivalents.
eslint parses the README's fenced code blocks, and the bare
`entry: [...]` object fragment failed with "Unexpected token :" — the
before/after entries are now wrapped in module.exports.
The shared preset-env targets (`esmodules` + node 0.12) also applied to
`src`, so `dist` was downlevelled to ES5 with inlined regenerator helpers.
Target node 20.9 by default and override only `client-src`, whose output has
to be parsable by an old browser. `lint:types-client` now checks the client
without node types and against an ES5 `lib`, so a post-ES5 built-in is an
error instead of a runtime failure.
Adding `exports` hides every path the package does not list (deep imports like
`webpack-dev-middleware/dist/...`), which is a breaking change. The
`./client` subpath resolves through the directory anyway, so the field is
dropped and a TODO records it for the next major. Also drops the now unused
`@babel/plugin-transform-runtime` dev dependency.
… built-ins

Drops the `no-use-before-define: { functions: false }` exception: the client
is reordered so every function is defined before its first reference, which
also removes the `@ts-expect-error`s that hoisting forced on process-update.
Replaces the built-ins an ES5 browser does not have (`Map`,
`URLSearchParams`, `Object.values`, `flatMap`, `includes`, `append`,
`remove`) and guards `fetch`. A non-numeric `timeout` is now ignored (`NaN`
never compares greater, so the watchdog could never report a dead connection)
and `dynamicPublicPath=false` no longer behaves like `true`.
The heartbeat and every publish wrote to each registered client, so a
response ended between the socket dying and its `close` event threw a
write-after-end. Clients are skipped once they end, and a request that was
already destroyed when the handshake finished is dropped instead of staying
in the client map forever (`close` never fires for it again).
Its siblings write to `../outputs/one-error-one-warning-one-success`; `js3`
wrote into `test/fixtures` and left an untracked directory behind after every
run.
Compiles every `client-src` file through the real build config (`envName:
"production"`, since jest runs under the test env) and walks the acorn AST
against an allowlist of ES5.1 node types, so a syntax nobody thought of fails
rather than slips through. `let`, generators, computed/shorthand properties,
bigint literals and post-ES5 regular expression flags are checked on the node
types ES5 already had. Only the module syntax webpack consumes (and the
`import.meta.webpackHot` it replaces) is allowed through.
@socket-security

socket-security Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedjest-environment-jsdom@​30.4.11001006291100
Addedansi-html-community@​0.0.81001008779100

View full report

@socket-security

socket-security Bot commented Sep 1, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm data-urls is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: package-lock.jsonnpm/jest-environment-jsdom@30.4.1npm/data-urls@5.0.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/data-urls@5.0.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

Warn High
Obfuscated code: npm rrweb-cssom is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: package-lock.jsonnpm/jest-environment-jsdom@30.4.1npm/rrweb-cssom@0.8.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/rrweb-cssom@0.8.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

Codecov reported three uncovered lines in src/hot.js. Two are branches the
review added (the catch-up write to an ended response, and the idempotent
disconnect), one is the child-compilation path of extractBundles. hot.js is
at 100% lines from the unit test alone now.
@coderabbitai

coderabbitai Bot commented Sep 1, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 398c4d8b-1d1d-41d3-8b86-dcd09f1a7a17

📥 Commits

Reviewing files that changed from the base of the PR and between 70ba234 and c4798c1.

📒 Files selected for processing (9)
  • .changeset/hot-middleware-migration.md
  • client-src/index.js
  • client-src/overlay.js
  • src/middleware.js
  • src/options.json
  • test/__snapshots__/validation-options.test.js.snap.webpack5
  • test/client.test.js
  • test/middleware.test.js
  • test/validation-options.test.js
🚧 Files skipped from review as they are similar to previous changes (7)
  • .changeset/hot-middleware-migration.md
  • test/validation-options.test.js
  • client-src/overlay.js
  • src/middleware.js
  • test/client.test.js
  • client-src/index.js
  • test/middleware.test.js

Included review availability: Your plan provides up to 8 included reviews per hour; 6 remain after this review.


Walkthrough

This change adds configurable SSE-based hot module replacement to the middleware. It adds a browser client with update handling, shared error overlays, progress indicators, subscriptions, and reconnection support. It publishes client build output and TypeScript declarations. It adds validation, server and browser tests, ES5 checks, examples for standard, multi-compiler, and shared-overlay HMR, plus migration documentation and repository configuration updates.

Merge Risk: 🔵 Low · up to c4798

The new opt-in HMR endpoint can expose build filenames and diagnostics to cross-origin clients and retain unbounded persistent connections if reachable without upstream access controls; additionally, configured endpoints containing query or fragment components may not route correctly. The PR is mergeable with explicit owner awareness and follow-up on endpoint access limits and path handling.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: adding the hot option for hot module replacement.
Docstring Coverage ✅ Passed Docstring coverage is 93.83% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 81 functions across 47 files. (3 skipped: 3…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 93.83% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 81 functions across 47 files. (3 skipped: 3 unsupported.)

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hot-middleware

Warning

Some tools did not complete. Review the errors below.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.

🔧 ast-grep (0.45.2)
test/middleware.test.js

ast-grep timed out on this file


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: a1330527-c6f4-47eb-98a2-86f26b3daa44

📥 Commits

Reviewing files that changed from the base of the PR and between 11ea5b0 and 70ba234.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (62)
  • .changeset/hot-middleware-migration.md
  • .cspell.json
  • .gitignore
  • README.md
  • babel.config.js
  • client-src/globals.d.ts
  • client-src/index.js
  • client-src/indicator.js
  • client-src/overlay.js
  • client-src/process-update.js
  • client-src/theme.js
  • client-src/utils/get-hot.js
  • client-src/utils/log.js
  • client-src/utils/reload.js
  • client-src/utils/strip-ansi.js
  • eslint.config.mjs
  • examples/hot-multi-compiler/README.md
  • examples/hot-multi-compiler/public/index.html
  • examples/hot-multi-compiler/server.js
  • examples/hot-multi-compiler/src/admin-render.js
  • examples/hot-multi-compiler/src/admin.js
  • examples/hot-multi-compiler/src/index.js
  • examples/hot-multi-compiler/src/render.js
  • examples/hot-multi-compiler/webpack.config.js
  • examples/hot-shared-overlay/README.md
  • examples/hot-shared-overlay/public/index.html
  • examples/hot-shared-overlay/server.js
  • examples/hot-shared-overlay/src/app.js
  • examples/hot-shared-overlay/src/render.js
  • examples/hot-shared-overlay/src/widget.js
  • examples/hot-shared-overlay/webpack.config.js
  • examples/hot/README.md
  • examples/hot/public/index.html
  • examples/hot/server.js
  • examples/hot/src/index.js
  • examples/hot/src/render.js
  • examples/hot/webpack.config.js
  • lint-staged.config.js
  • package.json
  • src/hot.js
  • src/index.js
  • src/middleware.js
  • src/options.json
  • test/__snapshots__/client.test.js.snap.webpack5
  • test/__snapshots__/validation-options.test.js.snap.webpack5
  • test/client.test.js
  • test/es5.test.js
  • test/fixtures/webpack.array.one-error-one-warning-one-no.js
  • test/fixtures/webpack.array.one-error-one-warning-one-object.js
  • test/fixtures/webpack.array.one-error-one-warning-one-success.js
  • test/fixtures/webpack.array.warning.config.js
  • test/helpers/sse.js
  • test/hot.test.js
  • test/indicator.test.js
  • test/middleware.test.js
  • test/overlay.test.js
  • test/process-update.test.js
  • test/strip-ansi.test.js
  • test/validation-options.test.js
  • tsconfig.client.json
  • types/hot.d.ts
  • types/index.d.ts

Included review availability: Your plan provides up to 8 included reviews per hour; 7 remain after this review.

Comment thread .changeset/hot-middleware-migration.md Outdated
Comment thread client-src/index.js
Comment thread client-src/index.js
Comment thread client-src/overlay.js
Comment thread src/hot.js
*/
function createHot(compiler, userOptions) {
const options = userOptions === true ? {} : userOptions;
const path = options.path || HOT_DEFAULT_PATH;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reject query and fragment components in hot.path.

createHot preserves values such as "/__webpack_hmr?client=1". pathMatch parses the request URL and compares only its pathname with this full string. No request can match that configured endpoint, so the client receives a normal middleware response instead of SSE. Normalize this option to a pathname or reject ? and #.

Comment thread src/middleware.js Outdated
- Attach the SSE stream only for GET: a HEAD request to the hot path was
  handed a body and left hanging until it timed out.
- Reject a query string or fragment in `hot.path`: `pathMatch` compares
  pathnames, so such an endpoint could never match a request.
- Do not subscribe the same client copy twice: with `autoConnect` on, a
  `setOptionsAndConnect()` call added a second listener and every message
  was processed twice. Keyed by path, so a call that changes `path` still
  subscribes.
- Keep delivering to `subscribeAll` when the `name` filter rejects an
  event, as its documentation promises.
- Walk `querySelectorAll` by index: a NodeList is not iterable in an ES5
  browser, so the compiled for...of threw there.
- Say in the changeset that the client ships with the package rather than
  being served by the middleware.
@alexander-akait
alexander-akait merged commit dbbece3 into main Sep 1, 2026
20 checks passed
@alexander-akait
alexander-akait deleted the hot-middleware branch September 1, 2026 18:13
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.

3 participants