Webpack Start Server Plugin
razzle-start-server-webpack-plugin is a utility designed to automatically start a Node.js server after Webpack completes its build process, primarily for server-side bundles in development. It also integrates seamlessly with Hot Module Reloading (HMR) for server code, eliminating the need for manual server restarts during development. The current stable version is 4.2.18, released as part of the broader Razzle monorepo, indicating its release cadence is tied to Razzle's development lifecycle. Its key differentiators include simplified HMR setup for server code and the ability to pass arguments directly to Node.js or the server script, making debugging easier.
Common errors
-
StartServerPlugin is not a constructor
cause Attempting to import `StartServerPlugin` using a CommonJS `require` syntax or incorrect ES module syntax when the package is primarily ESM or configured as such.fixUse `import StartServerPlugin from 'start-server-webpack-plugin';` instead of `const StartServerPlugin = require('start-server-webpack-plugin');` and ensure your webpack config supports ESM. -
Cannot find module 'webpack/hot/poll?1000'
cause The `webpack/hot/poll` entry point is only available if `webpack` is correctly installed as a dependency and resolved within your project.fixEnsure `webpack` is installed as a peer dependency (e.g., `npm install webpack`) and that its version is compatible with the plugin (`~4||~5`). -
Server not restarting or HMR not working on file changes.
cause Webpack is not in watch mode, or `webpack.HotModuleReplacementPlugin` is missing, or the server-side code doesn't correctly accept HMR updates.fixEnsure `watch: true` is set in your Webpack config, `new webpack.HotModuleReplacementPlugin()` is included, and your server entry file includes `module.hot.accept();` logic if you want custom HMR handling.
Warnings
- breaking When upgrading from v2, the `name` option has been removed and replaced with `entryName`. Ensure you update your plugin configuration to use `entryName` if your server entry point is not named 'main'.
- gotcha This plugin is designed for development environments. It should generally not be used in production builds, as its primary purpose is to automatically start and restart the server with HMR functionality.
- gotcha When using Hot Module Reloading (HMR) with this plugin, you typically do not need to manually add `webpack/hot/dev-server` or similar HMR entry points to your server bundle, as the plugin handles appending necessary HMR code.
- gotcha Starting with version 4.2.18, the plugin adds support for `type: module` in `razzle.config.js`. If you are using an older version and encounter issues with ESM configurations, an update may be necessary.
Install
-
npm install razzle-start-server-webpack-plugin -
yarn add razzle-start-server-webpack-plugin -
pnpm add razzle-start-server-webpack-plugin
Imports
- StartServerPlugin
const StartServerPlugin = require('start-server-webpack-plugin');import StartServerPlugin from 'start-server-webpack-plugin';
Quickstart
import path from 'path';
import webpack from 'webpack';
import StartServerPlugin from 'start-server-webpack-plugin';
export default {
mode: 'development',
entry: {
server: [
'webpack/hot/poll?1000',
'./src/server.js'
]
},
target: 'node',
watch: true,
externals: [
/^[a-z].*$/ // Don't bundle node_modules
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new StartServerPlugin({
verbose: true,
debug: true,
entryName: 'server',
nodeArgs: ['--inspect-brk'], // For debugging
scriptArgs: ['--my-custom-arg'],
restartable: true,
once: false
}),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: '[name].js',
libraryTarget: 'commonjs2'
}
};
// A minimal server example (src/server.js)
// import express from 'express';
// const app = express();
// app.get('/', (req, res) => res.send('Hello HMR!'));
// const port = process.env.PORT || 3000;
// app.listen(port, () => console.log(`Server listening on port ${port}`));
// if (module.hot) {
// module.hot.accept();
// module.hot.dispose(() => console.log('Server disposed.'));
// }