Skip to content

Rspack static watch builds include dev-server client when WEBPACK_SERVE is unset #1137

@justin808

Description

@justin808

Summary

After bumping react-on-rails-starter-tanstack to shakapacker / shakapacker-rspack 10.1.0-rc.2 with Rspack, static watch mode renders successfully but the browser loads the Rspack dev-server client and tries to connect to a dev-server WebSocket.

Versions

  • shakapacker gem/npm: 10.1.0.rc.2 / 10.1.0-rc.2
  • shakapacker-rspack: 10.1.0-rc.2
  • @rspack/core: 2.0.4
  • @rspack/cli: 2.0.4
  • @rspack/dev-server: 2.0.1
  • assets_bundler: rspack
  • react_on_rails: 16.7.0.rc.1

Reproduction

In the starter, static mode runs bin/shakapacker-watch --watch with WEBPACK_SERVE unset. Requiring the Rspack config in that mode showed all three configs still had a devServer key.

Run:

RENDERER_LOG_LEVEL=error node script/dev-mode-smoke.mjs static

or start static mode and open /dashboard.

Actual

The page renders, but the browser console reports:

WebSocket connection to 'ws://localhost:3321/ws' failed: net::ERR_CONNECTION_REFUSED
[rspack-dev-server] Event

The generated static bundle source map includes @rspack/dev-server/client and @rspack/core/hot/dev-server.js.

Local investigation

node_modules/shakapacker/package/environments/development.js has different behavior for Webpack and Rspack:

  • Webpack only adds devServer when runningWebpackDevServer is true.
  • Rspack always adds devServer, then only gates React Refresh plugin setup on runningWebpackDevServer.

Rspack CLI appears to inject the dev-server client/runtime in watch builds whenever devServer exists, even without WEBPACK_SERVE=true.

Expected

Rspack static watch builds run through bin/shakapacker --watch / bin/shakapacker-watch --watch should omit devServer unless WEBPACK_SERVE=true, matching Webpack behavior and avoiding dev-server WebSocket attempts.

Temporary workaround

In the starter's config/rspack/development.js:

if (config.assets_bundler === 'rspack' && process.env.WEBPACK_SERVE !== 'true') {
  [clientWebpackConfig, serverWebpackConfig, rscWebpackConfig].forEach((webpackConfig) => {
    delete webpackConfig.devServer;
  });
}

With that workaround, RENDERER_LOG_LEVEL=error pnpm run test:dev-modes passes for dev-server, static-watch, and production-like modes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions