Resolving 'Starting the development server...' Hang in Webpack 5 Projects

After upgrading a project from webpack 4 to webpack 5 (webpack@^5.64.4, webpack-dev-server@^4.6.0), running npm start results in the terminal hanging at Starting the development server..., and the browser shows a blank page at localhost:3000.

Diagnosing Common Causes

Port Conflict

The default port for webpack-dev-server is 3000. Check if another process is using it:

lsof -i:3000

If occupied, either terminate the conflicting process or configure a different port in webpack.config.js:

devServer: {
  port: 3001,
}

In this case, no conflict was found.

Source Map Generation

Disabling source maps can sometimes resolve startup hangs during development:

Create .env in the project root:

GENERATE_SOURCEMAP=false

This helps reduce initial build overhead but didn’t fully solve the blank screan issue here.

Incorrect Entry Point Configuration

The project uses separate entry files for development (src/index2.js) and production (src/index.js). The webpack config must conditionally select the correct one:

// paths.js
const appDevEntry = resolveModule(resolveApp, 'src/index2');
const appProdEntry = resolveModule(resolveApp, 'src/index');

// webpack.config.js
entry: isEnvDevelopment ? appDevEntry : appProdEntry,

Without this, Reeact fails to mount to the DOM root, causing a blank page despite successful server startup.

Circular Dependencies

Circular module references can silently break execution in complex dependency graphs. To detect them, use circular-dependency-plugin:

const CircularDependencyPlugin = require('circular-dependency-plugin');

plugins: [
  new CircularDependencyPlugin({
    exclude: /node_modules/,
    include: /src/,
    failOnError: false,
    cwd: process.cwd(),
  }),
],

Refactoring to eliminate circular imports improved stability and testability.

SplitChunks Misconfiguration in Development

The original config applied code splitting in all environments:

optimization: {
  splitChunks: { chunks: 'all', name: false },
  runtimeChunk: { name: entrypoint => `runtime-${entrypoint.name}` }
}

However, aggressive chunking during development slows down builds and can interfere with hot reloading. Restrict it to production:

optimization: {
  splitChunks: isEnvProduction
    ? { chunks: 'all', name: false }
    : false,
  runtimeChunk: isEnvProduction
    ? { name: (entrypoint) => `runtime-${entrypoint.name}` }
    : false,
},

After this change, npm start launched successfully, and the app rendered correctly in the browser.

Tags: webpack webpack-dev-server frontend-development javascript build-tools

Posted on Sat, 09 May 2026 05:23:11 +0000 by sy-co