Skip to content

Fix sbt dev-web on Node 24 / webpack 5 - #440

Merged
AlexITC merged 9 commits into
wiringbits:masterfrom
AlexITC:master
May 22, 2026
Merged

Fix sbt dev-web on Node 24 / webpack 5#440
AlexITC merged 9 commits into
wiringbits:masterfrom
AlexITC:master

Conversation

@AlexITC

@AlexITC AlexITC commented May 22, 2026

Copy link
Copy Markdown
Contributor
  • Command-scoping syntax: the dev-web alias used the old sbt 0.13 ::
    separator instead of sbt 1.x /, causing a parse error on startup.
  • OpenSSL / MD4: webpack 5 uses MD4 hashing internally, which OpenSSL 3
    (bundled with Node 18+) dropped. Patch crypto.createHash in
    custom.webpack.config.js to substitute sha256 when md4 is requested.
  • @webpack-cli/serve version skew: yarn.lock had resolved the transitive
    dep to 1.7.0, which requires webpack-cli APIs (loadWebpack, toKebabCase,
    …) added only in webpack-cli 4.7.0+. sbt-scalajs-bundler hardcodes
    webpack-cli 4.5.0, so those calls blow up at runtime. Fix: pin
    @webpack-cli/serve to 1.3.1 (the version that shipped alongside
    webpack-cli 4.5.0) via a yarn resolutions block in additionalNpmConfig.

Also adds scripts/test-dev-web.sh: starts the dev server in the background,
polls http://localhost:8080/ until it responds HTTP 200, then tears down
cleanly. The CI workflow now runs this script as a dedicated step.

AlexITC and others added 5 commits May 21, 2026 12:10
- Scala 3.3.0 -> 3.6.4 (latest LTS) with all Scala 3.4+ source compatibility fixes
- JDK 11 -> 25 (latest LTS) in .sdkmanrc and CI workflow
- sbt 1.7.3 -> 1.12.11
- Replace vendored PekkoStream.scala with anorm-pekko 3.0.0 library
- Add pekko 1.6.0 dependencyOverrides for consistent version resolution
- Bump all library and plugin versions to latest compatible releases
- CI: node 16 -> 24, yarn install step, NODE_OPTIONS=--openssl-legacy-provider
- Fix timestamp precision in UsersControllerSpec for JDK 25 nanosecond clock
Mirror the same changes from pull_request.yml: temurin:25, node 24,
yarn install step, and NODE_OPTIONS for webpack compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Three separate issues prevented `sbt dev-web` from working after the
JDK 25 / Node 24 / Scala 3.6.4 upgrade:

1. Command-scoping syntax: the dev-web alias used the old sbt 0.13 `::`
   separator instead of sbt 1.x `/`, causing a parse error on startup.

2. OpenSSL / MD4: webpack 5 uses MD4 hashing internally, which
   OpenSSL 3 (bundled with Node 18+) dropped. Patch crypto.createHash
   in custom.webpack.config.js to substitute sha256 when md4 is requested.

3. @webpack-cli/serve version skew: yarn.lock had resolved the transitive
   dep to 1.7.0, which requires webpack-cli APIs (loadWebpack,
   toKebabCase, …) added only in webpack-cli 4.7.0+.
   sbt-scalajs-bundler hardcodes webpack-cli 4.5.0, so those calls blow
   up at runtime. Fix: pin @webpack-cli/serve to 1.3.1 (the version that
   shipped alongside webpack-cli 4.5.0) via a yarn resolutions block in
   additionalNpmConfig.

Also adds scripts/test-dev-web.sh: starts the dev server in the
background, polls http://localhost:8080/ until it responds HTTP 200,
then tears down cleanly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

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

This PR updates the Scala.js web dev workflow to work on newer Node/webpack stacks by fixing the dev-web sbt alias scoping syntax, pinning an incompatible @webpack-cli/serve transitive dependency, and adding a CI smoke test that boots the dev server and performs an HTTP health check.

Changes:

  • Fix dev-web sbt alias scoping syntax for sbt 1.x (/ instead of ::).
  • Pin @webpack-cli/serve to 1.3.1 via Yarn lock + additionalNpmConfig resolutions to match the webpack-cli version used by sbt-scalajs-bundler.
  • Add a CI step and script to start sbt dev-web and verify the dev server responds on http://localhost:8080/.

