Webpack Hot Server Middleware
webpack-hot-server-middleware is a utility designed to provide hot module replacement (HMR) capabilities for server-side Webpack bundles, specifically within universal or isomorphic JavaScript applications. It integrates seamlessly with `webpack-dev-middleware` and optionally `webpack-hot-middleware` to ensure that server bundles are always updated with the latest compilation changes during development, eliminating the need for manual server restarts. The package, currently at version 0.6.1, addresses a common pain point in development workflows where client bundles benefit from HMR but server bundles do not. It achieves this by replacing the entire server bundle in memory, leveraging the stateless nature of typical Express-style middleware. Key differentiators include its ability to share the same Webpack cache between client and server builds for faster compilation and its reliance on in-memory bundles to avoid disk I/O. Development appears to be in maintenance mode, with the last significant update occurring several years ago (February 2020), meaning its primary functionality is stable but new features or active modern Webpack compatibility updates are unlikely.
Common errors
-
TypeError: compiler.compilers.find is not a function
cause Webpack configuration is not an array, or is an array but missing 'name' properties for client/server configs.fixVerify that your `webpack.config.js` exports an array of configurations, and each configuration object includes a `name` property ('client' or 'server'). -
Error: Target 'node' must be set for the server bundle in webpack configuration.
cause The server-side Webpack configuration is missing the `target: 'node'` property.fixAdd `target: 'node'` to your server-specific Webpack configuration object. -
Server-side code changes are not reflecting without manual server restarts, despite HMR for client.
cause Likely incorrect middleware order or `serverSideRender` option missing in `webpack-dev-middleware` configuration.fixEnsure `webpackHotServerMiddleware` is mounted *after* `webpack-dev-middleware` in your Express application and `webpack-dev-middleware` has `serverSideRender: true`.
Warnings
- breaking Webpack configuration must be an array containing separate configurations for 'client' and 'server' bundles.
- breaking Client and server Webpack configurations must be explicitly named 'client' and 'server' respectively using the `name` property.
- gotcha This middleware must be mounted *after* `webpack-dev-middleware` in your Express application's middleware chain to ensure correct hot updates.
- gotcha The `serverSideRender: true` option is crucial for `webpack-dev-middleware` when using `webpack-hot-server-middleware` to ensure proper communication and server bundle compilation.
- gotcha The package has not seen active development since February 2020. While functional for its intended purpose, it might lack support for very recent Webpack features or new JavaScript language constructs without manual configuration adjustments.
Install
-
npm install webpack-hot-server-middleware -
yarn add webpack-hot-server-middleware -
pnpm add webpack-hot-server-middleware
Imports
- webpackHotServerMiddleware
const { default: webpackHotServerMiddleware } = require('webpack-hot-server-middleware');import webpackHotServerMiddleware from 'webpack-hot-server-middleware';
- webpackHotServerMiddleware (CJS)
const { webpackHotServerMiddleware } = require('webpack-hot-server-middleware');const webpackHotServerMiddleware = require('webpack-hot-server-middleware'); - WebpackHotServerMiddleware
import type WebpackHotServerMiddleware from 'webpack-hot-server-middleware';
Quickstart
// webpack.config.ts (simplified example for quickstart)
import type { Configuration } from 'webpack';
import path from 'path';
const isDevelopment = process.env.NODE_ENV !== 'production';
const clientConfig: Configuration = {
name: 'client',
target: 'web',
mode: isDevelopment ? 'development' : 'production',
entry: './src/client.ts',
output: {
filename: 'client.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
},
// ... other rules and plugins for client bundle (e.g., React, HMR client) ...
};
const serverConfig: Configuration = {
name: 'server',
target: 'node',
mode: isDevelopment ? 'development' : 'production',
entry: './src/server-renderer.ts',
output: {
filename: 'server.js',
path: path.resolve(__dirname, 'dist'),
libraryTarget: 'commonjs2',
},
// ... other rules and externals for server bundle (e.g., exclude node_modules) ...
};
export default [clientConfig, serverConfig];
// server.ts (main application entry point using Express)
import express from 'express';
import webpack from 'webpack';
import webpackDevMiddleware from 'webpack-dev-middleware';
import webpackHotServerMiddleware from 'webpack-hot-server-middleware';
import config from './webpack.config'; // Your array of Webpack configurations
const app = express();
const compiler = webpack(config);
// Mount webpack-dev-middleware first for client-side assets and HMR
app.use(webpackDevMiddleware(compiler, {
publicPath: '/', // Must match output.publicPath in clientConfig
serverSideRender: true, // Essential for isomorphic apps to allow dev-middleware to render server-side
stats: { colors: true },
}));
// Mount webpack-hot-server-middleware immediately after dev middleware
// It automatically picks up the 'server' named configuration from the compiler
app.use(webpackHotServerMiddleware(compiler));
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server listening on http://localhost:${PORT}`);
console.log('Ensure you have a `client.ts` for browser entry and `server-renderer.ts` for server-side rendering in your `src/` directory.');
console.log('The server renderer should export a function that returns Express middleware.');
});