Webpack Isomorphic Dev Middleware

raw JSON →
4.1.0 verified Thu Apr 23 auth: no javascript

webpack-isomorphic-dev-middleware is an Express middleware designed to streamline development for isomorphic (server-side rendered) applications using Webpack. It extends the functionality of webpack-dev-middleware by concurrently managing both client and server-side Webpack compilations. The package, currently at version 4.1.0, significantly simplifies complex isomorphic development setups by ensuring that both client and server bundles are compiled and ready before serving requests. It employs an in-memory filesystem for optimized compilation, delays responses until all necessary builds are complete, and injects compilation stats and server-exported methods into `res.locals.isomorphic`. Key differentiators include integrated compilation reporting for the terminal, optional OS notifications, and browser-based display of compilation errors. While a specific release cadence isn't stated, the version numbering suggests ongoing maintenance and updates, though its peer dependency range indicates primary support for Webpack versions up to v4.

error Peer dependency webpack@<5.0.0 not met
cause Attempting to install or run `webpack-isomorphic-dev-middleware` with Webpack v5 or a newer incompatible version installed in your project.
fix
Modify your package.json to use a compatible Webpack version (e.g., "webpack": "^4.0.0") and reinstall dependencies.
error TypeError: app.use is not a function
cause The `app` variable used with `app.use(webpackIsomorphicDevMiddleware(...))` is not a valid Express application instance, or it's improperly initialized.
fix
Ensure Express is installed (npm install express) and app is created as const app = express(); before attempting to use middleware.
error TypeError: Cannot read properties of undefined (reading 'isomorphic')
cause The `res.locals.isomorphic` object is being accessed before the `webpackIsomorphicDevMiddleware` has been applied to the Express app or before the initial Webpack compilations have completed.
fix
Verify that app.use(webpackIsomorphicDevMiddleware(...)) is called correctly and appears before any routes that attempt to access res.locals.isomorphic. The middleware automatically delays requests until compilation is ready, so this usually points to an ordering issue in Express middleware chain or direct access outside of a request context.
gotcha When using webpack v2 or v3 with `webpack-isomorphic-dev-middleware` v4, you might encounter peer dependency warnings. These can typically be safely ignored as the middleware maintains compatibility with these webpack versions.
fix No action is strictly required. If using npm 7+ and warnings prevent installation, consider using `--legacy-peer-deps` or upgrading webpack to v4 if possible.
breaking This version of `webpack-isomorphic-dev-middleware` explicitly lists peer dependency support for `webpack@>=2.0.0 <5.0.0`. Using Webpack v5 or newer will result in a peer dependency violation and may lead to compilation failures or unexpected behavior.
fix Downgrade webpack to a compatible version (e.g., v4) or check if a newer major version of `webpack-isomorphic-dev-middleware` has been released with Webpack 5+ support.
gotcha This middleware requires *both* a client-side and a server-side Webpack compiler instance. Incorrectly configured or missing compilers (especially forgetting `target: 'node'` for the server) will prevent proper compilation and server-side rendering functionality.
fix Ensure `clientCompiler` and `serverCompiler` are valid Webpack instances with distinct, complete configurations. The server compiler should always have `target: 'node'` and `libraryTarget: 'commonjs2'` for its output.
npm install webpack-isomorphic-dev-middleware
yarn add webpack-isomorphic-dev-middleware
pnpm add webpack-isomorphic-dev-middleware

This quickstart demonstrates how to set up `webpack-isomorphic-dev-middleware` with an Express server, integrating both client and server Webpack compilers, and enabling client-side Hot Module Replacement with `webpack-hot-middleware`. It includes minimal Webpack configurations for a client and a node server bundle, and a basic Express route that accesses the server exports via `res.locals.isomorphic` to render an isomorphic page.

const express = require('express');
const webpack = require('webpack');
const webpackIsomorphicDevMiddleware = require('webpack-isomorphic-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');
const nodeExternals = require('webpack-node-externals');
const path = require('path');
const fs = require('fs');

// Create dummy client and server entry points for demonstration
fs.mkdirSync(path.join(__dirname, 'src', 'client'), { recursive: true });
fs.writeFileSync(path.join(__dirname, 'src', 'client', 'index.js'), 'console.log("Client bundle loaded");');
fs.mkdirSync(path.join(__dirname, 'src', 'server'), { recursive: true });
fs.writeFileSync(path.join(__dirname, 'src', 'server', 'index.js'), 'module.exports = { greet: () => "Hello from server!" };');

const clientConfig = {
  mode: 'development',
  entry: [path.resolve(__dirname, 'src', 'client', 'index.js'), 'webpack-hot-middleware/client'],
  output: {
    path: path.resolve(__dirname, 'public'),
    filename: 'client.js',
    publicPath: '/' // Important for webpack-hot-middleware
  },
  plugins: [new webpack.HotModuleReplacementPlugin()]
};

const serverConfig = {
  mode: 'development',
  entry: path.resolve(__dirname, 'src', 'server', 'index.js'),
  output: {
    path: path.resolve(__dirname, 'build'),
    filename: 'server.js',
    libraryTarget: 'commonjs2' // Exposes module.exports
  },
  target: 'node',
  externals: [nodeExternals()]
};

const clientCompiler = webpack(clientConfig);
const serverCompiler = webpack(serverConfig);
const app = express();

// Serve any static files from the public folder
app.use('/', express.static(path.join(__dirname, 'public'), { maxAge: 0, etag: false }));

// Add the middleware that will wait for both client and server compilations to be ready
app.use(webpackIsomorphicDevMiddleware(clientCompiler, serverCompiler));

// You must also add webpack-hot-middleware to provide hot module replacement to the client
app.use(webpackHotMiddleware(clientCompiler, { quiet: true }));

// Catch all route to attempt to render our isomorphic application
app.get('*', (req, res) => {
  const { serverExports } = res.locals.isomorphic || {};
  console.log('Server received request. Isomorphic data ready.');

  res.send(`
    <!DOCTYPE html>
    <html>
      <head><title>Isomorphic App</title></head>
      <body>
        <h1>Isomorphic App</h1>
        <p>${serverExports?.greet?.() || 'Server exports not available yet.'}</p>
        <div id="root"></div>
        <script src="/client.js"></script>
      </body>
    </html>
  `);
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Development server listening on port ${PORT}`);
  console.log('Waiting for webpack client and server compilations...');
});