Reviewed changes

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

Show a summary per file
File Description
web/yarn.lock Pins @webpack-cli/serve to 1.3.1 to avoid runtime API mismatch with webpack-cli 4.5.0.
scripts/test-dev-web.sh Adds a CI smoke test that starts sbt dev-web, polls for readiness, then checks HTTP 200.
custom.webpack.config.js Patches crypto.createHash to substitute sha256 for md4 under OpenSSL 3.
build.sbt Adds Yarn resolutions config and fixes the sbt alias scoping syntax.
.github/workflows/pull_request.yml Runs the new test-dev-web script in CI.

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

Comment thread scripts/test-dev-web.sh Outdated
Comment on lines +11 to +21
# Keep a FIFO with an open write fd so sbt's stdin never hits EOF.
# Without it, sbt exits watch mode → JVM shutdown hooks kill webpack-dev-server.
FIFO=$(mktemp -u /tmp/sbt-stdin-XXXXXX)
mkfifo "$FIFO"
exec 9>"$FIFO"

cleanup() {
exec 9>&- 2>/dev/null || true
kill "$SBT_PID" 2>/dev/null || true
wait "$SBT_PID" 2>/dev/null || true
rm -f "$FIFO"
Comment thread scripts/test-dev-web.sh Outdated
Comment on lines +17 to +21
cleanup() {
exec 9>&- 2>/dev/null || true
kill "$SBT_PID" 2>/dev/null || true
wait "$SBT_PID" 2>/dev/null || true
rm -f "$FIFO"
Comment thread custom.webpack.config.js Outdated
// webpack 5 uses MD4 hashing internally, which OpenSSL 3 (Node 18+) dropped; patch to sha256
const crypto = require('crypto');
const origCreateHash = crypto.createHash;
crypto.createHash = (algorithm) => origCreateHash(algorithm === 'md4' ? 'sha256' : algorithm);
AlexITC and others added 2 commits May 22, 2026 04:51
- scripts/test-dev-web.sh: replace mktemp -u (race-prone) with mktemp -d
  and create the FIFO inside the temp dir; open FIFO read/write (exec 9<>)
  so the exec never blocks waiting for a reader; initialize SBT_PID=""
  before the trap to avoid unbound-variable errors under set -u
- custom.webpack.config.js: forward ...args in createHash wrapper so the
  optional options argument is not silently dropped

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
dev-web uses fastOptJS; web/build uses fullOptJS — independent targets,
so testing dev-web first avoids any cross-contamination from the prod build.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

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

Copilot reviewed 3 out of 5 changed files in this pull request and generated no new comments.

AlexITC and others added 2 commits May 22, 2026 05:46
The yarn resolutions field pins @webpack-cli/serve to 1.3.1 but is
ineffective when CI restores a stale node_modules from cache.  Add a
belt-and-suspenders postinstall script that patches the installed files
directly after every yarn install:
  - webpack-cli 4.5.0 makeCommand: add await so options() result is
    awaited before calling forEach (handles async options functions)
  - @webpack-cli/serve: shim loadWebpack() if missing (no-op on 1.3.1,
    fixes 1.6+ which calls an API added in webpack-cli 4.7.0)

Also improves test-dev-web.sh: captures sbt output to a log file and
fails immediately (no timeout wait) when [error] [webpack-cli] appears,
printing the relevant error lines to stderr for clear CI diagnostics.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
webpack-cli 4.5.0 (hardcoded by sbt-scalajs-bundler) depends on
@webpack-cli/serve@^1.3.0; without an explicit pin yarn resolves that
range to 1.7.0, which requires APIs only present in webpack-cli 4.7+
and breaks webpack serve on Node 24.

Adding @webpack-cli/serve as a direct devDependency at exactly 1.3.1
forces yarn to hoist that version everywhere, making it fully
compatible with webpack-cli 4.5.0 — no postinstall patching needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@AlexITC
AlexITC merged commit 52ce78f into wiringbits:master May 22, 2026
1 check 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.

2 participants