Webpack plugin to enable React Fast Refresh (Hot Reloading) for React components during development
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pre-built socket integrations enable seamless communication between the error overlay system and popular Webpack development servers for real-time error reporting and Hot Module Replacement coordination.
The plugin provides ready-to-use integrations for common development servers.
type SocketIntegration = 'wds' | 'whm' | 'wps' | false | string;
// Available integration modules
const WDSSocket = require('@pmmmwh/react-refresh-webpack-plugin/sockets/WDSSocket');
const WPSSocket = require('@pmmmwh/react-refresh-webpack-plugin/sockets/WPSSocket');
const WHMEventSource = require('@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource');Integration for webpack-dev-server using WebSocket communication.
// sockets/WDSSocket.js
const WDSSocket = require('@pmmmwh/react-refresh-webpack-plugin/sockets/WDSSocket');Configuration:
new ReactRefreshPlugin({
overlay: {
sockIntegration: 'wds' // Default
}
});Requirements:
webpack-dev-server: ^4.8.0 || 5.xFeatures:
Usage Example:
// webpack.config.js
const path = require('path');
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = {
mode: 'development',
devServer: {
hot: true,
port: 3000
},
plugins: [
new ReactRefreshPlugin({
overlay: {
sockIntegration: 'wds'
}
})
]
};Integration for webpack-hot-middleware using EventSource/Server-Sent Events.
// sockets/WHMEventSource.js
const WHMEventSource = require('@pmmmwh/react-refresh-webpack-plugin/sockets/WHMEventSource');Configuration:
new ReactRefreshPlugin({
overlay: {
sockIntegration: 'whm'
}
});Requirements:
webpack-hot-middleware: 2.xFeatures:
Usage Example:
// server.js
const express = require('express');
const webpack = require('webpack');
const webpackHotMiddleware = require('webpack-hot-middleware');
const config = require('./webpack.config.js');
const app = express();
const compiler = webpack(config);
app.use(webpackHotMiddleware(compiler, {
path: '/__webpack_hmr',
heartbeat: 10 * 1000
}));
// webpack.config.js
module.exports = {
entry: [
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000',
'./src/index.js'
],
plugins: [
new ReactRefreshPlugin({
overlay: {
sockIntegration: 'whm'
}
})
]
};Integration for webpack-plugin-serve using WebSocket communication.
// sockets/WPSSocket.js
const WPSSocket = require('@pmmmwh/react-refresh-webpack-plugin/sockets/WPSSocket');Configuration:
new ReactRefreshPlugin({
overlay: {
sockIntegration: 'wps'
}
});Requirements:
webpack-plugin-serve: 1.xFeatures:
Usage Example:
// webpack.config.js
const { WebpackPluginServe } = require('webpack-plugin-serve');
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = {
entry: ['webpack-plugin-serve/client', './src/index.js'],
plugins: [
new ReactRefreshPlugin({
overlay: {
sockIntegration: 'wps'
}
}),
new WebpackPluginServe({
port: 3000,
static: './dist'
})
]
};Create custom integrations for other development servers or custom setups.
// Socket integration modules export an init function
interface SocketIntegrationModule {
init(messageHandler: (message: HMRMessage) => void): void;
}
// All built-in socket integrations follow this pattern:
function initWDSSocket(messageHandler: (message: HMRMessage) => void): void;
function initWHMEventSource(messageHandler: (message: HMRMessage) => void): void;
function initWPSSocket(messageHandler: (message: HMRMessage) => void): void;Custom Integration Example:
// custom-socket.js
let socket = null;
let messageHandlers = [];
let errorHandlers = [];
let closeHandlers = [];
function connect() {
socket = new WebSocket('ws://localhost:8080/hmr');
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
messageHandlers.forEach(handler => handler(data));
};
socket.onerror = (error) => {
errorHandlers.forEach(handler => handler(error));
};
socket.onclose = () => {
closeHandlers.forEach(handler => handler());
};
}
function disconnect() {
if (socket) {
socket.close();
socket = null;
}
}
function onMessage(callback) {
messageHandlers.push(callback);
}
function onError(callback) {
errorHandlers.push(callback);
}
function onClose(callback) {
closeHandlers.push(callback);
}
module.exports = {
connect,
disconnect,
onMessage,
onError,
onClose
};Using Custom Integration:
new ReactRefreshPlugin({
overlay: {
sockIntegration: './src/custom-socket.js'
}
});Standard message format for communication between server and client:
interface HMRMessage {
type: 'ok' | 'warnings' | 'errors' | 'hash' | 'still-ok' | 'invalid';
data?: any;
hash?: string;
warnings?: string[];
errors?: string[];
}Message Types:
Example Messages:
// Successful compilation
{
type: 'ok',
hash: 'abc123def456'
}
// Compilation with errors
{
type: 'errors',
errors: [
'Module not found: Error: Can\'t resolve \'./missing-file\'',
'SyntaxError: Unexpected token'
]
}
// Compilation with warnings
{
type: 'warnings',
warnings: [
'Warning: React Hook useEffect has a missing dependency'
]
}All socket integrations provide connection lifecycle management:
Connection States:
Automatic Reconnection:
// Built-in reconnection logic
function attemptReconnection() {
let attempts = 0;
const maxAttempts = 10;
const baseDelay = 1000;
function reconnect() {
if (attempts >= maxAttempts) {
console.error('Max reconnection attempts reached');
return;
}
attempts++;
const delay = baseDelay * Math.pow(2, attempts - 1);
setTimeout(() => {
try {
connect();
} catch (error) {
console.warn('Reconnection failed, retrying...', error);
reconnect();
}
}, delay);
}
reconnect();
}The plugin automatically selects the appropriate integration based on configuration:
// Integration resolution logic
function resolveSocketIntegration(sockIntegration) {
switch (sockIntegration) {
case 'wds':
return require.resolve('./sockets/WDSSocket');
case 'whm':
return require.resolve('./sockets/WHMEventSource');
case 'wps':
return require.resolve('./sockets/WPSSocket');
case false:
return false;
default:
// Custom integration path
return require.resolve(sockIntegration);
}
}Disable socket communication when using custom error handling:
new ReactRefreshPlugin({
overlay: {
sockIntegration: false
}
});When disabled:
Install with Tessl CLI
npx tessl i tessl/npm-pmmmwh--react-refresh-webpack-plugin