Webpack Build Conflict Prevention

Date: November 26, 2025
Category: Frontend / Build Tools
Status: Active

Problem

Running yarn build while the webpack dev server (yarn wpd) is active causes conflicts because both processes try to write to the same output directory (public/javascripts/webpack/). This results in:

  • Corrupted assets
  • Build failures
  • Cryptic error messages
  • Wasted time debugging

Solution

A pre-build check script that detects if the dev server is running and aborts with a helpful message.

How It Works

Detection Methods

The script (script/check_wpd_running.sh) checks two ways, both scoped to
the current working directory
so a dev server running in a sibling worktree
does not block builds in this checkout:

  1. Lock File - Does ${PWD}/.wpd.lock exist? (set by wpd_start.sh)
  2. Port Check - Is a process listening on port 8081 and is its cwd
    equal to this directory? Resolved via lsof -d cwd (or /proc/<pid>/cwd
    on Linux), with both paths normalised through pwd -P.

The earlier global curl http://localhost:8081/... manifest probe was
removed: it could not be made directory-aware, so it produced false
positives in worktrees.

Lock File Management

The dev server start script (script/wpd_start.sh):

  • Creates .wpd.lock on start
  • Removes it on exit (Ctrl+C, kill, etc.)
  • Uses bash trap to ensure cleanup

User Experience

When Dev Server is Running

$ yarn build

╔══════════════════════════════════════════════════════════════════╗
║  ⚠️  WEBPACK DEV SERVER IS RUNNING!                              ║
╠══════════════════════════════════════════════════════════════════╣
║  Cannot run 'yarn build' while dev server is active.            ║
║  Both processes write to the same output directory.             ║
╠══════════════════════════════════════════════════════════════════╣
║  Options:                                                        ║
║    1. Stop the dev server first (Ctrl+C in that terminal)       ║
║    2. Or use 'yarn wpd:rebuild:inplace' to trigger a rebuild    ║
║       within the running dev server                             ║
╚══════════════════════════════════════════════════════════════════╝

When Dev Server is Not Running

$ yarn build
# Proceeds normally with webpack build

Files

File Purpose
script/check_wpd_running.sh Pre-build detection script
script/wpd_start.sh Dev server start with lock file
package.json Updated build scripts
.gitignore Added .wpd.lock

Scripts Updated

{
  "scripts": {
    "build": "./script/check_wpd_running.sh && yarn install && ...",
    "wpd": "./script/wpd_start.sh",
    "wp:rebuild": "./script/check_wpd_running.sh && ..."
  }
}

Protected Commands

Command Protection
yarn build ✅ Checks before build
yarn build:p ✅ Uses build, so protected
yarn wp:rebuild ✅ Checks before rebuild
yarn wpd Creates lock file
yarn wpd:rebuild:inplace Safe alternative for rebuilding

Alternatives When Dev Server is Running

Instead of stopping the dev server, you can:

1. Trigger In-Place Rebuild

yarn wpd:rebuild:inplace

This touches webpack.config.js to trigger a rebuild within the running dev server.

2. Stop Dev Server First

# In the dev server terminal
Ctrl+C

# Then build
yarn build

Technical Details

check_wpd_running.sh

#!/usr/bin/env bash
set -euo pipefail

WPD_PORT="${WPD_PORT:-8081}"
PWD_REAL="$(pwd -P)"
WPD_LOCKFILE="${PWD_REAL}/.wpd.lock"

# Check lockfile (already PWD-scoped) or that the listener on the port has
# its cwd in *this* checkout. A dev server in a sibling worktree won't match.
check_lockfile() {
  [ -f "${WPD_LOCKFILE}" ]
}

check_port_in_pwd() {
  local pids; pids="$(lsof -ti ":${WPD_PORT}" -sTCP:LISTEN 2>/dev/null || true)"
  [ -z "$pids" ] && return 1
  for pid in $pids; do
    cwd="$(lsof -a -p "${pid}" -d cwd -Fn 2>/dev/null | awk '/^n/ {sub(/^n/,""); print; exit}')"
    cwd="$( cd "$cwd" 2>/dev/null && pwd -P )"
    [ "$cwd" = "$PWD_REAL" ] && return 0
  done
  return 1
}

# Exit 1 if running here, 0 if not

wpd_start.sh

#!/usr/bin/env bash
set -euo pipefail

WPD_LOCKFILE="${PWD}/.wpd.lock"

# Cleanup on exit
cleanup() {
  rm -f "${WPD_LOCKFILE}"
}
trap cleanup EXIT INT TERM

# Create lock file
echo $$ > "${WPD_LOCKFILE}"

# Start webpack dev server
webpack serve --profile --host 0.0.0.0

Troubleshooting

Lock file exists but dev server not running

rm .wpd.lock

This can happen if the dev server crashed without cleanup.

Check is too slow

The HTTP check has a 1-second timeout. If your network is slow, increase it in the script or rely on port/lockfile checks.

See Also